org.apache.calcite.rex.RexProgramBuilder Java Examples

The following examples show how to use org.apache.calcite.rex.RexProgramBuilder. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: EnumerableFilterToCalcRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final EnumerableFilter filter = call.rel(0);
  final RelNode input = filter.getInput();

  // Create a program containing a filter.
  final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
  final RelDataType inputRowType = input.getRowType();
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(inputRowType, rexBuilder);
  programBuilder.addIdentity();
  programBuilder.addCondition(filter.getCondition());
  final RexProgram program = programBuilder.getProgram();

  final EnumerableCalc calc = EnumerableCalc.create(input, program);
  call.transformTo(calc);
}
 
Example #2
Source File: ReduceDecimalsRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    LogicalCalc calc = call.rel(0);

    // Expand decimals in every expression in this program. If no
    // expression changes, don't apply the rule.
    final RexProgram program = calc.getProgram();
    if (!RexUtil.requiresDecimalExpansion(program, true)) {
        return;
    }

    final RexBuilder rexBuilder = calc.getCluster().getRexBuilder();
    final RexShuttle shuttle = new DecimalShuttle(rexBuilder);
    RexProgramBuilder programBuilder = RexProgramBuilder.create(rexBuilder, calc.getInput().getRowType(),
            program.getExprList(), program.getProjectList(), program.getCondition(), program.getOutputRowType(),
            shuttle, true);

    final RexProgram newProgram = programBuilder.getProgram();
    LogicalCalc newCalc = LogicalCalc.create(calc.getInput(), newProgram);
    call.transformTo(newCalc);
}
 
Example #3
Source File: FilterMergeCrule.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Filter topFilter = call.rel(0);
  final Filter bottomFilter = call.rel(1);

  // use RexPrograms to merge the two FilterRels into a single program
  // so we can convert the two LogicalFilter conditions to directly
  // reference the bottom LogicalFilter's child
  RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
  RexProgram bottomProgram = createProgram(bottomFilter);
  RexProgram topProgram = createProgram(topFilter);

  RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);

  RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());

  final RelBuilder relBuilder = call.builder();
  relBuilder.push(bottomFilter.getInput()).filter(newCondition);

  call.transformTo(relBuilder.build());
}
 
Example #4
Source File: FilterMergeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Filter topFilter = call.rel(0);
  final Filter bottomFilter = call.rel(1);

  // use RexPrograms to merge the two FilterRels into a single program
  // so we can convert the two LogicalFilter conditions to directly
  // reference the bottom LogicalFilter's child
  RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
  RexProgram bottomProgram = createProgram(bottomFilter);
  RexProgram topProgram = createProgram(topFilter);

  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);

  RexNode newCondition =
      mergedProgram.expandLocalRef(
          mergedProgram.getCondition());

  final RelBuilder relBuilder = call.builder();
  relBuilder.push(bottomFilter.getInput())
      .filter(newCondition);

  call.transformTo(relBuilder.build());
}
 
Example #5
Source File: RelWriterTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testCalc() {
  final FrameworkConfig config = RelBuilderTest.config().build();
  final RelBuilder builder = RelBuilder.create(config);
  final RexBuilder rexBuilder = builder.getRexBuilder();
  final LogicalTableScan scan = (LogicalTableScan) builder.scan("EMP").build();
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(scan.getRowType(), rexBuilder);
  final RelDataTypeField field = scan.getRowType().getField("SAL", false, false);
  programBuilder.addIdentity();
  programBuilder.addCondition(
      rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
          new RexInputRef(field.getIndex(), field.getType()),
          builder.literal(10)));
  final LogicalCalc calc = LogicalCalc.create(scan, programBuilder.getProgram());
  String relJson = RelOptUtil.dumpPlan("", calc,
      SqlExplainFormat.JSON, SqlExplainLevel.EXPPLAN_ATTRIBUTES);
  String s =
      Frameworks.withPlanner((cluster, relOptSchema, rootSchema) -> {
        final RelJsonReader reader = new RelJsonReader(
            cluster, getSchema(calc), rootSchema);
        RelNode node;
        try {
          node = reader.read(relJson);
        } catch (IOException e) {
          throw TestUtil.rethrow(e);
        }
        return RelOptUtil.dumpPlan("", node, SqlExplainFormat.TEXT,
            SqlExplainLevel.EXPPLAN_ATTRIBUTES);
      });
  final String expected =
      "LogicalCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[>($t5, $t8)],"
          + " proj#0..7=[{exprs}], $condition=[$t9])\n"
          + "  LogicalTableScan(table=[[scott, EMP]])\n";
  assertThat(s, isLinux(expected));
}
 
