/** * Derives the list of column names suitable for NATURAL JOIN. These are the columns that occur * exactly once on each side of the join. * * @param leftRowType Row type of left input to the join * @param rightRowType Row type of right input to the join * @return List of columns that occur once on each side */ public static List<String> deriveNaturalJoinColumnList( RelDataType leftRowType, RelDataType rightRowType) { final List<String> naturalColumnNames = new ArrayList<>(); final List<String> leftNames = leftRowType.getFieldNames(); final List<String> rightNames = rightRowType.getFieldNames(); for (String name : leftNames) { if ((Collections.frequency(leftNames, name) == 1) && (Collections.frequency(rightNames, name) == 1)) { naturalColumnNames.add(name); } } return naturalColumnNames; }
/** * Creates a relational expression that projects the given fields of the input. * * <p>Optimizes if the fields are the identity projection. * * @param relBuilder RelBuilder * @param child Input relational expression * @param posList Source of each projected field * @return Relational expression that projects given fields */ public static RelNode createProject( final RelBuilder relBuilder, final RelNode child, final List<Integer> posList) { RelDataType rowType = child.getRowType(); final List<String> fieldNames = rowType.getFieldNames(); final RexBuilder rexBuilder = child.getCluster().getRexBuilder(); return createProject( child, new AbstractList<RexNode>() { public int size() { return posList.size(); } public RexNode get(int index) { final int pos = posList.get(index); return rexBuilder.makeInputRef(child, pos); } }, new AbstractList<String>() { public int size() { return posList.size(); } public String get(int index) { final int pos = posList.get(index); return fieldNames.get(pos); } }, true, relBuilder); }
protected DrillRel addRenamedProject(DrillRel rel, RelDataType validatedRowType) { RelDataType t = rel.getRowType(); RexBuilder b = rel.getCluster().getRexBuilder(); List<RexNode> projections = Lists.newArrayList(); int projectCount = t.getFieldList().size(); for (int i = 0; i < projectCount; i++) { projections.add(b.makeInputRef(rel, i)); } final List<String> fieldNames2 = SqlValidatorUtil.uniquify(validatedRowType.getFieldNames(), SqlValidatorUtil.F_SUGGESTER2); RelDataType newRowType = RexUtil.createStructType(rel.getCluster().getTypeFactory(), projections, fieldNames2); DrillProjectRel topProj = DrillProjectRel.create(rel.getCluster(), rel.getTraitSet(), rel, projections, newRowType); // Add a final non-trivial Project to get the validatedRowType, if child is not project. if (rel instanceof Project && DrillRelOptUtil.isTrivialProject(topProj, true)) { return rel; } else { return topProj; } }
public RelDataType toSql(RelDataType type) { if (type instanceof RelRecordType) { return createStructType( Lists.transform( type.getFieldList(), new Function<RelDataTypeField, RelDataType>() { public RelDataType apply(RelDataTypeField a0) { return toSql(a0.getType()); } }), type.getFieldNames()); } if (type instanceof JavaType) { return createTypeWithNullability(createSqlType(type.getSqlTypeName()), type.isNullable()); } return type; }
private SyntheticRecordType(RelDataType relType, String name) { this.relType = relType; this.name = name; assert relType == null || Util.isDistinct(relType.getFieldNames()) : "field names not distinct: " + relType; }