org.apache.calcite.plan.RelOptRuleCall Java Examples

The following examples show how to use org.apache.calcite.plan.RelOptRuleCall. 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: 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 #2
Source File: TestPushLimitToPruneableScan.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Test
public void testRule() throws Exception {
  final TestScanPrel scan = new TestScanPrel(cluster, TRAITS, table, pluginId, metadata, PROJECTED_COLUMNS, 0, false);
  final LimitPrel limitNode = new LimitPrel(cluster, TRAITS, scan,
      REX_BUILDER.makeExactLiteral(BigDecimal.valueOf(offset)),
      REX_BUILDER.makeExactLiteral(BigDecimal.valueOf(fetch)));

  boolean[] transformed = { false };
  final RelOptRuleCall call = newCall(rel -> {
    transformed[0] = true;
    checker.check(limitNode, scan, rel);
  }, limitNode, scan);

  assertTrue(PushLimitToPruneableScan.INSTANCE.matches(call));
  PushLimitToPruneableScan.INSTANCE.onMatch(call);
  assertThat(checker.shouldTransform(), is(transformed[0]));
}
 
Example #3
Source File: ConnectionStatusPredictionsProjectTableScanRule.java    From nifi with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final ConnectionStatusPredictionsTableScan scan = call.rel(1);
    final int[] fields = getProjectFields(project.getProjects());

    if (fields == null) {
        // Project contains expressions more complex than just field references.
        return;
    }

    call.transformTo(
        new ConnectionStatusPredictionsTableScan(
            scan.getCluster(),
            scan.getTable(),
            scan.connectionStatusPredictionsTable,
            fields));
}
 
Example #4
Source File: DrillPushLimitToScanRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
  DrillLimitRel limitRel = call.rel(0);
  DrillProjectRel projectRel = call.rel(1);
  // pushdown only apply limit but not offset,
  // so if getFetch() return null no need to run this rule.
  // Do not push across Project containing CONVERT_FROMJSON for limit 0 queries. For limit 0 queries, this would
  // mess up the schema since Convert_FromJson() is different from other regular functions in that it only knows
  // the output schema after evaluation is performed. When input has 0 row, Drill essentially does not have a way
  // to know the output type.
  // Cannot pushdown limit and offset in to flatten as long as we don't know data distribution in flattened field
  if (!limitRel.isPushDown() && (limitRel.getFetch() != null)
      && (!DrillRelOptUtil.isLimit0(limitRel.getFetch())
        || !DrillRelOptUtil.isProjectOutputSchemaUnknown(projectRel))
      && !DrillRelOptUtil.isProjectOutputRowcountUnknown(projectRel)) {
    return true;
  }
  return false;
}
 
Example #5
Source File: ProcessorStatusProjectTableScanRule.java    From nifi with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final ProcessorStatusTableScan scan = call.rel(1);
    final int[] fields = getProjectFields(project.getProjects());

    if (fields == null) {
        // Project contains expressions more complex than just field references.
        return;
    }

    call.transformTo(
        new ProcessorStatusTableScan(
            scan.getCluster(),
            scan.getTable(),
            scan.processorStatusTable,
            fields));
}
 
Example #6
Source File: AggregateRemoveRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Aggregate aggregate = call.rel(0);
  final RelNode input = call.rel(1);
  if (!aggregate.getAggCallList().isEmpty() || aggregate.indicator) {
    return;
  }
  final RelMetadataQuery mq = call.getMetadataQuery();
  if (!SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet()))) {
    return;
  }
  // Distinct is "GROUP BY c1, c2" (where c1, c2 are a set of columns on
  // which the input is unique, i.e. contain a key) and has no aggregate
  // functions. It can be removed.
  final RelNode newInput = convert(input, aggregate.getTraitSet().simplify());

  // If aggregate was projecting a subset of columns, add a project for the
  // same effect.
  final RelBuilder relBuilder = call.builder();
  relBuilder.push(newInput);
  if (newInput.getRowType().getFieldCount()
      > aggregate.getRowType().getFieldCount()) {
    relBuilder.project(relBuilder.fields(aggregate.getGroupSet().asList()));
  }
  call.transformTo(relBuilder.build());
}
 
