Java Code Examples for org.apache.calcite.plan.hep.HepPlanner#setRoot()

The following examples show how to use org.apache.calcite.plan.hep.HepPlanner#setRoot() . 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: HepPlannerTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Tests that if two relational expressions are equivalent, the planner
 * notices, and only applies the rule once. */
@Test void testCommonSubExpression() {
  // In the following,
  //   (select 1 from dept where abs(-1)=20)
  // occurs twice, but it's a common sub-expression, so the rule should only
  // apply once.
  HepProgramBuilder programBuilder = HepProgram.builder();
  programBuilder.addRuleInstance(FilterToCalcRule.INSTANCE);

  final HepTestListener listener = new HepTestListener(0);
  HepPlanner planner = new HepPlanner(programBuilder.build());
  planner.addListener(listener);

  final String sql = "(select 1 from dept where abs(-1)=20)\n"
      + "union all\n"
      + "(select 1 from dept where abs(-1)=20)";
  planner.setRoot(tester.convertSqlToRel(sql).rel);
  RelNode bestRel = planner.findBestExp();

  assertThat(bestRel.getInput(0).equals(bestRel.getInput(1)), is(true));
  assertThat(listener.getApplyTimes() == 1, is(true));
}
 
Example 2
Source File: SqlHintsConverterTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testHintsPropagationInHepPlannerRules() {
  final String sql = "select /*+ use_hash_join(r, s), use_hash_join(emp, dept) */\n"
      + "ename, job, sal, dept.name\n"
      + "from emp join dept on emp.deptno = dept.deptno";
  final RelNode rel = tester.convertSqlToRel(sql).rel;
  final RelHint hint = RelHint.builder("USE_HASH_JOIN")
      .inheritPath(0)
      .hintOption("EMP")
      .hintOption("DEPT")
      .build();
  // Validate Hep planner.
  HepProgram program = new HepProgramBuilder()
      .addRuleInstance(MockJoinRule.INSTANCE)
      .build();
  HepPlanner planner = new HepPlanner(program);
  planner.setRoot(rel);
  RelNode newRel = planner.findBestExp();
  new ValidateHintVisitor(hint, Join.class).go(newRel);
}
 
Example 3
Source File: Programs.java    From Bats with Apache License 2.0 6 votes vote down vote up
/** Creates a program that executes a {@link HepProgram}. */
public static Program of(final HepProgram hepProgram, final boolean noDag,
    final RelMetadataProvider metadataProvider) {
  return (planner, rel, requiredOutputTraits, materializations, lattices) -> {
    final HepPlanner hepPlanner = new HepPlanner(hepProgram,
        null, noDag, null, RelOptCostImpl.FACTORY);

    List<RelMetadataProvider> list = new ArrayList<>();
    if (metadataProvider != null) {
      list.add(metadataProvider);
    }
    hepPlanner.registerMetadataProviders(list);
    RelMetadataProvider plannerChain =
        ChainedRelMetadataProvider.of(list);
    rel.getCluster().setMetadataProvider(plannerChain);

    hepPlanner.setRoot(rel);
    return hepPlanner.findBestExp();
  };
}
 
Example 4
Source File: HepPlannerTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testGC() throws Exception {
  HepProgramBuilder programBuilder = HepProgram.builder();
  programBuilder.addMatchOrder(HepMatchOrder.TOP_DOWN);
  programBuilder.addRuleInstance(CalcMergeRule.INSTANCE);
  programBuilder.addRuleInstance(ProjectToCalcRule.INSTANCE);
  programBuilder.addRuleInstance(FilterToCalcRule.INSTANCE);

  HepPlanner planner = new HepPlanner(programBuilder.build());
  planner.setRoot(
      tester.convertSqlToRel("select upper(name) from dept where deptno=20").rel);
  planner.findBestExp();
  // Reuse of HepPlanner (should trigger GC).
  planner.setRoot(
      tester.convertSqlToRel("select upper(name) from dept where deptno=20").rel);
  planner.findBestExp();
}
 