Example #6
Source File: EnumUtils.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Returns a predicate expression based on a join condition. **/
static Expression generatePredicate(
    EnumerableRelImplementor implementor,
    RexBuilder rexBuilder,
    RelNode left,
    RelNode right,
    PhysType leftPhysType,
    PhysType rightPhysType,
    RexNode condition) {
  final BlockBuilder builder = new BlockBuilder();
  final ParameterExpression left_ =
      Expressions.parameter(leftPhysType.getJavaRowType(), "left");
  final ParameterExpression right_ =
      Expressions.parameter(rightPhysType.getJavaRowType(), "right");
  final RexProgramBuilder program =
      new RexProgramBuilder(
          implementor.getTypeFactory().builder()
              .addAll(left.getRowType().getFieldList())
              .addAll(right.getRowType().getFieldList())
              .build(),
          rexBuilder);
  program.addCondition(condition);
  builder.add(
      Expressions.return_(null,
          RexToLixTranslator.translateCondition(program.getProgram(),
              implementor.getTypeFactory(),
              builder,
              new RexToLixTranslator.InputGetterImpl(
                  ImmutableList.of(Pair.of(left_, leftPhysType),
                      Pair.of(right_, rightPhysType))),
              implementor.allCorrelateVariables,
              implementor.getConformance())));
  return Expressions.lambda(Predicate2.class, builder.toBlock(), left_, right_);
}
 
Example #7
Source File: ReduceDecimalsRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  LogicalCalc calc = call.rel(0);

  // Expand decimals in every expression in this program. If no
  // expression changes, don't apply the rule.
  final RexProgram program = calc.getProgram();
  if (!RexUtil.requiresDecimalExpansion(program, true)) {
    return;
  }

  final RexBuilder rexBuilder = calc.getCluster().getRexBuilder();
  final RexShuttle shuttle = new DecimalShuttle(rexBuilder);
  RexProgramBuilder programBuilder =
      RexProgramBuilder.create(
          rexBuilder,
          calc.getInput().getRowType(),
          program.getExprList(),
          program.getProjectList(),
          program.getCondition(),
          program.getOutputRowType(),
          shuttle,
          true);

  final RexProgram newProgram = programBuilder.getProgram();
  LogicalCalc newCalc = LogicalCalc.create(calc.getInput(), newProgram);
  call.transformTo(newCalc);
}
 
Example #8
Source File: FilterCalcMergeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final LogicalFilter filter = call.rel(0);
  final LogicalCalc calc = call.rel(1);

  // Don't merge a filter onto a calc which contains windowed aggregates.
  // That would effectively be pushing a multiset down through a filter.
  // We'll have chance to merge later, when the over is expanded.
  if (calc.getProgram().containsAggs()) {
    return;
  }

  // Create a program containing the filter.
  final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
  final RexProgramBuilder progBuilder =
      new RexProgramBuilder(
          calc.getRowType(),
          rexBuilder);
  progBuilder.addIdentity();
  progBuilder.addCondition(filter.getCondition());
  RexProgram topProgram = progBuilder.getProgram();
  RexProgram bottomProgram = calc.getProgram();

  // Merge the programs together.
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);
  final LogicalCalc newCalc =
      LogicalCalc.create(calc.getInput(), mergedProgram);
  call.transformTo(newCalc);
}
 
Example #9
Source File: PythonCorrelateSplitRule.java    From flink with Apache License 2.0 5 votes vote down vote up
private FlinkLogicalCalc createTopCalc(
	int primitiveLeftFieldCount,
	RexBuilder rexBuilder,
	ArrayBuffer<RexNode> extractedRexNodes,
	RelDataType calcRowType,
	FlinkLogicalCorrelate newCorrelate) {
	RexProgram rexProgram = new RexProgramBuilder(newCorrelate.getRowType(), rexBuilder).getProgram();
	int offset = extractedRexNodes.size() + primitiveLeftFieldCount;

	// extract correlate output RexNode.
	List<RexNode> newTopCalcProjects = rexProgram
		.getExprList()
		.stream()
		.filter(x -> x instanceof RexInputRef)
		.filter(x -> {
			int index = ((RexInputRef) x).getIndex();
			return index < primitiveLeftFieldCount || index >= offset;
		})
		.collect(Collectors.toList());

	return new FlinkLogicalCalc(
		newCorrelate.getCluster(),
		newCorrelate.getTraitSet(),
		newCorrelate,
		RexProgram.create(
			newCorrelate.getRowType(),
			newTopCalcProjects,
			null,
			calcRowType,
			rexBuilder));
}
 
