Java源码示例:org.apache.calcite.rel.rules.ProjectRemoveRule

示例1
public void registerAbstractRelationalRules() {
  addRule(FilterJoinRule.FILTER_ON_JOIN);
  addRule(FilterJoinRule.JOIN);
  addRule(AbstractConverter.ExpandConversionRule.INSTANCE);
  addRule(JoinCommuteRule.INSTANCE);
  addRule(SemiJoinRule.PROJECT);
  addRule(SemiJoinRule.JOIN);
  if (CalciteSystemProperty.COMMUTE.value()) {
    addRule(JoinAssociateRule.INSTANCE);
  }
  addRule(AggregateRemoveRule.INSTANCE);
  addRule(UnionToDistinctRule.INSTANCE);
  addRule(ProjectRemoveRule.INSTANCE);
  addRule(AggregateJoinTransposeRule.INSTANCE);
  addRule(AggregateProjectMergeRule.INSTANCE);
  addRule(CalcRemoveRule.INSTANCE);
  addRule(SortRemoveRule.INSTANCE);

  // todo: rule which makes Project({OrdinalRef}) disappear
}
 
示例2
/**
 * Converts a relational expression to a form where
 * {@link org.apache.calcite.rel.logical.LogicalJoin}s are
 * as close to leaves as possible.
 */
public static RelNode toLeafJoinForm(RelNode rel) {
  final Program program = Programs.hep(
      ImmutableList.of(
          JoinProjectTransposeRule.RIGHT_PROJECT,
          JoinProjectTransposeRule.LEFT_PROJECT,
          FilterJoinRule.FilterIntoJoinRule.FILTER_ON_JOIN,
          ProjectRemoveRule.INSTANCE,
          ProjectMergeRule.INSTANCE),
      false,
      DefaultRelMetadataProvider.INSTANCE);
  if (CalciteSystemProperty.DEBUG.value()) {
    System.out.println(
        RelOptUtil.dumpPlan("before", rel, SqlExplainFormat.TEXT,
            SqlExplainLevel.DIGEST_ATTRIBUTES));
  }
  final RelNode rel2 = program.run(null, rel, null,
      ImmutableList.of(),
      ImmutableList.of());
  if (CalciteSystemProperty.DEBUG.value()) {
    System.out.println(
        RelOptUtil.dumpPlan("after", rel2, SqlExplainFormat.TEXT,
            SqlExplainLevel.DIGEST_ATTRIBUTES));
  }
  return rel2;
}
 
示例3
/**
 * Converts a relational expression to a form where
 * {@link org.apache.calcite.rel.logical.LogicalJoin}s are
 * as close to leaves as possible.
 */
public static RelNode toLeafJoinForm(RelNode rel) {
  final Program program = Programs.hep(
      ImmutableList.of(
          JoinProjectTransposeRule.RIGHT_PROJECT,
          JoinProjectTransposeRule.LEFT_PROJECT,
          FilterJoinRule.FilterIntoJoinRule.FILTER_ON_JOIN,
          ProjectRemoveRule.INSTANCE,
          ProjectMergeRule.INSTANCE),
      false,
      DefaultRelMetadataProvider.INSTANCE);
  if (CalciteSystemProperty.DEBUG.value()) {
    System.out.println(
        RelOptUtil.dumpPlan("before", rel, SqlExplainFormat.TEXT,
            SqlExplainLevel.DIGEST_ATTRIBUTES));
  }
  final RelNode rel2 = program.run(null, rel, null,
      ImmutableList.of(),
      ImmutableList.of());
  if (CalciteSystemProperty.DEBUG.value()) {
    System.out.println(
        RelOptUtil.dumpPlan("after", rel2, SqlExplainFormat.TEXT,
            SqlExplainLevel.DIGEST_ATTRIBUTES));
  }
  return rel2;
}
 
