protected RexBuilder getRexBuilder() { if(project != null) { return project.getCluster().getRexBuilder(); } return super.getRexBuilder(); }
protected DrillProjectRelBase(Convention convention, RelOptCluster cluster, RelTraitSet traits, RelNode child, List<? extends RexNode> exps, RelDataType rowType) { super(cluster, traits, child, exps, rowType); assert getConvention() == convention; nonSimpleFieldCount = this.getRowType().getFieldCount() - getSimpleFieldCount(); }
protected List<NamedExpression> getProjectExpressions(DrillParseContext context) { List<NamedExpression> expressions = Lists.newArrayList(); HashMap<String, String> starColPrefixes = new HashMap<>(); // T1.* will subsume T1.*0, but will not subsume any regular column/expression. // Select *, col1, *, col2 : the intermediate will output one set of regular columns expanded from star with prefix, // plus col1 and col2 without prefix. // This will allow us to differentiate the regular expanded from *, and the regular column referenced in the query. for (Pair<RexNode, String> pair : projects()) { if (StarColumnHelper.isPrefixedStarColumn(pair.right)) { String prefix = StarColumnHelper.extractStarColumnPrefix(pair.right); if (! starColPrefixes.containsKey(prefix)) { starColPrefixes.put(prefix, pair.right); } } } for (Pair<RexNode, String> pair : projects()) { if (! StarColumnHelper.subsumeColumn(starColPrefixes, pair.right)) { LogicalExpression expr = DrillOptiq.toDrill(context, getInput(), pair.left); expressions.add(new NamedExpression(expr, FieldReference.getWithQuotedRef(pair.right))); } } return expressions; }
if (indexContext.getLowerProject() != null) { RelCollation collation = IndexPlanUtils.buildCollationProject(indexContext.getLowerProject().getProjects(), null, indexContext.getScan(), functionInfo, indexContext); finalRel = new ProjectPrel(indexContext.getScan().getCluster(), indexScanTraitSet.plus(collation), indexScanPrel, indexContext.getLowerProject().getProjects(), indexContext.getLowerProject().getRowType()); indexContext.getLowerProject()!=null?indexContext.getLowerProject().getDigest(): indexContext.getScan().getDigest(), finalRel.getDigest()); return finalRel;
origScan, functionInfo, indexContext); indexProjectPrel = new ProjectPrel(origScan.getCluster(), indexFilterTraitSet.plus(collation), indexFilterPrel, IndexPlanUtils.getProjects(origProject), origProject.getRowType()); origScan, functionInfo, indexContext); ProjectPrel cap = new ProjectPrel(upperProject.getCluster(), newCollation==null?finalRel.getTraitSet() : finalRel.getTraitSet().plus(newCollation), finalRel, IndexPlanUtils.getProjects(upperProject), upperProject.getRowType()); upperProject==null?indexContext.getFilter().getDigest(): upperProject.getDigest(), finalRel.getDigest()); return finalRel;
RelDataType origRowType = origProject == null ? origScan.getRowType() : origProject.getRowType(); DrillDistributionTrait newDist = null; newDist = upperProject.getInput().getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE); if (!settings.isIndexForceSortNonCovering()) { newCollation = IndexPlanUtils.buildCollationProject(IndexPlanUtils.getProjects(upperProject), origProject, origScan, ProjectPrel cap = new ProjectPrel(upperProject.getCluster(), newProjectTraits, newRel, IndexPlanUtils.getProjects(upperProject), upperProject.getRowType()); newRel = cap;
protected RelDataType getRowType() { if(project != null) { return project.getRowType(); } return super.getRowType(); }
public static List<RexNode> getProjects(DrillProjectRelBase proj) { return proj.getProjects(); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner, mq).multiplyBy(.1); } double rowCount = mq.getRowCount(this); // Attribute small cost for projecting simple fields. In reality projecting simple columns in not free and // this allows projection pushdown/project-merge rules to kick-in thereby eliminating unneeded columns from // the projection. double cpuCost = DrillCostBase.PROJECT_CPU_COST * rowCount * nonSimpleFieldCount + (this.getRowType().getFieldCount() - nonSimpleFieldCount) * rowCount * DrillCostBase.BASE_CPU_COST; DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory(); return costFactory.makeCost(rowCount, cpuCost, 0, 0); }
private List<Pair<RexNode, String>> projects() { return Pair.zip(exps, getRowType().getFieldNames()); }
private int getSimpleFieldCount() { int cnt = 0; final ComplexFieldWithNamedSegmentIdentifier complexFieldIdentifer = new ComplexFieldWithNamedSegmentIdentifier(); // SimpleField, either column name, or complex field reference with only named segment ==> no array segment // a, a.b.c are simple fields. // a[1].b.c, a.b[1], a.b.c[1] are not simple fields, since they all contain array segment. // a + b, a * 10 + b, etc are not simple fields, since they are expressions. for (RexNode expr : this.getProjects()) { if (expr instanceof RexInputRef) { // Simple Field reference. cnt++; } else if (expr instanceof RexCall && expr.accept(complexFieldIdentifer)) { // Complex field with named segments only. cnt++; } } return cnt; }
if (upperProject != null) { ProjectPrel cap = new ProjectPrel(finalRel.getCluster(), finalRel.getTraitSet(), finalRel, IndexPlanUtils.getProjects(upperProject), upperProject.getRowType()); finalRel = cap;
if (indexContext.getUpperProject() != null && indexContext.getLowerProject() != null) { LogicalExpression expr = RexToExpression.toDrill(parserContext, indexContext.getLowerProject(), indexContext.getScan(), indexContext.getUpperProject().getProjects().get(idx)); indexContext.getSortExprs().add(expr);
public RelNode buildOriginalProject (RelNode newRel) { RelDataType origRowType = origProject == null ? origScan.getRowType() : origProject.getRowType(); final RelDataTypeFactory.FieldInfoBuilder finalFieldTypeBuilder = origScan.getCluster().getTypeFactory().builder(); List<RelDataTypeField> hjRowFields = newRel.getRowType().getFieldList(); int toRemoveRowKeyCount = 1; if (getRowKeyIndex(origRowType, origScan) < 0 ) { toRemoveRowKeyCount = 2; } finalFieldTypeBuilder.addAll(hjRowFields.subList(0, hjRowFields.size()-toRemoveRowKeyCount)); final RelDataType finalProjectRowType = finalFieldTypeBuilder.build(); List<RexNode> resetExprs = Lists.newArrayList(); for (int idx=0; idx<hjRowFields.size()-toRemoveRowKeyCount; ++idx) { resetExprs.add(RexInputRef.of(idx, newRel.getRowType())); } final ProjectPrel resetProjectPrel = new ProjectPrel(newRel.getCluster(), newRel.getTraitSet(), newRel, resetExprs, finalProjectRowType); newRel = resetProjectPrel; RelNode finalRel = Prule.convert(newRel, newRel.getTraitSet()); return finalRel; }
private boolean buildAndCheckCollation(IndexProperties indexProps) { IndexDescriptor indexDesc = indexProps.getIndexDesc(); FunctionalIndexInfo functionInfo = indexDesc.getFunctionalInfo(); RelCollation inputCollation; // for the purpose of collation we can assume that a covering index scan would provide // the collation property that would be relevant for non-covering as well ScanPrel indexScanPrel = IndexPlanUtils.buildCoveringIndexScan(indexContext.getScan(), indexDesc.getIndexGroupScan(), indexContext, indexDesc); inputCollation = indexScanPrel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE); // we don't create collation for Filter because it will inherit the child's collation if (indexContext.hasLowerProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getLowerProject().getProjects(), null, indexContext.getScan(), functionInfo,indexContext); } if (indexContext.hasUpperProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getUpperProject().getProjects(), indexContext.getLowerProject(), indexContext.getScan(), functionInfo, indexContext); } if ((inputCollation != null) && (inputCollation.satisfies(indexContext.getCollation()))) { return true; } return false; }
RelDataType origRowType = origProject.getRowType(); List<RelDataTypeField> origProjFields = origRowType.getFieldList(); leftFieldTypeBuilder.addAll(origProjFields);
if (indexContext.getUpperProject() != null) { if (indexContext.getLowerProject() == null) { for (RexNode rex : indexContext.getUpperProject().getProjects()) { LogicalExpression expr = RexToExpression.toDrill(parserContext, null, indexContext.getScan(), rex); exprs.add(expr); for (RexNode rex : indexContext.getUpperProject().getProjects()) { LogicalExpression expr = RexToExpression.toDrill(parserContext, indexContext.getLowerProject(), indexContext.getScan(), rex); exprs.add(expr); for (RexNode rex : indexContext.getLowerProject().getProjects()) { LogicalExpression expr = DrillOptiq.toDrill(parserContext, indexContext.getScan(), rex); exprs.add(expr);