Example 5
Source File: RelDecorrelator.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RelNode removeCorrelationViaRule(RelNode root) {
  final RelBuilderFactory f = relBuilderFactory();
  HepProgram program = HepProgram.builder()
      .addRuleInstance(new RemoveSingleAggregateRule(f))
      .addRuleInstance(new RemoveCorrelationForScalarProjectRule(f))
      .addRuleInstance(new RemoveCorrelationForScalarAggregateRule(f))
      .build();

  HepPlanner planner = createPlanner(program);

  planner.setRoot(root);
  return planner.findBestExp();
}
 
Example 6
Source File: MaterializedViewFilterScanRule.java    From quark with Apache License 2.0 5 votes vote down vote up
protected void apply(RelOptRuleCall call, Filter filter, TableScan scan) {
  //Avoid optimizing already optimized scan
  if (scan instanceof QuarkViewScan || scan instanceof QuarkTileScan) {
    return;
  }
  RelNode root = filter.copy(filter.getTraitSet(),
      Collections.singletonList((RelNode) scan));
  RelOptPlanner planner = call.getPlanner();
  if (planner instanceof VolcanoPlanner) {
    List<RelOptMaterialization> materializations
        = ((VolcanoPlanner) planner).getMaterializations();
    for (RelOptMaterialization materialization : materializations) {
      if (scan.getRowType().equals(materialization.queryRel.getRowType())) {
        RelNode target = materialization.queryRel;
        final HepPlanner hepPlanner =
            new HepPlanner(program, planner.getContext());
        hepPlanner.setRoot(target);
        target = hepPlanner.findBestExp();
        List<RelNode> subs = new MaterializedViewSubstitutionVisitor(target, root)
            .go(materialization.tableRel);
        for (RelNode s : subs) {
          call.transformTo(s);
        }
      }
    }
  }
}
 
Example 7
Source File: MaterializationExpander.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private static RelNode applyRule(RelNode node, RelOptRule rule) {
  final HepProgramBuilder builder = HepProgram.builder();
  builder.addMatchOrder(HepMatchOrder.ARBITRARY);
  builder.addRuleCollection(ImmutableList.of(rule));
  final HepProgram program = builder.build();

  final HepPlanner planner = new HepPlanner(program);
  planner.setRoot(node);
  return planner.findBestExp();
}
 
Example 8
Source File: SqlHintsConverterTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testHintsForCalc() {
  final String sql = "select /*+ resource(mem='1024MB')*/ ename, sal, deptno from emp";
  final RelNode rel = tester.convertSqlToRel(sql).rel;
  final RelHint hint = RelHint.builder("RESOURCE")
      .hintOption("MEM", "1024MB")
      .build();
  // planner rule to convert Project to Calc.
  HepProgram program = new HepProgramBuilder()
      .addRuleInstance(ProjectToCalcRule.INSTANCE)
      .build();
  HepPlanner planner = new HepPlanner(program);
  planner.setRoot(rel);
  RelNode newRel = planner.findBestExp();
  new ValidateHintVisitor(hint, Calc.class).go(newRel);
}
 
Example 9
Source File: MycatCalcitePlanner.java    From Mycat2 with GNU General Public License v3.0 5 votes vote down vote up
public RelNode pullUpUnion(RelNode relNode1) {
    HepProgramBuilder hepProgramBuilder = new HepProgramBuilder();
    hepProgramBuilder.addMatchLimit(PULL_RULES.size());
    hepProgramBuilder.addRuleCollection(PULL_RULES);
    final HepPlanner planner2 = new HepPlanner(hepProgramBuilder.build());
    planner2.setRoot(relNode1);
    return planner2.findBestExp();
}
 