Example #10
Source File: PythonCorrelateSplitRule.java    From flink with Apache License 2.0 5 votes vote down vote up
private FlinkLogicalCalc createTopCalc(
	int primitiveLeftFieldCount,
	RexBuilder rexBuilder,
	ArrayBuffer<RexNode> extractedRexNodes,
	RelDataType calcRowType,
	FlinkLogicalCorrelate newCorrelate) {
	RexProgram rexProgram = new RexProgramBuilder(newCorrelate.getRowType(), rexBuilder).getProgram();
	int offset = extractedRexNodes.size() + primitiveLeftFieldCount;

	// extract correlate output RexNode.
	List<RexNode> newTopCalcProjects = rexProgram
		.getExprList()
		.stream()
		.filter(x -> x instanceof RexInputRef)
		.filter(x -> {
			int index = ((RexInputRef) x).getIndex();
			return index < primitiveLeftFieldCount || index >= offset;
		})
		.collect(Collectors.toList());

	return new FlinkLogicalCalc(
		newCorrelate.getCluster(),
		newCorrelate.getTraitSet(),
		newCorrelate,
		RexProgram.create(
			newCorrelate.getRowType(),
			newTopCalcProjects,
			null,
			calcRowType,
			rexBuilder));
}
 
Example #11
Source File: OLAPFilterRel.java    From kylin with Apache License 2.0 5 votes vote down vote up
@Override
public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
    // keep it for having clause
    RexBuilder rexBuilder = getCluster().getRexBuilder();
    RelDataType inputRowType = getInput().getRowType();
    RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
    programBuilder.addIdentity();
    programBuilder.addCondition(this.condition);
    RexProgram program = programBuilder.getProgram();

    return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
            sole(inputs), program);
}
 
Example #12
Source File: RexNodeToJavaCodeCompiler.java    From streamline with Apache License 2.0 5 votes vote down vote up
public String compile(List<RexNode> nodes, RelDataType inputRowType, String className) {
  final RexProgramBuilder programBuilder =
          new RexProgramBuilder(inputRowType, rexBuilder);
  for (RexNode node : nodes) {
    programBuilder.addProject(node, null);
  }

  return compile(programBuilder.getProgram(), className);
}
 
Example #13
Source File: RexNodeToJavaCodeCompiler.java    From streamline with Apache License 2.0 5 votes vote down vote up
public BlockStatement compileToBlock(List<RexNode> nodes, RelDataType inputRowType) {
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(inputRowType, rexBuilder);
  for (RexNode node : nodes) {
    programBuilder.addProject(node, null);
  }

  return compileToBlock(programBuilder.getProgram());
}
 
Example #14
Source File: ExpressionCompiler.java    From attic-apex-malhar with Apache License 2.0 5 votes vote down vote up
/**
 * Create quasi-Java expression from given {@link RexNode}
 *
 * @param node Expression in the form of {@link RexNode}
 * @param inputRowType Input Data type to expression in the form of {@link RelDataType}
 * @param outputRowType Output data type of expression in the form of {@link RelDataType}
 *
 * @return Returns quasi-Java expression
 */
public String getExpression(RexNode node, RelDataType inputRowType, RelDataType outputRowType)
{
  final RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
  programBuilder.addProject(node, null);
  final RexProgram program = programBuilder.getProgram();

  final BlockBuilder builder = new BlockBuilder();
  final JavaTypeFactory javaTypeFactory = (JavaTypeFactory)rexBuilder.getTypeFactory();

  final RexToLixTranslator.InputGetter inputGetter = new RexToLixTranslator.InputGetterImpl(ImmutableList
      .of(Pair.<Expression, PhysType>of(Expressions.variable(Object[].class, "inputValues"),
      PhysTypeImpl.of(javaTypeFactory, inputRowType, JavaRowFormat.ARRAY, false))));
  final Function1<String, RexToLixTranslator.InputGetter> correlates =
      new Function1<String, RexToLixTranslator.InputGetter>()
    {
      public RexToLixTranslator.InputGetter apply(String a0)
      {
        throw new UnsupportedOperationException();
      }
    };

  final List<Expression> list = RexToLixTranslator.translateProjects(program, javaTypeFactory, builder,
      PhysTypeImpl.of(javaTypeFactory, outputRowType, JavaRowFormat.ARRAY, false), null, inputGetter, correlates);

  for (int i = 0; i < list.size(); i++) {
    Statement statement = Expressions.statement(list.get(i));
    builder.add(statement);
  }

  return finalizeExpression(builder.toBlock(), inputRowType);
}
 
Example #15
Source File: OLAPFilterRel.java    From kylin-on-parquet-v2 with Apache License 2.0 5 votes vote down vote up
@Override
public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
    // keep it for having clause
    RexBuilder rexBuilder = getCluster().getRexBuilder();
    RelDataType inputRowType = getInput().getRowType();
    RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
    programBuilder.addIdentity();
    programBuilder.addCondition(this.condition);
    RexProgram program = programBuilder.getProgram();

    return new EnumerableCalc(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), //
            sole(inputs), program);
}
 
