/**
  * 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;
 }
Exemple #2
0
  /**
   * 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;
 }