Example 10
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
public RelNode removeCorrelationViaRule(RelNode root) {
  final RelBuilderFactory f = relBuilderFactory();
  HepProgram program = HepProgram.builder()
      .addRuleInstance(new RemoveSingleAggregateRule(f))
      .addRuleInstance(new RemoveCorrelationForScalarProjectRule(f))
      .addRuleInstance(new RemoveCorrelationForScalarAggregateRule(f))
      .build();

  HepPlanner planner = createPlanner(program);

  planner.setRoot(root);
  return planner.findBestExp();
}
 
Example 11
Source File: Interpreter.java    From calcite with Apache License 2.0 5 votes vote down vote up
private RelNode optimize(RelNode rootRel) {
  final HepProgram hepProgram = new HepProgramBuilder()
      .addRuleInstance(CalcSplitRule.INSTANCE)
      .addRuleInstance(FilterTableScanRule.INSTANCE)
      .addRuleInstance(FilterTableScanRule.INTERPRETER)
      .addRuleInstance(ProjectTableScanRule.INSTANCE)
      .addRuleInstance(ProjectTableScanRule.INTERPRETER)
      .addRuleInstance(AggregateReduceFunctionsRule.INSTANCE)
      .build();
  final HepPlanner planner = new HepPlanner(hepProgram);
  planner.setRoot(rootRel);
  rootRel = planner.findBestExp();
  return rootRel;
}
 
Example 12
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 5 votes vote down vote up
public RelNode removeCorrelationViaRule(RelNode root) {
    final RelBuilderFactory f = relBuilderFactory();
    HepProgram program = HepProgram.builder().addRuleInstance(new RemoveSingleAggregateRule(f))
            .addRuleInstance(new RemoveCorrelationForScalarProjectRule(f))
            .addRuleInstance(new RemoveCorrelationForScalarAggregateRule(f)).build();

    HepPlanner planner = createPlanner(program);

    planner.setRoot(root);
    return planner.findBestExp();
}
 
Example 13
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 5 votes vote down vote up
private RelNode decorrelate(RelNode root) {
    // first adjust count() expression if any
    final RelBuilderFactory f = relBuilderFactory();
    HepProgram program = HepProgram.builder().addRuleInstance(new AdjustProjectForCountAggregateRule(false, f))
            .addRuleInstance(new AdjustProjectForCountAggregateRule(true, f))
            .addRuleInstance(new FilterJoinRule.FilterIntoJoinRule(true, f, FilterJoinRule.TRUE_PREDICATE))
            .addRuleInstance(new FilterProjectTransposeRule(Filter.class, Project.class, true, true, f))
            .addRuleInstance(new FilterCorrelateRule(f)).build();

    HepPlanner planner = createPlanner(program);

    planner.setRoot(root);
    root = planner.findBestExp();

    // Perform decorrelation.
    map.clear();

    final Frame frame = getInvoke(root, null);
    if (frame != null) {
        // has been rewritten; apply rules post-decorrelation
        final HepProgram program2 = HepProgram.builder()
                .addRuleInstance(new FilterJoinRule.FilterIntoJoinRule(true, f, FilterJoinRule.TRUE_PREDICATE))
                .addRuleInstance(new FilterJoinRule.JoinConditionPushRule(f, FilterJoinRule.TRUE_PREDICATE))
                .build();

        final HepPlanner planner2 = createPlanner(program2);
        final RelNode newRoot = frame.r;
        planner2.setRoot(newRoot);
        return planner2.findBestExp();
    }

    return root;
}
 
Example 14
Source File: InterpreterTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Test void testInterpretSemiJoin() throws Exception {
  final String sql = "select x, y from (values (1, 'a'), (2, 'b'), (3, 'c')) as t(x, y)\n"
      + "where x in\n"
      + "(select x from (values (1, 'd'), (3, 'g')) as t2(x, y))";
  SqlNode validate = planner.validate(planner.parse(sql));
  RelNode convert = planner.rel(validate).rel;
  final HepProgram program = new HepProgramBuilder()
      .addRuleInstance(SemiJoinRule.PROJECT)
      .build();
  final HepPlanner hepPlanner = new HepPlanner(program);
  hepPlanner.setRoot(convert);
  final RelNode relNode = hepPlanner.findBestExp();
  final Interpreter interpreter = new Interpreter(dataContext, relNode);
  assertRows(interpreter, true, "[1, a]", "[3, c]");
}
 