Example #16
Source File: HiveRexExecutorImpl.java    From marble with Apache License 2.0 5 votes vote down vote up
private String compile(RexBuilder rexBuilder, List<RexNode> constExps,
    RexToLixTranslator.InputGetter getter, RelDataType rowType) {
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(rowType, rexBuilder);
  for (RexNode node : constExps) {
    programBuilder.addProject(
        node, "c" + programBuilder.getProjectList().size());
  }
  final JavaTypeFactoryImpl javaTypeFactory =
      new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
  final BlockBuilder blockBuilder = new BlockBuilder();
  final ParameterExpression root0_ =
      Expressions.parameter(Object.class, "root0");
  final ParameterExpression root_ = DataContext.ROOT;
  blockBuilder.add(
      Expressions.declare(
          Modifier.FINAL, root_,
          Expressions.convert_(root0_, DataContext.class)));
  final SqlConformance conformance = SqlConformanceEnum.HIVE;
  final RexProgram program = programBuilder.getProgram();
  final List<Expression> expressions =
      RexToLixTranslator.translateProjects(program, javaTypeFactory,
          conformance, blockBuilder, null, root_, getter, null);
  blockBuilder.add(
      Expressions.return_(null,
          Expressions.newArrayInit(Object[].class, expressions)));
  final MethodDeclaration methodDecl =
      Expressions.methodDecl(Modifier.PUBLIC, Object[].class,
          BuiltInMethod.FUNCTION1_APPLY.method.getName(),
          ImmutableList.of(root0_), blockBuilder.toBlock());
  String code = Expressions.toString(methodDecl);
  if (CalcitePrepareImpl.DEBUG) {
    Util.debugCode(System.out, code);
  }
  return code;
}
 
Example #17
Source File: FilterMergeCrule.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a RexProgram corresponding to a LogicalFilter
 *
 * @param filterRel
 *          the LogicalFilter
 * @return created RexProgram
 */
private RexProgram createProgram(Filter filterRel) {
  RexProgramBuilder programBuilder = new RexProgramBuilder(filterRel.getRowType(),
      filterRel.getCluster().getRexBuilder());
  programBuilder.addIdentity();
  programBuilder.addCondition(filterRel.getCondition());
  return programBuilder.getProgram();
}
 
Example #18
Source File: DrillMergeFilterRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a RexProgram corresponding to a LogicalFilter
 *
 * @param filterRel the LogicalFilter
 * @return created RexProgram
 */
private RexProgram createProgram(Filter filterRel) {
  RexProgramBuilder programBuilder =
      new RexProgramBuilder(
          filterRel.getRowType(),
          filterRel.getCluster().getRexBuilder());
  programBuilder.addIdentity();
  programBuilder.addCondition(filterRel.getCondition());
  return programBuilder.getProgram();
}
 
Example #19
Source File: FilterMergeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a RexProgram corresponding to a LogicalFilter
 *
 * @param filterRel the LogicalFilter
 * @return created RexProgram
 */
private RexProgram createProgram(Filter filterRel) {
  RexProgramBuilder programBuilder =
      new RexProgramBuilder(
          filterRel.getRowType(),
          filterRel.getCluster().getRexBuilder());
  programBuilder.addIdentity();
  programBuilder.addCondition(filterRel.getCondition());
  return programBuilder.getProgram();
}
 
Example #20
Source File: DrillMergeFilterRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
    Filter topFilter = call.rel(0);
    Filter bottomFilter = call.rel(1);

    // use RexPrograms to merge the two FilterRels into a single program
    // so we can convert the two FilterRel conditions to directly
    // reference the bottom FilterRel's child
    RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
    RexProgram bottomProgram = createProgram(bottomFilter);
    RexProgram topProgram = createProgram(topFilter);

    RexProgram mergedProgram =
        RexProgramBuilder.mergePrograms(
            topProgram,
            bottomProgram,
            rexBuilder);

    RexNode newCondition =
        mergedProgram.expandLocalRef(
            mergedProgram.getCondition());

//    if(!RexUtil.isFlat(newCondition)){
//      RexCall newCall = (RexCall) newCondition;
//      newCondition = rexBuilder.makeFlatCall( newCall.getOperator(), newCall.getOperands());
//    }

    Filter newFilterRel =
        (Filter) filterFactory.createFilter(
            bottomFilter.getInput(),
            RexUtil.flatten(rexBuilder, newCondition));

    call.transformTo(newFilterRel);
  }
 
Example #21
Source File: RelStructuredTypeFlattener.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void rewriteRel(LogicalCalc rel) {
    // Translate the child.
    final RelNode newInput = getNewForOldRel(rel.getInput());

    final RelOptCluster cluster = rel.getCluster();
    RexProgramBuilder programBuilder = new RexProgramBuilder(newInput.getRowType(), cluster.getRexBuilder());

    // Convert the common expressions.
    final RexProgram program = rel.getProgram();
    final RewriteRexShuttle shuttle = new RewriteRexShuttle();
    for (RexNode expr : program.getExprList()) {
        programBuilder.registerInput(expr.accept(shuttle));
    }

    // Convert the projections.
    final List<Pair<RexNode, String>> flattenedExpList = new ArrayList<>();
    List<String> fieldNames = rel.getRowType().getFieldNames();
    flattenProjections(new RewriteRexShuttle(), program.getProjectList(), fieldNames, "", flattenedExpList);

    // Register each of the new projections.
    for (Pair<RexNode, String> flattenedExp : flattenedExpList) {
        programBuilder.addProject(flattenedExp.left, flattenedExp.right);
    }

    // Translate the condition.
    final RexLocalRef conditionRef = program.getCondition();
    if (conditionRef != null) {
        final Ord<RelDataType> newField = getNewFieldForOldInput(conditionRef.getIndex());
        programBuilder.addCondition(RexBuilder.getRexFactory().makeInputRef(newField.i, newField.e));
    }

    RexProgram newProgram = programBuilder.getProgram();

    // Create a new calc relational expression.
    LogicalCalc newRel = LogicalCalc.create(newInput, newProgram);
    setNewForOldRel(rel, newRel);
}
 