示例4
private RelNode canonicalize(RelNode rel) {
  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();
  final HepPlanner hepPlanner = new HepPlanner(program);
  hepPlanner.setRoot(rel);
  return hepPlanner.findBestExp();
}
 
示例5
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;
  HepProgram program =
      new HepProgramBuilder()
          .addRuleInstance(FilterProjectTransposeRule.INSTANCE)
          .addRuleInstance(ProjectMergeRule.INSTANCE)
          .addRuleInstance(ProjectRemoveRule.INSTANCE)
          .build();

  final HepPlanner hepPlanner = new HepPlanner(program);
  hepPlanner.setRoot(target);
  target = hepPlanner.findBestExp();

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

  return new MaterializedViewSubstitutionVisitor(target, root)
          .go(materialization.tableRel);
}
 
示例6
@Override
public void onMatch(RelOptRuleCall call) {
  Project project = call.rel(0);
  TableScan scan = call.rel(1);

  try {
    if (scan.getRowType().getFieldList().isEmpty()) {
      return;
    }

    ProjectPushInfo projectPushInfo = DrillRelOptUtil.getFieldsInformation(scan.getRowType(), project.getProjects());
    if (!canPushProjectIntoScan(scan.getTable(), projectPushInfo)
        || skipScanConversion(projectPushInfo.createNewRowType(project.getCluster().getTypeFactory()), scan)) {
      // project above scan may be removed in ProjectRemoveRule for the case when it is trivial
      return;
    }

    DrillScanRelBase newScan = createScan(scan, projectPushInfo);

    List<RexNode> newProjects = new ArrayList<>();
    for (RexNode n : project.getChildExps()) {
      newProjects.add(n.accept(projectPushInfo.getInputReWriter()));
    }

    DrillProjectRelBase newProject =
        createProject(project, newScan, newProjects);

    if (ProjectRemoveRule.isTrivial(newProject)) {
      call.transformTo(newScan);
    } else {
      call.transformTo(newProject);
    }
  } catch (IOException e) {
    throw new DrillRuntimeException(e);
  }
}
 
示例7
@Override
public void onMatch(RelOptRuleCall call) {
    DrillProjectRel projectRel = call.rel(0);
    DrillScanRel scanRel = call.rel(1);

    ItemStarFieldsVisitor itemStarFieldsVisitor = new ItemStarFieldsVisitor(
            scanRel.getRowType().getFieldNames());
    List<RexNode> projects = projectRel.getProjects();
    for (RexNode project : projects) {
        project.accept(itemStarFieldsVisitor);
    }

    // if there are no item fields, no need to proceed further
    if (itemStarFieldsVisitor.hasNoItemStarFields()) {
        return;
    }

    Map<String, DesiredField> itemStarFields = itemStarFieldsVisitor.getItemStarFields();

    DrillScanRel newScan = createNewScan(scanRel, itemStarFields);

    // re-write projects
    Map<RexNode, Integer> fieldMapper = createFieldMapper(itemStarFields.values(),
            scanRel.getRowType().getFieldCount());
    FieldsReWriter fieldsReWriter = new FieldsReWriter(fieldMapper);
    List<RexNode> newProjects = new ArrayList<>();
    for (RexNode node : projectRel.getChildExps()) {
        newProjects.add(node.accept(fieldsReWriter));
    }

    DrillProjectRel newProject = new DrillProjectRel(projectRel.getCluster(), projectRel.getTraitSet(), newScan,
            newProjects, projectRel.getRowType());

    if (ProjectRemoveRule.isTrivial(newProject)) {
        call.transformTo(newScan);
    } else {
        call.transformTo(newProject);
    }
}
 