Example 15
Source File: RelOptMaterializations.java    From calcite with Apache License 2.0 4 votes vote down vote up
private static List<RelNode> substitute(
    RelNode root, RelOptMaterialization materialization) {
  // First, if the materialization is in terms of a star table, rewrite
  // the query in terms of the star table.
  if (materialization.starTable != null) {
    RelNode newRoot = RelOptMaterialization.tryUseStar(root,
        materialization.starRelOptTable);
    if (newRoot != null) {
      root = newRoot;
    }
  }

  // Push filters to the bottom, and combine projects on top.
  RelNode target = materialization.queryRel;
  // try to trim unused field in relational expressions.
  root = trimUnusedfields(root);
  target = trimUnusedfields(target);
  HepProgram program =
      new HepProgramBuilder()
          .addRuleInstance(FilterProjectTransposeRule.INSTANCE)
          .addRuleInstance(FilterMergeRule.INSTANCE)
          .addRuleInstance(FilterJoinRule.FILTER_ON_JOIN)
          .addRuleInstance(FilterJoinRule.JOIN)
          .addRuleInstance(FilterAggregateTransposeRule.INSTANCE)
          .addRuleInstance(ProjectMergeRule.INSTANCE)
          .addRuleInstance(ProjectRemoveRule.INSTANCE)
          .addRuleInstance(ProjectJoinTransposeRule.INSTANCE)
          .addRuleInstance(ProjectSetOpTransposeRule.INSTANCE)
          .addRuleInstance(FilterToCalcRule.INSTANCE)
          .addRuleInstance(ProjectToCalcRule.INSTANCE)
          .addRuleInstance(FilterCalcMergeRule.INSTANCE)
          .addRuleInstance(ProjectCalcMergeRule.INSTANCE)
          .addRuleInstance(CalcMergeRule.INSTANCE)
          .build();

  // We must use the same HEP planner for the two optimizations below.
  // Thus different nodes with the same digest will share the same vertex in
  // the plan graph. This is important for the matching process.
  final HepPlanner hepPlanner = new HepPlanner(program);
  hepPlanner.setRoot(target);
  target = hepPlanner.findBestExp();

  hepPlanner.setRoot(root);
  root = hepPlanner.findBestExp();

  return new SubstitutionVisitor(target, root).go(materialization.tableRel);
}
 
Example 16
Source File: RelDecorrelator.java    From flink with Apache License 2.0 4 votes vote down vote up
private RelNode decorrelate(RelNode root) {
  // first adjust count() expression if any
  final RelBuilderFactory f = relBuilderFactory();
  HepProgram program = HepProgram.builder()
      .addRuleInstance(new AdjustProjectForCountAggregateRule(false, f))
      .addRuleInstance(new AdjustProjectForCountAggregateRule(true, f))
      .addRuleInstance(
          // use FilterJoinRule instead of FlinkFilterJoinRule while CALCITE-3170 is fixed
          new FlinkFilterJoinRule.FlinkFilterIntoJoinRule(true, f,
              FlinkFilterJoinRule.TRUE_PREDICATE))
      .addRuleInstance(
          new FilterProjectTransposeRule(Filter.class, Project.class, true,
              true, f))
      .addRuleInstance(new FilterCorrelateRule(f))
      .build();

  HepPlanner planner = createPlanner(program);

  planner.setRoot(root);
  root = planner.findBestExp();

  // Perform decorrelation.
  map.clear();

  final Frame frame = getInvoke(root, null);
  if (frame != null) {
    // has been rewritten; apply rules post-decorrelation
    final HepProgram program2 = HepProgram.builder()
        .addRuleInstance(
            // use FilterJoinRule instead of FlinkFilterJoinRule while CALCITE-3170 is fixed
            new FlinkFilterJoinRule.FlinkFilterIntoJoinRule(
                true, f,
                FlinkFilterJoinRule.TRUE_PREDICATE))
        .addRuleInstance(
            new FlinkFilterJoinRule.FlinkJoinConditionPushRule(
                f,
                FlinkFilterJoinRule.TRUE_PREDICATE))
        .build();

    final HepPlanner planner2 = createPlanner(program2);
    final RelNode newRoot = frame.r;
    planner2.setRoot(newRoot);
    return planner2.findBestExp();
  }

  return root;
}
 