Example #22
Source File: FilterCalcMergeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final LogicalFilter filter = call.rel(0);
  final LogicalCalc calc = call.rel(1);

  // Don't merge a filter onto a calc which contains windowed aggregates.
  // That would effectively be pushing a multiset down through a filter.
  // We'll have chance to merge later, when the over is expanded.
  if (calc.getProgram().containsAggs()) {
    return;
  }

  // Create a program containing the filter.
  final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
  final RexProgramBuilder progBuilder =
      new RexProgramBuilder(
          calc.getRowType(),
          rexBuilder);
  progBuilder.addIdentity();
  progBuilder.addCondition(filter.getCondition());
  RexProgram topProgram = progBuilder.getProgram();
  RexProgram bottomProgram = calc.getProgram();

  // Merge the programs together.
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);
  final LogicalCalc newCalc =
      LogicalCalc.create(calc.getInput(), mergedProgram);
  call.transformTo(newCalc);
}
 
Example #23
Source File: ProjectCalcMergeRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final LogicalProject project = call.rel(0);
  final LogicalCalc calc = call.rel(1);

  // Don't merge a project which contains windowed aggregates onto a
  // calc. That would effectively be pushing a windowed aggregate down
  // through a filter. Transform the project into an identical calc,
  // which we'll have chance to merge later, after the over is
  // expanded.
  final RelOptCluster cluster = project.getCluster();
  RexProgram program =
      RexProgram.create(
          calc.getRowType(),
          project.getProjects(),
          null,
          project.getRowType(),
          cluster.getRexBuilder());
  if (RexOver.containsOver(program)) {
    LogicalCalc projectAsCalc = LogicalCalc.create(calc, program);
    call.transformTo(projectAsCalc);
    return;
  }

  // Create a program containing the project node's expressions.
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  final RexProgramBuilder progBuilder =
      new RexProgramBuilder(
          calc.getRowType(),
          rexBuilder);
  for (Pair<RexNode, String> field : project.getNamedProjects()) {
    progBuilder.addProject(field.left, field.right);
  }
  RexProgram topProgram = progBuilder.getProgram();
  RexProgram bottomProgram = calc.getProgram();

  // Merge the programs together.
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);
  final LogicalCalc newCalc =
      LogicalCalc.create(calc.getInput(), mergedProgram);
  call.transformTo(newCalc);
}
 
Example #24
Source File: JaninoRexCompiler.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Scalar compile(List<RexNode> nodes, RelDataType inputRowType) {
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(inputRowType, rexBuilder);
  for (RexNode node : nodes) {
    programBuilder.addProject(node, null);
  }
  final RexProgram program = programBuilder.getProgram();

  final BlockBuilder builder = new BlockBuilder();
  final ParameterExpression context_ =
      Expressions.parameter(Context.class, "context");
  final ParameterExpression outputValues_ =
      Expressions.parameter(Object[].class, "outputValues");
  final JavaTypeFactoryImpl javaTypeFactory =
      new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());

  // public void execute(Context, Object[] outputValues)
  final RexToLixTranslator.InputGetter inputGetter =
      new RexToLixTranslator.InputGetterImpl(
          ImmutableList.of(
              Pair.of(
                  Expressions.field(context_,
                      BuiltInMethod.CONTEXT_VALUES.field),
                  PhysTypeImpl.of(javaTypeFactory, inputRowType,
                      JavaRowFormat.ARRAY, false))));
  final Function1<String, RexToLixTranslator.InputGetter> correlates = a0 -> {
    throw new UnsupportedOperationException();
  };
  final Expression root =
      Expressions.field(context_, BuiltInMethod.CONTEXT_ROOT.field);
  final SqlConformance conformance =
      SqlConformanceEnum.DEFAULT; // TODO: get this from implementor
  final List<Expression> list =
      RexToLixTranslator.translateProjects(program, javaTypeFactory,
          conformance, builder, null, root, inputGetter, correlates);
  for (int i = 0; i < list.size(); i++) {
    builder.add(
        Expressions.statement(
            Expressions.assign(
                Expressions.arrayIndex(outputValues_,
                    Expressions.constant(i)),
                list.get(i))));
  }
  return baz(context_, outputValues_, builder.toBlock());
}
 
