示例#1
0
 /**
  * Creates an expression accessing a given field from a record.
  *
  * @param expr Expression yielding a record
  * @param field Field
  * @return Expression accessing given field
  */
 private RexNode makeFieldAccessInternal(RexNode expr, final RelDataTypeField field) {
   if (expr instanceof RexRangeRef) {
     RexRangeRef range = (RexRangeRef) expr;
     if (field.getIndex() < 0) {
       return makeCall(
           field.getType(), GET_OPERATOR, ImmutableList.of(expr, makeLiteral(field.getName())));
     }
     return new RexInputRef(range.getOffset() + field.getIndex(), field.getType());
   }
   return new RexFieldAccess(expr, field);
 }
示例#2
0
  public static ImmutableMap<String, Integer> getRowColNameIndxMap(
      List<RelDataTypeField> rowFields) {
    Builder<String, Integer> bldr = ImmutableMap.<String, Integer>builder();

    int indx = 0;
    for (RelDataTypeField rdt : rowFields) {
      bldr.put(rdt.getName(), indx);
      indx++;
    }

    return bldr.build();
  }
 /** Creates a synthetic Java class whose fields have the same names and relational types. */
 private Type createSyntheticType(RelRecordType type) {
   final String name = "Record" + type.getFieldCount() + "_" + syntheticTypes.size();
   final SyntheticRecordType syntheticType = new SyntheticRecordType(type, name);
   for (final RelDataTypeField recordField : type.getFieldList()) {
     final Type javaClass = getJavaClass(recordField.getType());
     syntheticType.fields.add(
         new RecordFieldImpl(
             syntheticType,
             recordField.getName(),
             javaClass,
             recordField.getType().isNullable() && !Primitive.is(javaClass),
             Modifier.PUBLIC));
   }
   return register(syntheticType);
 }
示例#4
0
  private static void addFields(
      List<RelDataTypeField> fieldList,
      List<RelDataType> typeList,
      List<String> nameList,
      Set<String> uniqueNames) {
    for (RelDataTypeField field : fieldList) {
      String name = field.getName();

      // Ensure that name is unique from all previous field names
      if (uniqueNames.contains(name)) {
        String nameBase = name;
        for (int j = 0; ; j++) {
          name = nameBase + j;
          if (!uniqueNames.contains(name)) {
            break;
          }
        }
      }
      nameList.add(name);
      uniqueNames.add(name);
      typeList.add(field.getType());
    }
  }
示例#5
0
  /**
   * Push any equi join conditions that are not column references as Projections on top of the
   * children.
   *
   * @param factory Project factory to use.
   * @param inputRels inputs to a join
   * @param leftJoinKeys expressions for LHS of join key
   * @param rightJoinKeys expressions for RHS of join key
   * @param systemColCount number of system columns, usually zero. These columns are projected at
   *     the leading edge of the output row.
   * @param leftKeys on return this contains the join key positions from the new project rel on the
   *     LHS.
   * @param rightKeys on return this contains the join key positions from the new project rel on the
   *     RHS.
   * @return the join condition after the equi expressions pushed down.
   */
  public static RexNode projectNonColumnEquiConditions(
      ProjectFactory factory,
      RelNode[] inputRels,
      List<RexNode> leftJoinKeys,
      List<RexNode> rightJoinKeys,
      int systemColCount,
      List<Integer> leftKeys,
      List<Integer> rightKeys) {
    RelNode leftRel = inputRels[0];
    RelNode rightRel = inputRels[1];
    RexBuilder rexBuilder = leftRel.getCluster().getRexBuilder();
    RexNode outJoinCond = null;

    int origLeftInputSize = leftRel.getRowType().getFieldCount();
    int origRightInputSize = rightRel.getRowType().getFieldCount();

    List<RexNode> newLeftFields = new ArrayList<RexNode>();
    List<String> newLeftFieldNames = new ArrayList<String>();

    List<RexNode> newRightFields = new ArrayList<RexNode>();
    List<String> newRightFieldNames = new ArrayList<String>();
    int leftKeyCount = leftJoinKeys.size();
    int i;

    for (i = 0; i < origLeftInputSize; i++) {
      final RelDataTypeField field = leftRel.getRowType().getFieldList().get(i);
      newLeftFields.add(rexBuilder.makeInputRef(field.getType(), i));
      newLeftFieldNames.add(field.getName());
    }

    for (i = 0; i < origRightInputSize; i++) {
      final RelDataTypeField field = rightRel.getRowType().getFieldList().get(i);
      newRightFields.add(rexBuilder.makeInputRef(field.getType(), i));
      newRightFieldNames.add(field.getName());
    }

    int newKeyCount = 0;
    List<Pair<Integer, Integer>> origColEqConds = new ArrayList<Pair<Integer, Integer>>();
    for (i = 0; i < leftKeyCount; i++) {
      RexNode leftKey = leftJoinKeys.get(i);
      RexNode rightKey = rightJoinKeys.get(i);

      if (leftKey instanceof RexInputRef && rightKey instanceof RexInputRef) {
        origColEqConds.add(
            Pair.of(((RexInputRef) leftKey).getIndex(), ((RexInputRef) rightKey).getIndex()));
      } else {
        newLeftFields.add(leftKey);
        newLeftFieldNames.add(null);
        newRightFields.add(rightKey);
        newRightFieldNames.add(null);
        newKeyCount++;
      }
    }

    for (i = 0; i < origColEqConds.size(); i++) {
      Pair<Integer, Integer> p = origColEqConds.get(i);
      RexNode leftKey = leftJoinKeys.get(i);
      RexNode rightKey = rightJoinKeys.get(i);
      leftKeys.add(p.left);
      rightKeys.add(p.right);
      RexNode cond =
          rexBuilder.makeCall(
              SqlStdOperatorTable.EQUALS,
              rexBuilder.makeInputRef(leftKey.getType(), systemColCount + p.left),
              rexBuilder.makeInputRef(
                  rightKey.getType(), systemColCount + origLeftInputSize + newKeyCount + p.right));
      if (outJoinCond == null) {
        outJoinCond = cond;
      } else {
        outJoinCond = rexBuilder.makeCall(SqlStdOperatorTable.AND, outJoinCond, cond);
      }
    }

    if (newKeyCount == 0) {
      return outJoinCond;
    }

    int newLeftOffset = systemColCount + origLeftInputSize;
    int newRightOffset = systemColCount + origLeftInputSize + origRightInputSize + newKeyCount;
    for (i = 0; i < newKeyCount; i++) {
      leftKeys.add(origLeftInputSize + i);
      rightKeys.add(origRightInputSize + i);
      RexNode cond =
          rexBuilder.makeCall(
              SqlStdOperatorTable.EQUALS,
              rexBuilder.makeInputRef(
                  newLeftFields.get(origLeftInputSize + i).getType(), newLeftOffset + i),
              rexBuilder.makeInputRef(
                  newRightFields.get(origRightInputSize + i).getType(), newRightOffset + i));
      if (outJoinCond == null) {
        outJoinCond = cond;
      } else {
        outJoinCond = rexBuilder.makeCall(SqlStdOperatorTable.AND, outJoinCond, cond);
      }
    }

    // added project if need to produce new keys than the original input
    // fields
    if (newKeyCount > 0) {
      leftRel =
          factory.createProject(
              leftRel, newLeftFields, SqlValidatorUtil.uniquify(newLeftFieldNames));
      rightRel =
          factory.createProject(
              rightRel, newRightFields, SqlValidatorUtil.uniquify(newRightFieldNames));
    }

    inputRels[0] = leftRel;
    inputRels[1] = rightRel;

    return outJoinCond;
  }