Class RexProgramBuilder


  • public class RexProgramBuilder
    extends java.lang.Object
    Workspace for constructing a RexProgram.

    RexProgramBuilder is necessary because a RexProgram is immutable. (The String class has the same problem: it is immutable, so they introduced StringBuilder.)

    • Field Detail

      • exprList

        private final java.util.List<RexNode> exprList
      • localRefList

        private final java.util.List<RexLocalRef> localRefList
      • projectRefList

        private final java.util.List<RexLocalRef> projectRefList
      • projectNameList

        private final java.util.List<java.lang.String> projectNameList
      • validating

        private boolean validating
    • Constructor Detail

      • RexProgramBuilder

        public RexProgramBuilder​(RelDataType inputRowType,
                                 RexBuilder rexBuilder)
        Creates a program-builder that will not simplify.
      • RexProgramBuilder

        private RexProgramBuilder​(RexBuilder rexBuilder,
                                  RelDataType inputRowType,
                                  java.util.List<RexNode> exprList,
                                  java.lang.Iterable<? extends RexNode> projectList,
                                  RexNode condition,
                                  RelDataType outputRowType,
                                  boolean normalize,
                                  RexSimplify simplify)
        Creates a program builder with the same contents as a program.
        Parameters:
        rexBuilder - Rex builder
        inputRowType - Input row type
        exprList - Common expressions
        projectList - Projections
        condition - Condition, or null
        outputRowType - Output row type
        normalize - Whether to normalize
        simplify - Simplifier, or null to not simplify
    • Method Detail

      • assertionsAreEnabled

        private static boolean assertionsAreEnabled()
        Returns whether assertions are enabled in this class.
      • validate

        private void validate​(RexNode expr,
                              int fieldOrdinal)
      • addProject

        public RexLocalRef addProject​(RexNode expr,
                                      java.lang.String name)
        Adds a project expression to the program.

        The expression specified in terms of the input fields. If not, call registerOutput(RexNode) first.

        Parameters:
        expr - Expression to add
        name - Name of field in output row type; if null, a unique name will be generated when the program is created
        Returns:
        the ref created
      • addProject

        public RexLocalRef addProject​(int ordinal,
                                      java.lang.String name)
        Adds a projection based upon the indexth expression.
        Parameters:
        ordinal - Index of expression to project
        name - Name of field in output row type; if null, a unique name will be generated when the program is created
        Returns:
        the ref created
      • addProject

        public RexLocalRef addProject​(int at,
                                      RexNode expr,
                                      java.lang.String name)
        Adds a project expression to the program at a given position.

        The expression specified in terms of the input fields. If not, call registerOutput(RexNode) first.

        Parameters:
        at - Position in project list to add expression
        expr - Expression to add
        name - Name of field in output row type; if null, a unique name will be generated when the program is created
        Returns:
        the ref created
      • addProject

        public RexLocalRef addProject​(int at,
                                      int ordinal,
                                      java.lang.String name)
        Adds a projection based upon the indexth expression at a given position.
        Parameters:
        at - Position in project list to add expression
        ordinal - Index of expression to project
        name - Name of field in output row type; if null, a unique name will be generated when the program is created
        Returns:
        the ref created
      • addCondition

        public void addCondition​(RexNode expr)
        Sets the condition of the program.

        The expression must be specified in terms of the input fields. If not, call registerOutput(RexNode) first.

      • registerInput

        public RexLocalRef registerInput​(RexNode expr)
        Registers an expression in the list of common sub-expressions, and returns a reference to that expression.

        The expression must be expressed in terms of the inputs of this program.

      • registerOutput

        public RexLocalRef registerOutput​(RexNode expr)
        Converts an expression expressed in terms of the outputs of this program into an expression expressed in terms of the inputs, registers it in the list of common sub-expressions, and returns a reference to that expression.
        Parameters:
        expr - Expression to register
      • registerInternal

        private RexLocalRef registerInternal​(RexNode expr,
                                             boolean force)
        Registers an expression in the list of common sub-expressions, and returns a reference to that expression.

        If an equivalent sub-expression already exists, creates another expression only if force is true.

        Parameters:
        expr - Expression to register
        force - Whether to create a new sub-expression if an equivalent sub-expression exists.
      • addExpr

        public RexLocalRef addExpr​(RexNode expr)
        Adds an expression to the list of common expressions, and returns a reference to the expression. DOES NOT CHECK WHETHER THE EXPRESSION ALREADY EXISTS.
        Parameters:
        expr - Expression
        Returns:
        Reference to expression
      • getProgram

        public RexProgram getProgram()
        Converts the state of the program builder to an immutable program, normalizing in the process.

        It is OK to call this method, modify the program specification (by adding projections, and so forth), and call this method again.

      • getProgram

        public RexProgram getProgram​(boolean normalize)
        Converts the state of the program builder to an immutable program.

        It is OK to call this method, modify the program specification (by adding projections, and so forth), and call this method again.

        Parameters:
        normalize - Whether to normalize
      • computeOutputRowType

        private RelDataType computeOutputRowType()
      • generateMissingNames

        private void generateMissingNames()
      • forProgram

        public static RexProgramBuilder forProgram​(RexProgram program,
                                                   RexBuilder rexBuilder,
                                                   boolean normalize)
        Creates a program builder and initializes it from an existing program.

        Calling getProgram() immediately after creation will return a program equivalent (in terms of external behavior) to the existing program.

        The existing program will not be changed. (It cannot: programs are immutable.)

        Parameters:
        program - Existing program
        rexBuilder - Rex builder
        normalize - Whether to normalize
        Returns:
        A program builder initialized with an equivalent program
      • create

        public static RexProgramBuilder create​(RexBuilder rexBuilder,
                                               RelDataType inputRowType,
                                               java.util.List<RexNode> exprList,
                                               java.util.List<? extends RexNode> projectList,
                                               RexNode condition,
                                               RelDataType outputRowType,
                                               boolean normalize,
                                               RexSimplify simplify)
        Creates a program builder with the same contents as a program.

        If normalize, converts the program to canonical form. In canonical form, in addition to the usual constraints:

        • The first N internal expressions are RexInputRefs to the N input fields;
        • Subsequent internal expressions reference only preceding expressions;
        • Arguments to RexCalls must be RexLocalRefs (that is, expressions must have maximum depth 1)

        there are additional constraints:

        • Expressions appear in the left-deep order they are needed by the projections and (if present) the condition. Thus, expression N+1 is the leftmost argument (literal or or call) in the expansion of projection #0.
        • There are no duplicate expressions
        • There are no unused expressions
        Parameters:
        rexBuilder - Rex builder
        inputRowType - Input row type
        exprList - Common expressions
        projectList - Projections
        condition - Condition, or null
        outputRowType - Output row type
        normalize - Whether to normalize
        simplify - Whether to simplify expressions
        Returns:
        A program builder
      • create

        public static RexProgramBuilder create​(RexBuilder rexBuilder,
                                               RelDataType inputRowType,
                                               java.util.List<RexNode> exprList,
                                               java.util.List<RexLocalRef> projectRefList,
                                               RexLocalRef conditionRef,
                                               RelDataType outputRowType,
                                               RexShuttle shuttle,
                                               boolean updateRefs)
        Creates a program builder with the same contents as a program, applying a shuttle first.

        TODO: Refactor the above create method in terms of this one.

        Parameters:
        rexBuilder - Rex builder
        inputRowType - Input row type
        exprList - Common expressions
        projectRefList - Projections
        conditionRef - Condition, or null
        outputRowType - Output row type
        shuttle - Shuttle to apply to each expression before adding it to the program builder
        updateRefs - Whether to update references that changes as a result of rewrites made by the shuttle
        Returns:
        A program builder
      • add

        private void add​(java.util.List<RexNode> exprList,
                         java.util.List<RexLocalRef> projectRefList,
                         RexLocalRef conditionRef,
                         RelDataType outputRowType,
                         RexShuttle shuttle,
                         boolean updateRefs)
        Adds a set of expressions, projections and filters, applying a shuttle first.
        Parameters:
        exprList - Common expressions
        projectRefList - Projections
        conditionRef - Condition, or null
        outputRowType - Output row type
        shuttle - Shuttle to apply to each expression before adding it to the program builder
        updateRefs - Whether to update references that changes as a result of rewrites made by the shuttle
      • mergePrograms

        public static RexProgram mergePrograms​(RexProgram topProgram,
                                               RexProgram bottomProgram,
                                               RexBuilder rexBuilder)
        Merges two programs together, and normalizes the result.
        Parameters:
        topProgram - Top program. Its expressions are in terms of the outputs of the bottom program.
        bottomProgram - Bottom program. Its expressions are in terms of the result fields of the relational expression's input
        rexBuilder - Rex builder
        Returns:
        Merged program
        See Also:
        mergePrograms(RexProgram, RexProgram, RexBuilder, boolean)
      • mergePrograms

        public static RexProgram mergePrograms​(RexProgram topProgram,
                                               RexProgram bottomProgram,
                                               RexBuilder rexBuilder,
                                               boolean normalize)
        Merges two programs together.

        All expressions become common sub-expressions. For example, the query

        SELECT x + 1 AS p, x + y AS q FROM (
           SELECT a + b AS x, c AS y
           FROM t
           WHERE c = 6)}

        would be represented as the programs

           Calc:
               Projects={$2, $3},
               Condition=null,
               Exprs={$0, $1, $0 + 1, $0 + $1})
           Calc(
               Projects={$3, $2},
               Condition={$4}
               Exprs={$0, $1, $2, $0 + $1, $2 = 6}
         

        The merged program is

           Calc(
              Projects={$4, $5}
              Condition=$6
              Exprs={0: $0       // a
                     1: $1        // b
                     2: $2        // c
                     3: ($0 + $1) // x = a + b
                     4: ($3 + 1)  // p = x + 1
                     5: ($3 + $2) // q = x + y
                     6: ($2 = 6)  // c = 6
         

        Another example:

        SELECT *
         FROM (
           SELECT a + b AS x, c AS y
           FROM t
           WHERE c = 6)
         WHERE x = 5

        becomes

        SELECT a + b AS x, c AS y
         FROM t
         WHERE c = 6 AND (a + b) = 5
        Parameters:
        topProgram - Top program. Its expressions are in terms of the outputs of the bottom program.
        bottomProgram - Bottom program. Its expressions are in terms of the result fields of the relational expression's input
        rexBuilder - Rex builder
        normalize - Whether to convert program to canonical form
        Returns:
        Merged program
      • registerProjectsAndCondition

        private java.util.List<RexLocalRef> registerProjectsAndCondition​(RexProgram program)
      • clearProjects

        public void clearProjects()
        Removes all project items.

        After calling this method, you may need to re-normalize.

      • clearCondition

        public void clearCondition()
        Clears the condition.

        After calling this method, you may need to re-normalize.

      • addIdentity

        public void addIdentity()
        Adds a project item for every input field.

        You cannot call this method if there are other project items.

      • makeInputRef

        public RexLocalRef makeInputRef​(int index)
        Creates a reference to a given input field.
        Parameters:
        index - Ordinal of input field, must be less than the number of fields in the input type
        Returns:
        Reference to input field
      • getInputRowType

        public RelDataType getInputRowType()
        Returns the rowtype of the input to the program
      • getProjectList

        public java.util.List<RexLocalRef> getProjectList()
        Returns the list of project expressions.