Example #25
Source File: RelStructuredTypeFlattener.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void rewriteRel(LogicalCalc rel) {
  // Translate the child.
  final RelNode newInput = getNewForOldRel(rel.getInput());

  final RelOptCluster cluster = rel.getCluster();
  RexProgramBuilder programBuilder =
      new RexProgramBuilder(
          newInput.getRowType(),
          cluster.getRexBuilder());

  // Convert the common expressions.
  final RexProgram program = rel.getProgram();
  final RewriteRexShuttle shuttle = new RewriteRexShuttle();
  for (RexNode expr : program.getExprList()) {
    programBuilder.registerInput(expr.accept(shuttle));
  }

  // Convert the projections.
  final List<Pair<RexNode, String>> flattenedExpList = new ArrayList<>();
  List<String> fieldNames = rel.getRowType().getFieldNames();
  flattenProjections(new RewriteRexShuttle(),
      program.getProjectList(),
      fieldNames,
      "",
      flattenedExpList);

  // Register each of the new projections.
  for (Pair<RexNode, String> flattenedExp : flattenedExpList) {
    programBuilder.addProject(flattenedExp.left, flattenedExp.right);
  }

  // Translate the condition.
  final RexLocalRef conditionRef = program.getCondition();
  if (conditionRef != null) {
    final Ord<RelDataType> newField =
        getNewFieldForOldInput(conditionRef.getIndex());
    programBuilder.addCondition(new RexLocalRef(newField.i, newField.e));
  }

  RexProgram newProgram = programBuilder.getProgram();

  // Create a new calc relational expression.
  LogicalCalc newRel = LogicalCalc.create(newInput, newProgram);
  setNewForOldRel(rel, newRel);
}
 
Example #26
Source File: EnumerableMatch.java    From calcite with Apache License 2.0 4 votes vote down vote up
private Expression implementMatcher(EnumerableRelImplementor implementor,
    PhysType physType, BlockBuilder builder, ParameterExpression row_) {
  final Expression patternBuilder_ = builder.append("patternBuilder",
      Expressions.call(BuiltInMethod.PATTERN_BUILDER.method));
  final Expression automaton_ = builder.append("automaton",
      Expressions.call(implementPattern(patternBuilder_, pattern),
          BuiltInMethod.PATTERN_TO_AUTOMATON.method));
  Expression matcherBuilder_ = builder.append("matcherBuilder",
      Expressions.call(BuiltInMethod.MATCHER_BUILDER.method, automaton_));
  final BlockBuilder builder2 = new BlockBuilder();


  // Wrap a MemoryEnumerable around

  for (Map.Entry<String, RexNode> entry : patternDefinitions.entrySet()) {
    // Translate REX to Expressions
    RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
    RexProgramBuilder rexProgramBuilder =
        new RexProgramBuilder(physType.getRowType(), rexBuilder);

    rexProgramBuilder.addCondition(entry.getValue());

    final RexToLixTranslator.InputGetter inputGetter1 =
        new PrevInputGetter(row_, physType);

    final Expression condition = RexToLixTranslator
        .translateCondition(rexProgramBuilder.getProgram(),
            (JavaTypeFactory) getCluster().getTypeFactory(),
            builder2,
            inputGetter1,
            implementor.allCorrelateVariables,
            implementor.getConformance());

    builder2.add(Expressions.return_(null, condition));
    final Expression predicate_ =
        implementPredicate(physType, row_, builder2.toBlock());

    matcherBuilder_ = Expressions.call(matcherBuilder_,
        BuiltInMethod.MATCHER_BUILDER_ADD.method,
        Expressions.constant(entry.getKey()),
        predicate_);
  }
  return builder.append("matcher",
      Expressions.call(matcherBuilder_,
          BuiltInMethod.MATCHER_BUILDER_BUILD.method));
}
 