示例8
@Override
public Prel visitProject(ProjectPrel prel, Void value) throws RuntimeException {
  // Require prefix rename : there exists other expression, in addition to a star column.
  if (!prefixedForStar  // not set yet.
      && StarColumnHelper.containsStarColumnInProject(prel.getInput().getRowType(), prel.getProjects())
      && prel.getRowType().getFieldNames().size() > 1) {
    prefixedForStar = true;
  }

  // For project, we need make sure that the project's field name is same as the input,
  // when the project expression is RexInPutRef, since we may insert a PAS which will
  // rename the projected fields.

  RelNode child = ((Prel) prel.getInput(0)).accept(this, null);

  List<String> fieldNames = Lists.newArrayList();

  for (Pair<String, RexNode> pair : Pair.zip(prel.getRowType().getFieldNames(), prel.getProjects())) {
    if (pair.right instanceof RexInputRef) {
      String name = child.getRowType().getFieldNames().get(((RexInputRef) pair.right).getIndex());
      fieldNames.add(name);
    } else {
      fieldNames.add(pair.left);
    }
  }

  // Make sure the field names are unique : no allow of duplicate field names in a rowType.
  fieldNames = makeUniqueNames(fieldNames);

  RelDataType rowType = RexUtil.createStructType(prel.getCluster().getTypeFactory(),
      prel.getProjects(), fieldNames, null);

  ProjectPrel newProj = (ProjectPrel) prel.copy(prel.getTraitSet(), child, prel.getProjects(), rowType);

  if (ProjectRemoveRule.isTrivial(newProj)) {
    return (Prel) child;
  } else {
    return newProj;
  }
}
 
示例9
public static boolean isTrivialProject(Project project, boolean useNamesInIdentityProjCalc) {
    if (!useNamesInIdentityProjCalc) {
        return ProjectRemoveRule.isTrivial(project);
    } else {
        return containIdentity(project.getProjects(), project.getRowType(), project.getInput().getRowType());
    }
}
 
示例10
@Override
public void onMatch(RelOptRuleCall call) {
  final ProjectForFlattenRel proj = call.rel(0);
  final ScanRelBase scan = call.rel(1);

  try {
    final ProjectPushInfo columnInfoItemsExprs = PrelUtil.getColumns(scan.getRowType(), proj.getItemExprs());
    if (columnInfoItemsExprs == null || columnInfoItemsExprs.isStarQuery()) {
      return;
    }

    final ScanRelBase newScan = scan.cloneWithProject(columnInfoItemsExprs.columns);

    // if the scan is the same as this one (no change in projections), no need to push down.
    if(newScan.getProjectedColumns().equals(scan.getProjectedColumns())){
      return;
    }

    List<RexNode> newProjects = Lists.newArrayList();
    for (RexNode n : proj.getProjExprs()) {
      newProjects.add(n.accept(columnInfoItemsExprs.getInputRewriter()));
    }

    final ProjectRel newProj =
            ProjectRel.create(proj.getCluster(),
                    proj.getTraitSet().plus(Rel.LOGICAL),
                    newScan,
                    newProjects,
                    proj.getRowType());

    if (ProjectRemoveRule.isTrivial(newProj)) {
      call.transformTo(newScan);
    } else {
      call.transformTo(newProj);
    }
  } catch (Exception e) {
    throw Throwables.propagate(e);
  }
}
 
示例11
@Override
public void onMatch(RelOptRuleCall call) {
  final Project proj = call.rel(0);
  final ScanCrel scan = call.rel(1);

  ProjectPushInfo columnInfo = PrelUtil.getColumns(scan.getRowType(), proj.getProjects());

  // get TableBase, either wrapped in RelOptTable, or TranslatableTable. TableBase table = scan.getTable().unwrap(TableBase.class);
  if (columnInfo == null || columnInfo.isStarQuery()) {
    return;
  }

  ScanCrel newScan = scan.cloneWithProject(columnInfo.columns);

  List<RexNode> newProjects = Lists.newArrayList();
  for (RexNode n : proj.getChildExps()) {
    newProjects.add(n.accept(columnInfo.getInputRewriter()));
  }

  final RelBuilder relBuilder = relBuilderFactory.create(proj.getCluster(), null);
  relBuilder.push(newScan);
  relBuilder.project(newProjects, proj.getRowType().getFieldNames());
  final RelNode newProj = relBuilder.build();

  if (newProj instanceof Project
      && ProjectRemoveRule.isTrivial((Project) newProj)
      && newScan.getRowType().getFullTypeString().equals(newProj.getRowType().getFullTypeString())) {
      call.transformTo(newScan);
  } else {
    if(newScan.getProjectedColumns().equals(scan.getProjectedColumns())) {
      // no point in doing a pushdown that doesn't change anything.
      return;
    }

    call.transformTo(newProj);
  }
}
 