Example 17
Source File: MaterializedViewJoinRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Override protected RelNode rewriteQuery(
    RelBuilder relBuilder,
    RexBuilder rexBuilder,
    RexSimplify simplify,
    RelMetadataQuery mq,
    RexNode compensationColumnsEquiPred,
    RexNode otherCompensationPred,
    Project topProject,
    RelNode node,
    BiMap<RelTableRef, RelTableRef> viewToQueryTableMapping,
    EquivalenceClasses viewEC, EquivalenceClasses queryEC) {
  // Our target node is the node below the root, which should have the maximum
  // number of available expressions in the tree in order to maximize our
  // number of rewritings.
  // We create a project on top. If the program is available, we execute
  // it to maximize rewriting opportunities. For instance, a program might
  // pull up all the expressions that are below the aggregate so we can
  // introduce compensation filters easily. This is important depending on
  // the planner strategy.
  RelNode newNode = node;
  RelNode target = node;
  if (unionRewritingPullProgram != null) {
    final HepPlanner tmpPlanner = new HepPlanner(unionRewritingPullProgram);
    tmpPlanner.setRoot(newNode);
    newNode = tmpPlanner.findBestExp();
    target = newNode.getInput(0);
  }

  // All columns required by compensating predicates must be contained
  // in the query.
  List<RexNode> queryExprs = extractReferences(rexBuilder, target);

  if (!compensationColumnsEquiPred.isAlwaysTrue()) {
    compensationColumnsEquiPred = rewriteExpression(rexBuilder, mq,
        target, target, queryExprs, viewToQueryTableMapping.inverse(), queryEC, false,
        compensationColumnsEquiPred);
    if (compensationColumnsEquiPred == null) {
      // Skip it
      return null;
    }
  }
  // For the rest, we use the query equivalence classes
  if (!otherCompensationPred.isAlwaysTrue()) {
    otherCompensationPred = rewriteExpression(rexBuilder, mq,
        target, target, queryExprs, viewToQueryTableMapping.inverse(), viewEC, true,
        otherCompensationPred);
    if (otherCompensationPred == null) {
      // Skip it
      return null;
    }
  }
  final RexNode queryCompensationPred = RexUtil.not(
      RexUtil.composeConjunction(rexBuilder,
          ImmutableList.of(compensationColumnsEquiPred,
              otherCompensationPred)));

  // Generate query rewriting.
  RelNode rewrittenPlan = relBuilder
      .push(target)
      .filter(simplify.simplifyUnknownAsFalse(queryCompensationPred))
      .build();
  if (unionRewritingPullProgram != null) {
    rewrittenPlan = newNode.copy(
        newNode.getTraitSet(), ImmutableList.of(rewrittenPlan));
  }
  if (topProject != null) {
    return topProject.copy(topProject.getTraitSet(), ImmutableList.of(rewrittenPlan));
  }
  return rewrittenPlan;
}
 