Example #7
Source File: ElasticScanPrule.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  ElasticsearchScanDrel logicalScan = call.rel(0);
  ElasticIntermediateScanPrel physicalScan = new ElasticIntermediateScanPrel(
      logicalScan.getCluster(),
      logicalScan.getTraitSet().replace(Prel.PHYSICAL),
      logicalScan.getTable(),
      logicalScan.getTableMetadata(),
      logicalScan.getProjectedColumns(),
      logicalScan.getObservedRowcountAdjustment()
      );

  RelNode converted = new ElasticsearchIntermediatePrel(
      physicalScan.getTraitSet(),
      physicalScan,
      lookupContext);

  call.transformTo(converted);
}
 
Example #8
Source File: PushProjectIntoTableSourceScanRule.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	LogicalTableScan scan = call.rel(1);
	TableSourceTable tableSourceTable = scan.getTable().unwrap(TableSourceTable.class);
	if (tableSourceTable == null || !(tableSourceTable.tableSource() instanceof SupportsProjectionPushDown)) {
		return false;
	}
	SupportsProjectionPushDown pushDownSource = (SupportsProjectionPushDown) tableSourceTable.tableSource();
	if (pushDownSource.supportsNestedProjection()) {
		throw new TableException("Nested projection push down is unsupported now. \n" +
				"Please disable nested projection (SupportsProjectionPushDown#supportsNestedProjection returns false), " +
				"planner will push down the top-level columns.");
	} else {
		return true;
	}
}
 
Example #9
Source File: MaterializedViewFilterScanRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
protected void apply(RelOptRuleCall call, Filter filter, TableScan scan) {
  final RelOptPlanner planner = call.getPlanner();
  final List<RelOptMaterialization> materializations =
      planner.getMaterializations();
  if (!materializations.isEmpty()) {
    RelNode root = filter.copy(filter.getTraitSet(),
        Collections.singletonList((RelNode) scan));
    List<RelOptMaterialization> applicableMaterializations =
        RelOptMaterializations.getApplicableMaterializations(root, materializations);
    for (RelOptMaterialization materialization : applicableMaterializations) {
      if (RelOptUtil.areRowTypesEqual(scan.getRowType(),
          materialization.queryRel.getRowType(), false)) {
        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 #10
Source File: SubQueryRemoveRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Filter filter = call.rel(0);
  final RelBuilder builder = call.builder();
  builder.push(filter.getInput());
  int count = 0;
  RexNode c = filter.getCondition();
  while (true) {
    final RexSubQuery e = RexUtil.SubQueryFinder.find(c);
    if (e == null) {
      assert count > 0;
      break;
    }
    ++count;
    final RelOptUtil.Logic logic =
        LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(c), e);
    final Set<CorrelationId>  variablesSet =
        RelOptUtil.getVariablesUsed(e.rel);
    final RexNode target = apply(e, variablesSet, logic,
        builder, 1, builder.peek().getRowType().getFieldCount());
    final RexShuttle shuttle = new ReplaceSubQueryShuttle(e, target);
    c = c.accept(shuttle);
  }
  builder.filter(c);
  builder.project(fields(builder, filter.getRowType().getFieldCount()));
  call.transformTo(builder.build());
}
 
Example #11
Source File: FlowFileProjectTableScanRule.java    From nifi with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final FlowFileTableScan scan = call.rel(1);
    final int[] fields = getProjectFields(project.getProjects());

    if (fields == null) {
        // Project contains expressions more complex than just field references.
        return;
    }

    call.transformTo(
        new FlowFileTableScan(
            scan.getCluster(),
            scan.getTable(),
            scan.flowFileTable,
            fields));
}
 
Example #12
Source File: SubQueryRemoveRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final RelBuilder builder = call.builder();
    builder.push(filter.getInput());
    int count = 0;
    RexNode c = filter.getCondition();
    while (true) {
        final RexSubQuery e = RexUtil.SubQueryFinder.find(c);
        if (e == null) {
            assert count > 0;
            break;
        }
        ++count;
        final RelOptUtil.Logic logic = LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(c), e);
        final Set<CorrelationId> variablesSet = RelOptUtil.getVariablesUsed(e.getRel());
        final RexNode target = apply(e, variablesSet, logic, builder, 1,
                builder.peek().getRowType().getFieldCount());
        final RexShuttle shuttle = new ReplaceSubQueryShuttle(e, target);
        c = c.accept(shuttle);
    }
    builder.filter(c);
    builder.project(fields(builder, filter.getRowType().getFieldCount()));
    call.transformTo(builder.build());
}
 