Example #27
Source File: EnumerableMatch.java    From calcite with Apache License 2.0 4 votes vote down vote up
private Expression implementEmitter(EnumerableRelImplementor implementor,
    PhysType physType, PhysType inputPhysType) {
  final ParameterExpression rows_ =
      Expressions.parameter(Types.of(List.class, inputPhysType.getJavaRowType()), "rows");
  final ParameterExpression rowStates_ =
      Expressions.parameter(List.class, "rowStates");
  final ParameterExpression symbols_ =
      Expressions.parameter(List.class, "symbols");
  final ParameterExpression match_ =
      Expressions.parameter(int.class, "match");
  final ParameterExpression consumer_ =
      Expressions.parameter(Consumer.class, "consumer");
  final ParameterExpression i_ = Expressions.parameter(int.class, "i");

  final ParameterExpression row_ =
      Expressions.parameter(inputPhysType.getJavaRowType(), "row");

  final BlockBuilder builder2 = new BlockBuilder();

  // Add loop variable initialization
  builder2.add(
      Expressions.declare(0, row_,
          EnumUtils.convert(
              Expressions.call(rows_, BuiltInMethod.LIST_GET.method, i_),
              inputPhysType.getJavaRowType())));

  RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
  RexProgramBuilder rexProgramBuilder =
      new RexProgramBuilder(inputPhysType.getRowType(), rexBuilder);
  for (Map.Entry<String, RexNode> entry : measures.entrySet()) {
    rexProgramBuilder.addProject(entry.getValue(), entry.getKey());
  }

  final RexToLixTranslator translator = RexToLixTranslator.forAggregation(
      (JavaTypeFactory) getCluster().getTypeFactory(),
      builder2,
      new PassedRowsInputGetter(row_, rows_, inputPhysType),
      implementor.getConformance());

  final ParameterExpression result_ =
      Expressions.parameter(physType.getJavaRowType());

  builder2.add(
      Expressions.declare(Modifier.FINAL, result_,
          Expressions.new_(physType.getJavaRowType())));
  Ord.forEach(measures.values(), (measure, i) ->
      builder2.add(
          Expressions.statement(
              Expressions.assign(physType.fieldReference(result_, i),
                  implementMeasure(translator, rows_, symbols_, i_, row_,
                      measure)))));
  builder2.add(
      Expressions.statement(
          Expressions.call(consumer_, BuiltInMethod.CONSUMER_ACCEPT.method,
              result_)));

  final BlockBuilder builder = new BlockBuilder();

  // Loop Length

  // we have to use an explicit for (int i = ...) loop, as we need to know later
  // which of the matched rows are already passed (in MatchUtils), so foreach cannot be used
  builder.add(
      Expressions.for_(
          Expressions.declare(0, i_, Expressions.constant(0)),
          Expressions.lessThan(i_,
              Expressions.call(rows_, BuiltInMethod.COLLECTION_SIZE.method)),
          Expressions.preIncrementAssign(i_),
          builder2.toBlock()));

  return Expressions.new_(
      Types.of(Enumerables.Emitter.class), NO_EXPRS,
      Expressions.list(
          EnumUtils.overridingMethodDecl(
              BuiltInMethod.EMITTER_EMIT.method,
              ImmutableList.of(rows_, rowStates_, symbols_, match_,
                  consumer_),
              builder.toBlock())));
}
 
Example #28
Source File: SemiJoinProjectTransposeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Pulls the project above the semijoin and returns the resulting semijoin
 * condition. As a result, the semijoin condition should be modified such
 * that references to the LHS of a semijoin should now reference the
 * children of the project that's on the LHS.
 *
 * @param project  LogicalProject on the LHS of the semijoin
 * @param semiJoin the semijoin
 * @return the modified semijoin condition
 */
private RexNode adjustCondition(LogicalProject project, LogicalJoin semiJoin) {
  // create two RexPrograms -- the bottom one representing a
  // concatenation of the project and the RHS of the semijoin and the
  // top one representing the semijoin condition

  RexBuilder rexBuilder = project.getCluster().getRexBuilder();
  RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
  RelNode rightChild = semiJoin.getRight();

  // for the bottom RexProgram, the input is a concatenation of the
  // child of the project and the RHS of the semijoin
  RelDataType bottomInputRowType =
      SqlValidatorUtil.deriveJoinRowType(
          project.getInput().getRowType(),
          rightChild.getRowType(),
          JoinRelType.INNER,
          typeFactory,
          null,
          semiJoin.getSystemFieldList());
  RexProgramBuilder bottomProgramBuilder =
      new RexProgramBuilder(bottomInputRowType, rexBuilder);

  // add the project expressions, then add input references for the RHS
  // of the semijoin
  for (Pair<RexNode, String> pair : project.getNamedProjects()) {
    bottomProgramBuilder.addProject(pair.left, pair.right);
  }
  int nLeftFields = project.getInput().getRowType().getFieldCount();
  List<RelDataTypeField> rightFields =
      rightChild.getRowType().getFieldList();
  int nRightFields = rightFields.size();
  for (int i = 0; i < nRightFields; i++) {
    final RelDataTypeField field = rightFields.get(i);
    RexNode inputRef =
        rexBuilder.makeInputRef(
            field.getType(), i + nLeftFields);
    bottomProgramBuilder.addProject(inputRef, field.getName());
  }
  RexProgram bottomProgram = bottomProgramBuilder.getProgram();

  // input rowtype into the top program is the concatenation of the
  // project and the RHS of the semijoin
  RelDataType topInputRowType =
      SqlValidatorUtil.deriveJoinRowType(
          project.getRowType(),
          rightChild.getRowType(),
          JoinRelType.INNER,
          typeFactory,
          null,
          semiJoin.getSystemFieldList());
  RexProgramBuilder topProgramBuilder =
      new RexProgramBuilder(
          topInputRowType,
          rexBuilder);
  topProgramBuilder.addIdentity();
  topProgramBuilder.addCondition(semiJoin.getCondition());
  RexProgram topProgram = topProgramBuilder.getProgram();

  // merge the programs and expand out the local references to form
  // the new semijoin condition; it now references a concatenation of
  // the project's child and the RHS of the semijoin
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);

  return mergedProgram.expandLocalRef(
      mergedProgram.getCondition());
}
 