Example 18
Source File: CalciteRunners.java    From Mycat2 with GNU General Public License v3.0 4 votes vote down vote up
@SneakyThrows
    public static RowBaseIterator run(String sql, MycatCalciteDataContext calciteDataContext, RelNode relNode) {
        SqlRecorder recorder = SqlRecorderRuntime.INSTANCE.getCurrentRecorder();
        Map<String, List<SingeTargetSQLTable>> map = new HashMap<>();
        relNode.accept(new RelShuttleImpl() {
            @Override
            public RelNode visit(TableScan scan) {
                SingeTargetSQLTable unwrap = scan.getTable().unwrap(SingeTargetSQLTable.class);
                if (unwrap != null && !unwrap.existsEnumerable()) {
                    List<SingeTargetSQLTable> tables = map.computeIfAbsent(unwrap.getTargetName(), s -> new ArrayList<>(2));
                    tables.add(unwrap);
                }
                return super.visit(scan);
            }
        });

        HepProgramBuilder hepProgramBuilder = new HepProgramBuilder();
        hepProgramBuilder.addMatchLimit(64);

        hepProgramBuilder.addRuleInstance(StreamUnionRule.INSTANCE);
        final HepPlanner planner2 = new HepPlanner(hepProgramBuilder.build());
        planner2.setRoot(relNode);
        relNode = planner2.findBestExp();

        //check
        relNode.accept(new RelShuttleImpl() {
            @Override
            public RelNode visit(LogicalUnion union) {
                if (union.getInputs().size() > 2) {
                    throw new AssertionError("union input more 2");
                }
                return super.visit(union);
            }
        });
        long startGetConnectionTime = TimeProvider.INSTANCE.now();
        fork(sql, calciteDataContext, map);
        long cbo = TimeProvider.INSTANCE.now();
        recorder.addRecord(SqlRecorderType.GET_CONNECTION, sql, cbo - startGetConnectionTime);
        ArrayBindable bindable1 = Interpreters.bindable(relNode);
        long execution_start = TimeProvider.INSTANCE.now();
        recorder.addRecord(SqlRecorderType.CBO, sql, execution_start - cbo);
//        EnumerableInterpretable.toBindable()
        Enumerable<Object[]> bind = bindable1.bind(calciteDataContext);
        Enumerator<Object[]> enumerator = bind.enumerator();

        return new EnumeratorRowIterator(CalciteConvertors.getMycatRowMetaData(relNode.getRowType()), enumerator,
                () -> {
                    recorder.addRecord(SqlRecorderType.EXECUTION_TIME, sql, TimeProvider.INSTANCE.now()-execution_start);
                    recorder.addRecord(SqlRecorderType.AT_END, sql, TimeProvider.INSTANCE.now());
                });
    }
 