示例12
public static boolean isTrivialProject(Project project, boolean useNamesInIdentityProjCalc) {
  if (!useNamesInIdentityProjCalc) {
    return ProjectRemoveRule.isTrivial(project);
  }  else {
    return containIdentity(project.getProjects(), project.getRowType(), project.getInput().getRowType());
  }
}
 
示例13
@Override public void register(RelOptPlanner planner) {
  for (RelOptRule rule : JdbcRules.rules(this)) {
    planner.addRule(rule);
  }
  planner.addRule(FilterSetOpTransposeRule.INSTANCE);
  planner.addRule(ProjectRemoveRule.INSTANCE);
}
 
示例14
@Test void testReplaceCommonSubexpression() throws Exception {
  // Note that here it may look like the rule is firing
  // twice, but actually it's only firing once on the
  // common sub-expression.  The purpose of this test
  // is to make sure the planner can deal with
  // rewriting something used as a common sub-expression
  // twice by the same parent (the join in this case).

  final String sql = "select d1.deptno from (select * from dept) d1,\n"
      + "(select * from dept) d2";
  sql(sql).withRule(ProjectRemoveRule.INSTANCE).check();
}
 
示例15
@Override
public void register(RelOptPlanner planner) {
    planner.addRule(FilterSetOpTransposeRule.INSTANCE);
    planner.addRule(ProjectRemoveRule.INSTANCE);
}
 
示例16
protected HepProgramBuilder getProgramBuilder() {
  return new HepProgramBuilder()
    .addRuleInstance(PushFilterPastProjectRule.CALCITE_NO_CHILD_CHECK)
    .addRuleInstance(ProjectMergeRule.INSTANCE)
    .addRuleInstance(ProjectRemoveRule.INSTANCE);
}
 
示例17
@Override
public Prel visitProject(ProjectPrel prel, Void value) throws RuntimeException {
  ProjectPrel proj = prel;

  // Require prefix rename : there exists other expression, in addition to a star column.
  if (!prefixedForStar  // not set yet.
      && StarColumnHelper.containsStarColumnInProject(prel.getInput().getRowType(), proj.getProjects())
      && prel.getRowType().getFieldNames().size() > 1) {
    prefixedForStar = true;
  }

  // For project, we need make sure that the project's field name is same as the input,
  // when the project expression is RexInPutRef, since we may insert a PAS which will
  // rename the projected fields.

  RelNode child = ((Prel) prel.getInput(0)).accept(this, null);

  List<String> fieldNames = Lists.newArrayList();

  for (Pair<String, RexNode> pair : Pair.zip(prel.getRowType().getFieldNames(), proj.getProjects())) {
    if (pair.right instanceof RexInputRef) {
      String name = child.getRowType().getFieldNames().get(((RexInputRef) pair.right).getIndex());
      fieldNames.add(name);
    } else {
      fieldNames.add(pair.left);
    }
  }

  // Make sure the field names are unique : no allow of duplicate field names in a rowType.
  fieldNames = makeUniqueNames(fieldNames);

  RelDataType rowType = RexUtil.createStructType(prel.getCluster().getTypeFactory(), proj.getProjects(), fieldNames);

  ProjectPrel newProj = (ProjectPrel) proj.copy(proj.getTraitSet(), child, proj.getProjects(), rowType);

  if (ProjectRemoveRule.isTrivial(newProj)) {
    return (Prel) child;
  } else {
    return newProj;
  }
}
 