Example #29
Source File: SemiJoinProjectTransposeRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Pulls the project above the semijoin and returns the resulting semijoin
 * condition. As a result, the semijoin condition should be modified such
 * that references to the LHS of a semijoin should now reference the
 * children of the project that's on the LHS.
 *
 * @param project  LogicalProject on the LHS of the semijoin
 * @param semiJoin the semijoin
 * @return the modified semijoin condition
 */
private RexNode adjustCondition(LogicalProject project, SemiJoin semiJoin) {
  // create two RexPrograms -- the bottom one representing a
  // concatenation of the project and the RHS of the semijoin and the
  // top one representing the semijoin condition

  RexBuilder rexBuilder = project.getCluster().getRexBuilder();
  RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
  RelNode rightChild = semiJoin.getRight();

  // for the bottom RexProgram, the input is a concatenation of the
  // child of the project and the RHS of the semijoin
  RelDataType bottomInputRowType =
      SqlValidatorUtil.deriveJoinRowType(
          project.getInput().getRowType(),
          rightChild.getRowType(),
          JoinRelType.INNER,
          typeFactory,
          null,
          semiJoin.getSystemFieldList());
  RexProgramBuilder bottomProgramBuilder =
      new RexProgramBuilder(bottomInputRowType, rexBuilder);

  // add the project expressions, then add input references for the RHS
  // of the semijoin
  for (Pair<RexNode, String> pair : project.getNamedProjects()) {
    bottomProgramBuilder.addProject(pair.left, pair.right);
  }
  int nLeftFields = project.getInput().getRowType().getFieldCount();
  List<RelDataTypeField> rightFields =
      rightChild.getRowType().getFieldList();
  int nRightFields = rightFields.size();
  for (int i = 0; i < nRightFields; i++) {
    final RelDataTypeField field = rightFields.get(i);
    RexNode inputRef =
        rexBuilder.makeInputRef(
            field.getType(), i + nLeftFields);
    bottomProgramBuilder.addProject(inputRef, field.getName());
  }
  RexProgram bottomProgram = bottomProgramBuilder.getProgram();

  // input rowtype into the top program is the concatenation of the
  // project and the RHS of the semijoin
  RelDataType topInputRowType =
      SqlValidatorUtil.deriveJoinRowType(
          project.getRowType(),
          rightChild.getRowType(),
          JoinRelType.INNER,
          typeFactory,
          null,
          semiJoin.getSystemFieldList());
  RexProgramBuilder topProgramBuilder =
      new RexProgramBuilder(
          topInputRowType,
          rexBuilder);
  topProgramBuilder.addIdentity();
  topProgramBuilder.addCondition(semiJoin.getCondition());
  RexProgram topProgram = topProgramBuilder.getProgram();

  // merge the programs and expand out the local references to form
  // the new semijoin condition; it now references a concatenation of
  // the project's child and the RHS of the semijoin
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);

  return mergedProgram.expandLocalRef(
      mergedProgram.getCondition());
}
 
Example #30
Source File: ProjectCalcMergeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final LogicalProject project = call.rel(0);
  final LogicalCalc calc = call.rel(1);

  // Don't merge a project which contains windowed aggregates onto a
  // calc. That would effectively be pushing a windowed aggregate down
  // through a filter. Transform the project into an identical calc,
  // which we'll have chance to merge later, after the over is
  // expanded.
  final RelOptCluster cluster = project.getCluster();
  RexProgram program =
      RexProgram.create(
          calc.getRowType(),
          project.getProjects(),
          null,
          project.getRowType(),
          cluster.getRexBuilder());
  if (RexOver.containsOver(program)) {
    LogicalCalc projectAsCalc = LogicalCalc.create(calc, program);
    call.transformTo(projectAsCalc);
    return;
  }

  // Create a program containing the project node's expressions.
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  final RexProgramBuilder progBuilder =
      new RexProgramBuilder(
          calc.getRowType(),
          rexBuilder);
  for (Pair<RexNode, String> field : project.getNamedProjects()) {
    progBuilder.addProject(field.left, field.right);
  }
  RexProgram topProgram = progBuilder.getProgram();
  RexProgram bottomProgram = calc.getProgram();

  // Merge the programs together.
  RexProgram mergedProgram =
      RexProgramBuilder.mergePrograms(
          topProgram,
          bottomProgram,
          rexBuilder);
  final LogicalCalc newCalc =
      LogicalCalc.create(calc.getInput(), mergedProgram);
  call.transformTo(newCalc);
}