Example 19
Source File: AbstractMaterializedViewRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
@Override
protected RelNode rewriteQuery(RelBuilder relBuilder, RexBuilder rexBuilder, RexSimplify simplify,
        RelMetadataQuery mq, RexNode compensationColumnsEquiPred, RexNode otherCompensationPred,
        Project topProject, RelNode node, BiMap<RelTableRef, RelTableRef> viewToQueryTableMapping,
        EquivalenceClasses viewEC, EquivalenceClasses queryEC) {
    // Our target node is the node below the root, which should have the maximum
    // number of available expressions in the tree in order to maximize our
    // number of rewritings.
    // We create a project on top. If the program is available, we execute
    // it to maximize rewriting opportunities. For instance, a program might
    // pull up all the expressions that are below the aggregate so we can
    // introduce compensation filters easily. This is important depending on
    // the planner strategy.
    RelNode newNode = node;
    RelNode target = node;
    if (unionRewritingPullProgram != null) {
        final HepPlanner tmpPlanner = new HepPlanner(unionRewritingPullProgram);
        tmpPlanner.setRoot(newNode);
        newNode = tmpPlanner.findBestExp();
        target = newNode.getInput(0);
    }

    // All columns required by compensating predicates must be contained
    // in the query.
    List<RexNode> queryExprs = extractReferences(rexBuilder, target);

    if (!compensationColumnsEquiPred.isAlwaysTrue()) {
        compensationColumnsEquiPred = rewriteExpression(rexBuilder, mq, target, target, queryExprs,
                viewToQueryTableMapping.inverse(), queryEC, false, compensationColumnsEquiPred);
        if (compensationColumnsEquiPred == null) {
            // Skip it
            return null;
        }
    }
    // For the rest, we use the query equivalence classes
    if (!otherCompensationPred.isAlwaysTrue()) {
        otherCompensationPred = rewriteExpression(rexBuilder, mq, target, target, queryExprs,
                viewToQueryTableMapping.inverse(), viewEC, true, otherCompensationPred);
        if (otherCompensationPred == null) {
            // Skip it
            return null;
        }
    }
    final RexNode queryCompensationPred = RexUtil.not(RexUtil.composeConjunction(rexBuilder,
            ImmutableList.of(compensationColumnsEquiPred, otherCompensationPred)));

    // Generate query rewriting.
    RelNode rewrittenPlan = relBuilder.push(target)
            .filter(simplify.simplifyUnknownAsFalse(queryCompensationPred)).build();
    if (unionRewritingPullProgram != null) {
        rewrittenPlan = newNode.copy(newNode.getTraitSet(), ImmutableList.of(rewrittenPlan));
    }
    if (topProject != null) {
        return topProject.copy(topProject.getTraitSet(), ImmutableList.of(rewrittenPlan));
    }
    return rewrittenPlan;
}
 
Example 20
Source File: MutableRelTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Verifies that after conversion to and from a MutableRel, the new
 * RelNode remains identical to the original RelNode. */
private static void checkConvertMutableRel(
    String rel, String sql, boolean decorrelate, List<RelOptRule> rules) {
  final SqlToRelTestBase test = new SqlToRelTestBase() {
  };
  RelNode origRel = test.createTester().convertSqlToRel(sql).rel;
  if (decorrelate) {
    final RelBuilder relBuilder =
        RelFactories.LOGICAL_BUILDER.create(origRel.getCluster(), null);
    origRel = RelDecorrelator.decorrelateQuery(origRel, relBuilder);
  }
  if (rules != null) {
    final HepProgram hepProgram =
        new HepProgramBuilder().addRuleCollection(rules).build();
    final HepPlanner hepPlanner = new HepPlanner(hepProgram);
    hepPlanner.setRoot(origRel);
    origRel = hepPlanner.findBestExp();
  }
  // Convert to and from a mutable rel.
  final MutableRel mutableRel = MutableRels.toMutable(origRel);
  final RelNode newRel = MutableRels.fromMutable(mutableRel);

  // Check if the mutable rel digest contains the target rel.
  final String mutableRelStr = mutableRel.deep();
  final String msg1 =
      "Mutable rel: " + mutableRelStr + " does not contain target rel: " + rel;
  assertTrue(mutableRelStr.contains(rel), msg1);

  // Check if the mutable rel's row-type is identical to the original
  // rel's row-type.
  final RelDataType origRelType = origRel.getRowType();
  final RelDataType mutableRelType = mutableRel.rowType;
  final String msg2 =
      "Mutable rel's row type does not match with the original rel.\n"
      + "Original rel type: " + origRelType
      + ";\nMutable rel type: " + mutableRelType;
  assertTrue(
      equal(
          "origRelType", origRelType,
          "mutableRelType", mutableRelType,
          IGNORE),
      msg2);

  // Check if the new rel converted from the mutable rel is identical
  // to the original rel.
  final String origRelStr = RelOptUtil.toString(origRel);
  final String newRelStr = RelOptUtil.toString(newRel);
  final String msg3 =
      "The converted new rel is different from the original rel.\n"
      + "Original rel: " + origRelStr + ";\nNew rel: " + newRelStr;
  assertEquals(origRelStr, newRelStr, msg3);
}