示例18
@Override
public void onMatch(RelOptRuleCall call) {
	LogicalProject project = call.rel(0);
	LogicalTableScan scan = call.rel(1);

	int[] usedFields = RexNodeExtractor.extractRefInputFields(project.getProjects());
	// if no fields can be projected, we keep the original plan.
	if (scan.getRowType().getFieldCount() == usedFields.length) {
		return;
	}

	TableSourceTable oldTableSourceTable = scan.getTable().unwrap(TableSourceTable.class);
	DynamicTableSource newTableSource = oldTableSourceTable.tableSource().copy();

	int[][] projectedFields = new int[usedFields.length][];
	List<String> fieldNames = new ArrayList<>();
	for (int i = 0; i < usedFields.length; ++i) {
		int usedField = usedFields[i];
		projectedFields[i] = new int[] { usedField };
		fieldNames.add(scan.getRowType().getFieldNames().get(usedField));
	}
	((SupportsProjectionPushDown) newTableSource).applyProjection(projectedFields);
	FlinkTypeFactory flinkTypeFactory = (FlinkTypeFactory) oldTableSourceTable.getRelOptSchema().getTypeFactory();
	RelDataType newRowType = flinkTypeFactory.projectStructType(oldTableSourceTable.getRowType(), usedFields);

	// project push down does not change the statistic, we can reuse origin statistic
	TableSourceTable newTableSourceTable = oldTableSourceTable.copy(
			newTableSource, newRowType, new String[] { ("project=[" + String.join(", ", fieldNames) + "]") });

	LogicalTableScan newScan = new LogicalTableScan(
			scan.getCluster(), scan.getTraitSet(), scan.getHints(), newTableSourceTable);
	// rewrite input field in projections
	List<RexNode> newProjects = RexNodeRewriter.rewriteWithNewFieldInput(project.getProjects(), usedFields);
	LogicalProject newProject = project.copy(
			project.getTraitSet(),
			newScan,
			newProjects,
			project.getRowType());

	if (ProjectRemoveRule.isTrivial(newProject)) {
		// drop project if the transformed program merely returns its input
		call.transformTo(newScan);
	} else {
		call.transformTo(newProject);
	}
}
 
示例19
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);
}
 
示例20
private void removeTrivialProject(boolean useRule) {
  VolcanoPlanner planner = new VolcanoPlanner();

  planner.addRelTraitDef(ConventionTraitDef.INSTANCE);

  if (useRule) {
    planner.addRule(ProjectRemoveRule.INSTANCE);
  }

  planner.addRule(new PhysLeafRule());
  planner.addRule(new GoodSingleRule());
  planner.addRule(new PhysProjectRule());

  planner.addRule(
      new ConverterRule(
          RelNode.class,
          PHYS_CALLING_CONVENTION,
          EnumerableConvention.INSTANCE,
          "PhysToIteratorRule") {
        public RelNode convert(RelNode rel) {
          return new PhysToIteratorConverter(
              rel.getCluster(),
              rel);
        }
      });

  RelOptCluster cluster = newCluster(planner);
  PhysLeafRel leafRel =
      new PhysLeafRel(
          cluster,
          "a");
  final RelBuilder relBuilder =
      RelFactories.LOGICAL_BUILDER.create(leafRel.getCluster(), null);
  RelNode projectRel =
      relBuilder.push(leafRel)
          .project(relBuilder.alias(relBuilder.field(0), "this"))
          .build();
  NoneSingleRel singleRel =
      new NoneSingleRel(
          cluster,
          projectRel);
  RelNode convertedRel =
      planner.changeTraits(
          singleRel,
          cluster.traitSetOf(EnumerableConvention.INSTANCE));
  planner.setRoot(convertedRel);
  RelNode result = planner.chooseDelegate().findBestExp();
  assertTrue(result instanceof PhysToIteratorConverter);
}