Example #13
Source File: ReduceExpressionsRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final Project project = call.rel(0);
  final RelMetadataQuery mq = call.getMetadataQuery();
  final RelOptPredicateList predicates =
      mq.getPulledUpPredicates(project.getInput());
  final List<RexNode> expList =
      Lists.newArrayList(project.getProjects());
  if (reduceExpressions(project, expList, predicates, false,
      matchNullability)) {
    call.transformTo(
        call.builder()
            .push(project.getInput())
            .project(expList, project.getRowType().getFieldNames())
            .build());

    // New plan is absolutely better than old plan.
    call.getPlanner().setImportance(project, 0.0);
  }
}
 
Example #14
Source File: OLAPLimitRule.java    From kylin-on-parquet-v2 with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    if (sort.offset == null && sort.fetch == null) {
        return;
    }

    RelTraitSet origTraitSet = sort.getTraitSet();
    RelTraitSet traitSet = origTraitSet.replace(OLAPRel.CONVENTION).simplify();

    RelNode input = sort.getInput();
    if (!sort.getCollation().getFieldCollations().isEmpty()) {
        // Create a sort with the same sort key, but no offset or fetch.
        input = sort.copy(sort.getTraitSet(), input, sort.getCollation(), null, null);
    }
    RelNode x = convert(input, input.getTraitSet().replace(OLAPRel.CONVENTION));
    call.transformTo(new OLAPLimitRel(sort.getCluster(), traitSet, x, sort.offset, sort.fetch));
}
 
Example #15
Source File: DbScanToIndexScanPrule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public IndexLogicalPlanCallContext onMatch(RelOptRuleCall call) {
  final DrillSortRel sort = call.rel(0);
  final DrillProjectRel capProject = call.rel(1);
  final DrillFilterRel filter = call.rel(2);
  final DrillProjectRel project = call.rel(3);
  final DrillScanRel scan = call.rel(4);
  return new IndexLogicalPlanCallContext(call, sort, capProject, filter, project, scan);
}
 
Example #16
Source File: ProjectSetOpTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  LogicalProject origProj = call.rel(0);
  SetOp setOp = call.rel(1);

  // cannot push project past a distinct
  if (!setOp.all) {
    return;
  }

  // locate all fields referenced in the projection
  PushProjector pushProject =
      new PushProjector(
          origProj, null, setOp, preserveExprCondition, call.builder());
  pushProject.locateAllRefs();

  List<RelNode> newSetOpInputs = new ArrayList<>();
  int[] adjustments = pushProject.getAdjustments();

  // push the projects completely below the setop; this
  // is different from pushing below a join, where we decompose
  // to try to keep expensive expressions above the join,
  // because UNION ALL does not have any filtering effect,
  // and it is the only operator this rule currently acts on
  for (RelNode input : setOp.getInputs()) {
    // be lazy:  produce two ProjectRels, and let another rule
    // merge them (could probably just clone origProj instead?)
    Project p = pushProject.createProjectRefsAndExprs(input, true, false);
    newSetOpInputs.add(pushProject.createNewProject(p, adjustments));
  }

  // create a new setop whose children are the ProjectRels created above
  SetOp newSetOp =
      setOp.copy(setOp.getTraitSet(), newSetOpInputs);

  call.transformTo(newSetOp);
}
 
Example #17
Source File: AggregateProjectMergeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Aggregate aggregate = call.rel(0);
  final Project project = call.rel(1);
  RelNode x = apply(call, aggregate, project);
  if (x != null) {
    call.transformTo(x);
  }
}
 
Example #18
Source File: FilterAggStarRule.java    From quark with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  final LogicalFilter filter = call.rel(0);
  Aggregate aggregate2 = call.rel(1);
  final Project project = call.rel(2);
  final StarTable.StarTableScan scan = call.rel(3);
  apply(call, null, filter, aggregate2, project, scan);
}
 
Example #19
Source File: FilterMergeRule.java    From calcite 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);

  final RelBuilder relBuilder = call.builder();
  relBuilder.push(bottomFilter.getInput())
      .filter(bottomFilter.getCondition(), topFilter.getCondition());

  call.transformTo(relBuilder.build());
}
 
