private static RexCall adjustOBSchema(RexCall obyExpr, Project obChild, List<FieldSchema> resultSchema) { int a = -1; List<RexNode> operands = new ArrayList<>(); for (int k = 0; k < obyExpr.operands.size(); k++) { RexNode rn = obyExpr.operands.get(k); for (int j = 0; j < resultSchema.size(); j++) { if( obChild.getChildExps().get(j).toString().equals(rn.toString())) { a = j; break; } } if (a != -1) { operands.add(new RexInputRef(a, rn.getType())); } else { if (rn instanceof RexCall) { operands.add(adjustOBSchema((RexCall)rn, obChild, resultSchema)); } else { operands.add(rn); } } a = -1; } return (RexCall) obChild.getCluster().getRexBuilder().makeCall( obyExpr.getType(), obyExpr.getOperator(), operands); }
RelMetadataQuery mq = rel.getCluster().getMetadataQuery(); double numRows = mq.getRowCount(tScan); List<ColStatistics> colStats = tScan.getColStat(BitSets
private static RexCall adjustOBSchema(RexCall obyExpr, Project obChild, List<FieldSchema> resultSchema) { int a = -1; List<RexNode> operands = new ArrayList<>(); for (int k = 0; k < obyExpr.operands.size(); k++) { RexNode rn = obyExpr.operands.get(k); for (int j = 0; j < resultSchema.size(); j++) { if( obChild.getChildExps().get(j).toString().equals(rn.toString())) { a = j; break; } } if (a != -1) { operands.add(new RexInputRef(a, rn.getType())); } else { if (rn instanceof RexCall) { operands.add(adjustOBSchema((RexCall)rn, obChild, resultSchema)); } else { operands.add(rn); } } a = -1; } return (RexCall) obChild.getCluster().getRexBuilder().makeCall( obyExpr.getType(), obyExpr.getOperator(), operands); }
@Override public void onMatch(RelOptRuleCall call) { final Project project = call.rel(0); boolean changed = false; final RexBuilder rexBuilder = project.getCluster().getRexBuilder(); List<RexNode> newProjects = new ArrayList<>(); for (RexNode oldNode : project.getProjects()) { RexNode newNode = analyzeRexNode(rexBuilder, oldNode); if (!newNode.toString().equals(oldNode.toString())) { changed = true; newProjects.add(newNode); } else { newProjects.add(oldNode); } } if (!changed) { return; } Project newProject = project.copy(project.getTraitSet(), project.getInput(), newProjects, project.getRowType(), project.getFlags()); call.transformTo(newProject); }
@Override public RelNode convert(RelNode rel) { final Project project = (Project) rel; final RelNode input = project.getInput(); return new StreamsProjectRel(project.getCluster(), project.getTraitSet().replace(StreamsLogicalConvention.INSTANCE), convert(input, input.getTraitSet().replace(StreamsLogicalConvention.INSTANCE)), project.getProjects(), project.getRowType()); } }
final RelOptCluster cluster = project.getCluster(); RelNode newProject = RelOptUtil.createProject(aggregate, ImmutableList.of(rexBuilder.makeCast(
final RexBuilder rexBuilder = project.getCluster().getRexBuilder(); RelOptPredicateList childInfo = mq.getPulledUpPredicates(child);
final RexBuilder rexBuilder = project.getCluster().getRexBuilder(); RelOptPredicateList childInfo = mq.getPulledUpPredicates(child);
@Override public void onMatch(RelOptRuleCall call) { final Project project = call.rel(0); final RexBuilder rexBuilder = project.getCluster().getRexBuilder(); List<RexNode> topProjExprs = project.getChildExps(); Join join = call.rel(1);
project.getCluster().getPlanner().getContext().unwrap(SubqueryConf.class); boolean isCorrScalarQuery = subqueryConfig.getCorrScalarRexSQWithAgg().contains(e.rel); boolean hasNoWindowingAndNoGby =
public static int numReducibleExprs(Project project) { final List<RexNode> expList = Lists.newArrayList(project.getProjects()); final RelMetadataQuery mq = project.getCluster().getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(project.getInput()); boolean reducible = reduceExpressions(project, expList, predicates); if (reducible) { int numReducible = 0; for (int i = 0; i < project.getProjects().size(); i++) { if (!project.getProjects().get(i).toString().equals(expList.get(i).toString())) { numReducible++; } } return numReducible; } else { return 0; } } }
private static RexCall adjustOBSchema(RexCall obyExpr, Project obChild, List<FieldSchema> resultSchema) { int a = -1; List<RexNode> operands = new ArrayList<>(); for (int k = 0; k < obyExpr.operands.size(); k++) { RexNode rn = obyExpr.operands.get(k); for (int j = 0; j < resultSchema.size(); j++) { if( obChild.getChildExps().get(j).toString().equals(rn.toString())) { a = j; break; } } if (a != -1) { operands.add(new RexInputRef(a, rn.getType())); } else { if (rn instanceof RexCall) { operands.add(adjustOBSchema((RexCall)rn, obChild, resultSchema)); } else { operands.add(rn); } } a = -1; } return (RexCall) obChild.getCluster().getRexBuilder().makeCall( obyExpr.getType(), obyExpr.getOperator(), operands); }
/** * Expression lineage from Project. */ public Set<RexNode> getExpressionLineage(Project rel, final RelMetadataQuery mq, RexNode outputExpression) { final RelNode input = rel.getInput(); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); // Extract input fields referenced by expression final ImmutableBitSet inputFieldsUsed = extractInputRefs(outputExpression); // Infer column origin expressions for given references final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>(); for (int idx : inputFieldsUsed) { final RexNode inputExpr = rel.getChildExps().get(idx); final Set<RexNode> originalExprs = mq.getExpressionLineage(input, inputExpr); if (originalExprs == null) { // Bail out return null; } final RexInputRef ref = RexInputRef.of(idx, rel.getRowType().getFieldList()); mapping.put(ref, originalExprs); } // Return result return createAllPossibleExpressions(rexBuilder, outputExpression, mapping); }
/** * Expression lineage from Project. */ public Set<RexNode> getExpressionLineage(Project rel, final RelMetadataQuery mq, RexNode outputExpression) { final RelNode input = rel.getInput(); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); // Extract input fields referenced by expression final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>(); final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields); outputExpression.accept(inputFinder); final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build(); // Infer column origin expressions for given references final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>(); for (int idx : inputFieldsUsed) { final RexNode inputExpr = rel.getChildExps().get(idx); final Set<RexNode> originalExprs = mq.getExpressionLineage(input, inputExpr); if (originalExprs == null) { // Bail out return null; } final RexInputRef ref = RexInputRef.of(idx, rel.getRowType().getFieldList()); mapping.put(ref, originalExprs); } // Return result return createAllPossibleExpressions(rexBuilder, outputExpression, mapping); }
public Double getSelectivity(Project rel, RelMetadataQuery mq, RexNode predicate) { final List<RexNode> notPushable = new ArrayList<>(); final List<RexNode> pushable = new ArrayList<>(); RelOptUtil.splitFilters( ImmutableBitSet.range(rel.getRowType().getFieldCount()), predicate, pushable, notPushable); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); RexNode childPred = RexUtil.composeConjunction(rexBuilder, pushable, true); RexNode modifiedPred; if (childPred == null) { modifiedPred = null; } else { modifiedPred = RelOptUtil.pushPastProject(childPred, rel); } Double selectivity = mq.getSelectivity(rel.getInput(), modifiedPred); if (selectivity == null) { return null; } else { RexNode pred = RexUtil.composeConjunction(rexBuilder, notPushable, true); return selectivity * RelMdUtil.guessSelectivity(pred); } }
public Double getSelectivity(Project rel, RelMetadataQuery mq, RexNode predicate) { final List<RexNode> notPushable = new ArrayList<>(); final List<RexNode> pushable = new ArrayList<>(); RelOptUtil.splitFilters( ImmutableBitSet.range(rel.getRowType().getFieldCount()), predicate, pushable, notPushable); final RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); RexNode childPred = RexUtil.composeConjunction(rexBuilder, pushable, true); RexNode modifiedPred; if (childPred == null) { modifiedPred = null; } else { modifiedPred = RelOptUtil.pushPastProject(childPred, rel); } Double selectivity = mq.getSelectivity(rel.getInput(), modifiedPred); if (selectivity == null) { return null; } else { RexNode pred = RexUtil.composeConjunction(rexBuilder, notPushable, true); return selectivity * RelMdUtil.guessSelectivity(pred); } }
@Override public void onMatch(RelOptRuleCall call) { final Project toTransform = call.rel(0); final RelNode input = toTransform.getInput(); final RelTraitSet traits = toTransform.getTraitSet().plus(Rel.LOGICAL); final RelNode convertedInput = convert(input, input.getTraitSet().plus(Rel.LOGICAL).simplify()); call.transformTo(new ProjectRel(toTransform.getCluster(), traits, convertedInput, toTransform.getProjects(), toTransform.getRowType())); } }
@Override public void onMatch(RelOptRuleCall call) { final Project project = call.rel(0); final RelNode input = project.getInput(); final RelTraitSet traits = project.getTraitSet().plus(DrillRel.DRILL_LOGICAL); final RelNode convertedInput = convert(input, input.getTraitSet().plus(DrillRel.DRILL_LOGICAL).simplify()); call.transformTo(new DrillProjectRel( project.getCluster(), traits, convertedInput, project.getProjects(), project.getRowType())); } }
@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); } }
public void onMatch(RelOptRuleCall call) { Project project = call.rel(0); DruidQuery query = call.rel(1); final RelOptCluster cluster = project.getCluster(); final RexBuilder rexBuilder = cluster.getRexBuilder(); if (!DruidQuery.isValidSignature(query.signature() + 'o')) { return; } Pair<ImmutableMap<String, String>, Boolean> scanned = scanProject(query, project); // Only try to push down Project when there will be Post aggregators in result DruidQuery if (scanned.right) { Pair<Project, Project> splitProjectAggregate = splitProject(rexBuilder, query, project, scanned.left, cluster); Project inner = splitProjectAggregate.left; Project outer = splitProjectAggregate.right; DruidQuery newQuery = DruidQuery.extendQuery(query, inner); // When all project get pushed into DruidQuery, the project can be replaced by DruidQuery. if (outer != null) { Project newProject = outer.copy(outer.getTraitSet(), newQuery, outer.getProjects(), outer.getRowType()); call.transformTo(newProject); } else { call.transformTo(newQuery); } } }