private Prel newProject(List<RexNode> exprs, RelDataType rowType, Prel child) { return new ProjectPrel(cluster, traits, child, exprs, rowType); }
private Prel newProject(List<RexNode> exprs, RelDataType rowType, Prel child) { return new ProjectPrel(cluster, traits, child, exprs, rowType); }
@Override public Project copy(RelTraitSet traitSet, RelNode input, List<RexNode> exps, RelDataType rowType) { return new ProjectPrel(getCluster(), traitSet, input, exps, rowType); }
private Prel addTrivialOrderedProjectPrel(Prel prel) { RelDataType t = prel.getRowType(); RexBuilder b = prel.getCluster().getRexBuilder(); List<RexNode> projections = Lists.newArrayList(); int projectCount = t.getFieldList().size(); // no point in reordering if we only have one column if (projectCount < 2) { return prel; } for (int i = 0; i < projectCount; i++) { projections.add(b.makeInputRef(prel, i)); } return new ProjectPrel(prel.getCluster(), prel.getTraitSet(), prel, projections, prel.getRowType()); }
private RelNode rename(RelNode input, List<RelDataTypeField> inputFields, List<String> outputFieldNames) { List<RexNode> exprs = Lists.newArrayList(); for (RelDataTypeField field : inputFields) { RexNode expr = input.getCluster().getRexBuilder().makeInputRef(field.getType(), field.getIndex()); exprs.add(expr); } RelDataType rowType = RexUtil.createStructType(input.getCluster().getTypeFactory(), exprs, outputFieldNames); ProjectPrel proj = new ProjectPrel(input.getCluster(), input.getTraitSet(), input, exprs, rowType); return proj; }
private Prel renameAsNecessary(RelDataType expectedRowType, Prel initialInput) { if(RelOptUtil.areRowTypesEqual(initialInput.getRowType(), expectedRowType, false) && !RelOptUtil.areRowTypesEqual(initialInput.getRowType(), expectedRowType, true)) { final List<RexNode> refs = new ArrayList<>(); final List<RelDataTypeField> fields = expectedRowType.getFieldList(); final RexBuilder rb = initialInput.getCluster().getRexBuilder(); for(int i = 0; i < expectedRowType.getFieldCount(); i++) { refs.add(rb.makeInputRef(fields.get(i).getType(), i)); } return new ProjectPrel(initialInput.getCluster(), initialInput.getTraitSet(), initialInput, refs, expectedRowType); } else { return initialInput; } }
output = new ProjectPrel(output.getCluster(), poppedProject.getTraitSet(), output, poppedProject.getChildExps(), poppedProject.getRowType());
public static ProjectPrel addHashProject(List<DistributionField> distFields, Prel input, Integer ringCount){ // Insert Project SqlOperatorImpl with new column that will be a hash for HashToRandomExchange fields final List<String> outputFieldNames = Lists.newArrayList(input.getRowType().getFieldNames()); final String fieldName = ringCount == null ? HashPrelUtil.HASH_EXPR_NAME : WriterPrel.BUCKET_NUMBER_FIELD; outputFieldNames.add(fieldName); final RexBuilder rexBuilder = input.getCluster().getRexBuilder(); final List<RelDataTypeField> childRowTypeFields = input.getRowType().getFieldList(); // create new hashed field. final HashExpressionCreatorHelper<RexNode> hashHelper = new RexNodeBasedHashExpressionCreatorHelper(rexBuilder); final List<RexNode> distFieldRefs = Lists.newArrayListWithExpectedSize(distFields.size()); for(int i = 0; i < distFields.size(); i++) { final int fieldId = distFields.get(i).getFieldId(); distFieldRefs.add(rexBuilder.makeInputRef(childRowTypeFields.get(fieldId).getType(), fieldId)); } final List <RexNode> updatedExpr = Lists.newArrayListWithExpectedSize(childRowTypeFields.size() + 1); for ( RelDataTypeField field : childRowTypeFields) { RexNode rex = rexBuilder.makeInputRef(field.getType(), field.getIndex()); updatedExpr.add(rex); } RexNode hashExpression = HashPrelUtil.createHashBasedPartitionExpression(distFieldRefs, hashHelper); if(ringCount != null){ RelDataType intType = input.getCluster().getTypeFactory().createSqlType(SqlTypeName.INTEGER); hashExpression = rexBuilder.makeCall(SqlStdOperatorTable.MOD, ImmutableList.of(hashExpression, rexBuilder.makeExactLiteral(BigDecimal.valueOf(ringCount), intType))); hashExpression = rexBuilder.makeCall(SqlStdOperatorTable.ABS, Collections.singletonList(hashExpression)); } updatedExpr.add(hashExpression); RelDataType rowType = RexUtil.createStructType(input.getCluster().getTypeFactory(), updatedExpr, outputFieldNames); ProjectPrel addColumnprojectPrel = new ProjectPrel(input.getCluster(), input.getTraitSet(), input, updatedExpr, rowType); return addColumnprojectPrel; }
@Override public Prel visitLeaf(LeafPrel scanPrel, Void value) throws RuntimeException { if (StarColumnHelper.containsStarColumn(scanPrel.getRowType()) && prefixedForStar ) { List<RexNode> exprs = Lists.newArrayList(); for (RelDataTypeField field : scanPrel.getRowType().getFieldList()) { RexNode expr = scanPrel.getCluster().getRexBuilder().makeInputRef(field.getType(), field.getIndex()); exprs.add(expr); } List<String> fieldNames = Lists.newArrayList(); long tableId = tableNumber.getAndIncrement(); for (String name : scanPrel.getRowType().getFieldNames()) { if (StarColumnHelper.isNonPrefixedStarColumn(name)) { fieldNames.add("T" + tableId + StarColumnHelper.PREFIX_DELIMITER + name); // Add prefix to * column. } else { fieldNames.add(name); // Keep regular column as it is. } } RelDataType rowType = RexUtil.createStructType(scanPrel.getCluster().getTypeFactory(), exprs, fieldNames); // insert a PAS. ProjectPrel proj = new ProjectPrel(scanPrel.getCluster(), scanPrel.getTraitSet(), scanPrel, exprs, rowType); return proj; } else { return visitPrel(scanPrel, value); } }
@Override public RelNode convertChild(ProjectRel project, RelNode rel) throws RuntimeException { DistributionTrait childDist = rel.getTraitSet().getTrait(DistributionTraitDef.INSTANCE); RelCollation childCollation = rel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE); DistributionTrait newDist = convertDist(childDist, distributionMap); RelCollation newCollation = convertRelCollation(childCollation, collationMap); RelTraitSet newProjectTraits = newTraitSet(Prel.PHYSICAL, newDist, newCollation); return new ProjectPrel(project.getCluster(), newProjectTraits, rel, project.getProjects(), project.getRowType()); }
private Prel visit(ExchangePrel hashPrel, List<DistributionTrait.DistributionField> fields, Prel child) { final List<String> childFields = child.getRowType().getFieldNames(); // Insert Project SqlOperatorImpl with new column that will be a hash for HashToRandomExchange fields final ProjectPrel addColumnprojectPrel = HashPrelUtil.addHashProject(fields, child, null); final Prel newPrel = (Prel) hashPrel.copy(addColumnprojectPrel.getTraitSet(), Collections.<RelNode>singletonList(addColumnprojectPrel)); int validRows = newPrel.getRowType().getFieldCount() - 1; final List<RelDataTypeField> all = newPrel.getRowType().getFieldList(); final List<RexNode> keptExprs = new ArrayList<>(validRows); final RexBuilder rexBuilder = newPrel.getCluster().getRexBuilder(); for(int i = 0; i < validRows; i++){ RexNode rex = rexBuilder.makeInputRef(all.get(i).getType(), i); keptExprs.add(rex); } // remove earlier inserted Project SqlOperatorImpl - since it creates issues down the road in HashJoin RelDataType removeRowType = RexUtil.createStructType(newPrel.getCluster().getTypeFactory(), keptExprs, childFields); return new ProjectPrel(newPrel.getCluster(), newPrel.getTraitSet(), newPrel, keptExprs, removeRowType); }
final ProjectPrel newBottomProject = new ProjectPrel(topRel.getCluster(), topRel.getTraitSet(), inputRel, bottomExprs, bottomType);
private Prel insertProjUnderScreenOrWriter(Prel prel, RelDataType origRowType, Prel child) { ProjectPrel proj = null; List<RelNode> children = Lists.newArrayList(); List<RexNode> exprs = Lists.newArrayList(); for (int i = 0; i < origRowType.getFieldCount(); i++) { RexNode expr = child.getCluster().getRexBuilder().makeInputRef(origRowType.getFieldList().get(i).getType(), i); exprs.add(expr); } RelDataType newRowType = RexUtil.createStructType(child.getCluster().getTypeFactory(), exprs, origRowType.getFieldNames()); int fieldCount = prel.getRowType().isStruct()? prel.getRowType().getFieldCount():1; // Insert PUS/PUW : remove the prefix and keep the original field name. if (fieldCount > 1) { // // no point in allowing duplicates if we only have one column proj = new ProjectAllowDupPrel(child.getCluster(), child.getTraitSet(), child, exprs, newRowType); } else { proj = new ProjectPrel(child.getCluster(), child.getTraitSet(), child, exprs, newRowType); } children.add(proj); return (Prel) prel.copy(prel.getTraitSet(), children); } @Override
exprs.add(RexInputRef.of(0, scanRowType)); final ProjectPrel newProj = new ProjectPrel(agg.getCluster(), agg.getTraitSet().plus(Prel.PHYSICAL) .plus(DistributionTrait.SINGLETON), values, exprs, agg.getRowType()); call.transformTo(newProj);
@Override public void onMatch(RelOptRuleCall call) { final ProjectRel project = (ProjectRel) call.rel(0); final RelNode input = project.getInput(); RelTraitSet traits = input.getTraitSet().plus(Prel.PHYSICAL); RelNode convertedInput = convert(input, traits); // Maintain two different map for distribution trait and collation trait. // For now, the only difference comes from the way how cast function impacts propagating trait. final Map<Integer, Integer> distributionMap = getDistributionMap(project); final Map<Integer, Integer> collationMap = getCollationMap(project); boolean traitPull = new ProjectTraitPull(call, distributionMap, collationMap).go(project, convertedInput); if(!traitPull){ call.transformTo(new ProjectPrel(project.getCluster(), convertedInput.getTraitSet(), convertedInput, project.getProjects(), project.getRowType())); } }