Example #20
Source File: DbScanSortRemovalRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public IndexPhysicalPlanCallContext onMatch(RelOptRuleCall call) {
  final ScanPrel scan = call.rel(3);
  final OrderedRel sort = call.rel(0);
  final ProjectPrel proj = call.rel(2);
  final ExchangePrel exch = call.rel(1);
  return new IndexPhysicalPlanCallContext(call,  sort, proj, scan, exch);
}
 
Example #21
Source File: ConverterRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  RelNode rel = call.rel(0);
  if (rel.getTraitSet().contains(inTrait)) {
    final RelNode converted = convert(rel);
    if (converted != null) {
      call.transformTo(converted);
    }
  }
}
 
Example #22
Source File: JoinAddRedundantSemiJoinRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  Join origJoinRel = call.rel(0);
  if (origJoinRel.isSemiJoinDone()) {
    return;
  }

  // can't process outer joins using semijoins
  if (origJoinRel.getJoinType() != JoinRelType.INNER) {
    return;
  }

  // determine if we have a valid join condition
  final JoinInfo joinInfo = origJoinRel.analyzeCondition();
  if (joinInfo.leftKeys.size() == 0) {
    return;
  }

  RelNode semiJoin =
      LogicalJoin.create(origJoinRel.getLeft(),
          origJoinRel.getRight(),
          ImmutableList.of(),
          origJoinRel.getCondition(),
          ImmutableSet.of(),
          JoinRelType.SEMI);

  RelNode newJoinRel =
      origJoinRel.copy(
          origJoinRel.getTraitSet(),
          origJoinRel.getCondition(),
          semiJoin,
          origJoinRel.getRight(),
          JoinRelType.INNER,
          true);

  call.transformTo(newJoinRel);
}
 
Example #23
Source File: InfoSchemaPushFilterIntoScan.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
  final FilterPrel filterRel = call.rel(0);
  final ProjectPrel projectRel = call.rel(1);
  final InfoSchemaScanPrel scanRel = call.rel(2);
  doMatch(call, scanRel, projectRel, filterRel);
}
 
Example #24
Source File: MultiJoinProjectTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override protected Project getRightChild(RelOptRuleCall call) {
  if (call.rels.length == 4) {
    return call.rel(2);
  } else {
    return call.rel(3);
  }
}
 
Example #25
Source File: ElasticsearchLimitRule.java    From dk-fitting with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall relOptRuleCall) {
    EnumerableLimit limit = relOptRuleCall.rel(0);
    RelNode convert = convert(limit);
    if(convert != null){
        relOptRuleCall.transformTo(convert);
    }
}
 
Example #26
Source File: FlinkAggregateJoinTransposeRule.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	// avoid push aggregates through dim join
	Join join = call.rel(1);
	RelNode right = join.getRight();
	// right tree should not contain temporal table
	return !containsSnapshot(right);
}
 
Example #27
Source File: ProjectMultiJoinMergeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  Project project = call.rel(0);
  MultiJoin multiJoin = call.rel(1);

  // if all inputs have their projFields set, then projection information
  // has already been pushed into each input
  boolean allSet = true;
  for (int i = 0; i < multiJoin.getInputs().size(); i++) {
    if (multiJoin.getProjFields().get(i) == null) {
      allSet = false;
      break;
    }
  }
  if (allSet) {
    return;
  }

  // create a new MultiJoin that reflects the columns in the projection
  // above the MultiJoin
  final RelBuilder relBuilder = call.builder();
  MultiJoin newMultiJoin =
      RelOptUtil.projectMultiJoin(multiJoin, project);
  relBuilder.push(newMultiJoin)
      .project(project.getProjects(), project.getRowType().getFieldNames());

  call.transformTo(relBuilder.build());
}
 
Example #28
Source File: CassandraRules.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** @see org.apache.calcite.rel.convert.ConverterRule */
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  CassandraFilter filter = call.rel(2);
  final RelNode converted = convert(sort, filter);
  if (converted != null) {
    call.transformTo(converted);
  }
}
 
Example #29
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 #30
Source File: ValuesPrule.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public void onMatch(final RelOptRuleCall call) {
  final ValuesRel rel = (ValuesRel) call.rel(0);
  try{
    call.transformTo(new ValuesPrel(rel.getCluster(), rel.getTraitSet().plus(Prel.PHYSICAL), rel.getRowType(), rel.getTuplesAsJsonOptions(), rel.getRows()));
  }catch(IOException e){
    logger.warn("Failure while converting JSONOptions.", e);
  }
}