Class RexProgramBuilder

java.lang.Object
org.apache.calcite.rex.RexProgramBuilder

public class RexProgramBuilder extends 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.)

  • Constructor Details

    • RexProgramBuilder

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

    • addProject

      public RexLocalRef addProject(RexNode expr, @Nullable 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, @Nullable 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, 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, 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
    • 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
    • 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, List<RexNode> exprList, List<? extends RexNode> projectList, @Nullable RexNode condition, RelDataType outputRowType, boolean normalize, @Nullable 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

      @Deprecated public static RexProgramBuilder create(RexBuilder rexBuilder, RelDataType inputRowType, List<RexNode> exprList, List<? extends RexNode> projectList, @Nullable RexNode condition, RelDataType outputRowType, boolean normalize, boolean simplify_)
      Deprecated.
    • create

      @Deprecated public static RexProgramBuilder create(RexBuilder rexBuilder, RelDataType inputRowType, List<RexNode> exprList, List<? extends RexNode> projectList, @Nullable RexNode condition, RelDataType outputRowType, boolean normalize)
      Deprecated.
    • create

      public static RexProgramBuilder create(RexBuilder rexBuilder, RelDataType inputRowType, List<RexNode> exprList, List<RexLocalRef> projectRefList, @Nullable 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
    • normalize

      @Deprecated public static RexProgram normalize(RexBuilder rexBuilder, RexProgram program)
      Deprecated.
    • 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

      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
    • 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 row type of the input to the program.
    • getProjectList

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