protected void doPushLimitIntoGroupScan(RelOptRuleCall call, LimitPrel limit, final ProjectPrel project, ScanPrel scan, GroupScan groupScan) { try { final GroupScan newGroupScan = getGroupScanWithLimit(groupScan, limit); if (newGroupScan == null) { return; } final ScanPrel newScan = new ScanPrel(scan.getCluster(), scan.getTraitSet(), newGroupScan, scan.getRowType(), scan.getTable()); final RelNode newChild; if (project != null) { final ProjectPrel newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), newScan, project.getProjects(), project.getRowType()); newChild = newProject; } else { newChild = newScan; } call.transformTo(newChild); logger.debug("pushLimitIntoGroupScan: Converted to a new ScanPrel " + newScan.getGroupScan()); } catch (Exception e) { logger.warn("pushLimitIntoGroupScan: Exception while trying limit pushdown!", e); } }
protected void doPushLimitIntoRowKeyJoin(RelOptRuleCall call, LimitPrel limit, final ProjectPrel project, RowKeyJoinPrel join) { final RelNode newChild; try { RelNode left = join.getLeft(); RelNode right = join.getRight(); final RelNode limitOnLeft = new LimitPrel(left.getCluster(), left.getTraitSet(), left, limit.getOffset(), limit.getFetch()); RowKeyJoinPrel newJoin = new RowKeyJoinPrel(join.getCluster(), join.getTraitSet(), limitOnLeft, right, join.getCondition(), join.getJoinType()); if (project != null) { final ProjectPrel newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), newJoin, project.getProjects(), project.getRowType()); newChild = newProject; } else { newChild = newJoin; } call.transformTo(newChild); logger.debug("pushLimitIntoRowKeyJoin: Pushed limit on left side of Join " + join.toString()); } catch (Exception e) { logger.warn("pushLimitIntoRowKeyJoin: Exception while trying limit pushdown!", e); } } }
@Override public void onMatch(RelOptRuleCall call) { final ProjectPrel project = call.rel(1); final LimitPrel limit = call.rel(0); RelNode child = project.getInput(); final RelNode limitUnderProject = new LimitPrel(child.getCluster(), child.getTraitSet(), child, limit.getOffset(), limit.getFetch()); final RelNode newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), limitUnderProject, project.getProjects(), project.getRowType()); if (DrillRelOptUtil.isProjectFlatten(project)) { //Preserve limit above the project since Flatten can produce more rows. Also mark it so we do not fire the rule again. child = newProject; final RelNode limitAboveProject = new LimitPrel(child.getCluster(), child.getTraitSet(), child, limit.getOffset(), limit.getFetch(), true); call.transformTo(limitAboveProject); } else { call.transformTo(newProject); } }
new ProjectPrel(project.getCluster(), project.getTraitSet().plus(Prel.DRILL_PHYSICAL), newScan,
@Override public Project copy(RelTraitSet traitSet, RelNode input, List<RexNode> exps, RelDataType rowType) { return new ProjectPrel(getCluster(), traitSet, input, exps, rowType, this.outputProj); }
@Override public Prel prepareForLateralUnnestPipeline(List<RelNode> children) { RelDataTypeFactory typeFactory = this.getCluster().getTypeFactory(); RexBuilder builder = this.getCluster().getRexBuilder(); List<RexNode> projects = Lists.newArrayList(); projects.add(builder.makeInputRef(typeFactory.createSqlType(SqlTypeName.INTEGER), 0)); // right shift the previous field indices. projects.addAll(DrillRelOptUtil.transformExprs(builder, this.getProjects(), DrillRelOptUtil.rightShiftColsInRowType(this.getInput().getRowType()))); List<String> fieldNames = new ArrayList<>(); List<RelDataType> fieldTypes = new ArrayList<>(); fieldNames.add("$drill_implicit_field$"); fieldTypes.add(typeFactory.createSqlType(SqlTypeName.INTEGER)); for (RelDataTypeField field : this.rowType.getFieldList()) { fieldNames.add(field.getName()); fieldTypes.add(field.getType()); } RelDataType newRowType = typeFactory.createStructType(fieldTypes, fieldNames); return (Prel) this.copy(this.getTraitSet(), children.get(0), projects, newRowType); } }
@Override public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException { Prel child = (Prel) this.getInput(); PhysicalOperator childPOP = child.getPhysicalOperator(creator); org.apache.drill.exec.physical.config.Project p = new org.apache.drill.exec.physical.config.Project( this.getProjectExpressions(new DrillParseContext(PrelUtil.getSettings(getCluster()))), childPOP, outputProj); return creator.addMetadata(this, p); }
allExprs.add(currRexNode); relDataTypes.add(new RelDataTypeFieldImpl("EXPR$" + exprIndex, allExprs.size(), factory.createSqlType(SqlTypeName.ANY))); childProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), originalInput, ImmutableList.copyOf(allExprs), new RelRecordType(relDataTypes)); originalInput = childProject;
ProjectPrel newProject = new ProjectPrel(node.getCluster(), project.getTraitSet(), newChild, exprList, new RelRecordType(relDataTypes)); FlattenPrel flatten = new FlattenPrel(project.getCluster(), project.getTraitSet(), newProject, flatttenExpr); return flatten;
protected void doPushLimitIntoGroupScan(RelOptRuleCall call, LimitPrel limit, final ProjectPrel project, ScanPrel scan, GroupScan groupScan) { try { final GroupScan newGroupScan = getGroupScanWithLimit(groupScan, limit); if (newGroupScan == null) { return; } final ScanPrel newScan = new ScanPrel(scan.getCluster(), scan.getTraitSet(), newGroupScan, scan.getRowType(), scan.getTable()); final RelNode newChild; if (project != null) { final ProjectPrel newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), newScan, project.getProjects(), project.getRowType()); newChild = newProject; } else { newChild = newScan; } call.transformTo(newChild); logger.debug("pushLimitIntoGroupScan: Converted to a new ScanPrel " + newScan.getGroupScan()); } catch (Exception e) { logger.warn("pushLimitIntoGroupScan: Exception while trying limit pushdown!", e); } }
RelDataType rowType = RexUtil.createStructType(prel.getCluster().getTypeFactory(), prel.getProjects(), fieldNames, null);
protected void doPushLimitIntoRowKeyJoin(RelOptRuleCall call, LimitPrel limit, final ProjectPrel project, RowKeyJoinPrel join) { final RelNode newChild; try { RelNode left = join.getLeft(); RelNode right = join.getRight(); final RelNode limitOnLeft = new LimitPrel(left.getCluster(), left.getTraitSet(), left, limit.getOffset(), limit.getFetch()); RowKeyJoinPrel newJoin = new RowKeyJoinPrel(join.getCluster(), join.getTraitSet(), limitOnLeft, right, join.getCondition(), join.getJoinType()); if (project != null) { final ProjectPrel newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), newJoin, project.getProjects(), project.getRowType()); newChild = newProject; } else { newChild = newJoin; } call.transformTo(newChild); logger.debug("pushLimitIntoRowKeyJoin: Pushed limit on left side of Join " + join.toString()); } catch (Exception e) { logger.warn("pushLimitIntoRowKeyJoin: Exception while trying limit pushdown!", e); } } }
newPrel = new UnorderedMuxExchangePrel(addColumnprojectPrel.getCluster(), addColumnprojectPrel.getTraitSet(), addColumnprojectPrel);
DrillParseContext parseContxt = new DrillParseContext(PrelUtil.getPlannerSettings(newProject.getCluster())); for(RexNode projectRex: newProject.getProjects()) { RexNode newRex = IndexPlanUtils.rewriteFunctionalRex(indexContext, parseContxt, null, origScan, projectRex, ProjectPrel rewrittenProject = new ProjectPrel(newProject.getCluster(), collation==null? newProject.getTraitSet() : newProject.getTraitSet().plus(collation), indexScanPrel, newProjects, newProject.getRowType());
DrillParseContext parseContxt = new DrillParseContext(PrelUtil.getPlannerSettings(newProject.getCluster())); for(RexNode projectRex: newProject.getProjects()) { RexNode newRex = IndexPlanUtils.rewriteFunctionalRex(indexContext, parseContxt, null, origScan, projectRex, indexScanPrel.getRowType(), functionInfo); ProjectPrel rewrittenProject = new ProjectPrel(newProject.getCluster(), newCollation==null? newProject.getTraitSet() : newProject.getTraitSet().plus(newCollation), indexFilterPrel, newProjects, newProject.getRowType());
@Override public void onMatch(RelOptRuleCall call) { final ProjectPrel project = call.rel(1); final LimitPrel limit = call.rel(0); RelNode child = project.getInput(); final RelNode limitUnderProject = new LimitPrel(child.getCluster(), child.getTraitSet(), child, limit.getOffset(), limit.getFetch()); final RelNode newProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), limitUnderProject, project.getProjects(), project.getRowType()); if (DrillRelOptUtil.isProjectFlatten(project)) { //Preserve limit above the project since Flatten can produce more rows. Also mark it so we do not fire the rule again. child = newProject; final RelNode limitAboveProject = new LimitPrel(child.getCluster(), child.getTraitSet(), child, limit.getOffset(), limit.getFetch(), true); call.transformTo(limitAboveProject); } else { call.transformTo(newProject); } }
new ProjectPrel(project.getCluster(), project.getTraitSet().plus(Prel.DRILL_PHYSICAL), newScan,