Exemple #1
0
 /**
  * Creates a RexBuilder.
  *
  * @param typeFactory Type factory
  */
 public RexBuilder(RelDataTypeFactory typeFactory) {
   this.typeFactory = typeFactory;
   this.booleanTrue =
       makeLiteral(
           Boolean.TRUE, typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
   this.booleanFalse =
       makeLiteral(
           Boolean.FALSE, typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
   this.charEmpty =
       makeLiteral(
           new NlsString("", null, null),
           typeFactory.createSqlType(SqlTypeName.CHAR, 0),
           SqlTypeName.CHAR);
   this.constantNull =
       makeLiteral(null, typeFactory.createSqlType(SqlTypeName.NULL), SqlTypeName.NULL);
 }
Exemple #2
0
 /** Creates a Timestamp literal. */
 public RexLiteral makeTimestampLiteral(Calendar timestamp, int precision) {
   assert timestamp != null;
   return makeLiteral(
       timestamp,
       typeFactory.createSqlType(SqlTypeName.TIMESTAMP, precision),
       SqlTypeName.TIMESTAMP);
 }
Exemple #3
0
 /** Creates a double-precision literal. */
 public RexLiteral makeApproxLiteral(BigDecimal bd) {
   // Validator should catch if underflow is allowed
   // If underflow is allowed, let underflow become zero
   if (bd.doubleValue() == 0) {
     bd = BigDecimal.ZERO;
   }
   return makeApproxLiteral(bd, typeFactory.createSqlType(SqlTypeName.DOUBLE));
 }
Exemple #4
0
 /** Creates a numeric literal. */
 public RexLiteral makeExactLiteral(BigDecimal bd) {
   RelDataType relType;
   int scale = bd.scale();
   long l = bd.unscaledValue().longValue();
   assert scale >= 0;
   assert scale <= typeFactory.getTypeSystem().getMaxNumericScale() : scale;
   assert BigDecimal.valueOf(l, scale).equals(bd);
   if (scale == 0) {
     if ((l >= Integer.MIN_VALUE) && (l <= Integer.MAX_VALUE)) {
       relType = typeFactory.createSqlType(SqlTypeName.INTEGER);
     } else {
       relType = typeFactory.createSqlType(SqlTypeName.BIGINT);
     }
   } else {
     int precision = bd.unscaledValue().toString().length();
     relType = typeFactory.createSqlType(SqlTypeName.DECIMAL, scale, precision);
   }
   return makeExactLiteral(bd, relType);
 }
Exemple #5
0
  public RelDataType createSqlType(RelDataTypeFactory typeFactory) {
    BitString bitString;
    switch (typeName) {
      case NULL:
      case BOOLEAN:
        RelDataType ret = typeFactory.createSqlType(typeName);
        ret = typeFactory.createTypeWithNullability(ret, null == value);
        return ret;
      case BINARY:
        bitString = (BitString) value;
        int bitCount = bitString.getBitCount();
        return typeFactory.createSqlType(SqlTypeName.BINARY, bitCount / 8);
      case CHAR:
        NlsString string = (NlsString) value;
        Charset charset = string.getCharset();
        if (null == charset) {
          charset = typeFactory.getDefaultCharset();
        }
        SqlCollation collation = string.getCollation();
        if (null == collation) {
          collation = SqlCollation.COERCIBLE;
        }
        RelDataType type = typeFactory.createSqlType(SqlTypeName.CHAR, string.getValue().length());
        type = typeFactory.createTypeWithCharsetAndCollation(type, charset, collation);
        return type;

      case INTERVAL_YEAR_MONTH:
      case INTERVAL_DAY_TIME:
        SqlIntervalLiteral.IntervalValue intervalValue = (SqlIntervalLiteral.IntervalValue) value;
        return typeFactory.createSqlIntervalType(intervalValue.getIntervalQualifier());

      case SYMBOL:
        return typeFactory.createSqlType(SqlTypeName.SYMBOL);

      case INTEGER: // handled in derived class
      case TIME: // handled in derived class
      case VARCHAR: // should never happen
      case VARBINARY: // should never happen

      default:
        throw Util.needToImplement(toString() + ", operand=" + value);
    }
  }
Exemple #6
0
 /**
  * Creates a character string literal with type CHAR and default charset and collation.
  *
  * @param s String value
  * @return Character string literal
  */
 protected RexLiteral makePreciseStringLiteral(String s) {
   assert s != null;
   if (s.equals("")) {
     return charEmpty;
   } else {
     return makeLiteral(
         new NlsString(s, null, null),
         typeFactory.createSqlType(SqlTypeName.CHAR, s.length()),
         SqlTypeName.CHAR);
   }
 }
    @Override
    public AggregateCall other(RelDataTypeFactory typeFactory, AggregateCall e) {

      return AggregateCall.create(
          new HiveSqlCountAggFunction(
              isDistinct, returnTypeInference, operandTypeInference, operandTypeChecker),
          false,
          ImmutableIntList.of(),
          -1,
          typeFactory.createTypeWithNullability(
              typeFactory.createSqlType(SqlTypeName.BIGINT), true),
          "count");
    }
Exemple #8
0
 private RelDataType guessType(Object value) {
   if (value == null) {
     return typeFactory.createSqlType(SqlTypeName.NULL);
   }
   if (value instanceof Float || value instanceof Double) {
     return typeFactory.createSqlType(SqlTypeName.DOUBLE);
   }
   if (value instanceof Number) {
     return typeFactory.createSqlType(SqlTypeName.BIGINT);
   }
   if (value instanceof Boolean) {
     return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
   }
   if (value instanceof String) {
     return typeFactory.createSqlType(SqlTypeName.CHAR, ((String) value).length());
   }
   if (value instanceof ByteString) {
     return typeFactory.createSqlType(SqlTypeName.BINARY, ((ByteString) value).length());
   }
   throw new AssertionError("unknown type " + value.getClass());
 }
Exemple #9
0
 /** Creates a Time literal. */
 public RexLiteral makeTimeLiteral(Calendar time, int precision) {
   assert time != null;
   return makeLiteral(
       time, typeFactory.createSqlType(SqlTypeName.TIME, precision), SqlTypeName.TIME);
 }
Exemple #10
0
 /** Creates a Date literal. */
 public RexLiteral makeDateLiteral(Calendar date) {
   assert date != null;
   return makeLiteral(date, typeFactory.createSqlType(SqlTypeName.DATE), SqlTypeName.DATE);
 }
Exemple #11
0
 /** Creates a byte array literal. */
 public RexLiteral makeBinaryLiteral(ByteString byteString) {
   return makeLiteral(
       byteString,
       typeFactory.createSqlType(SqlTypeName.BINARY, byteString.length()),
       SqlTypeName.BINARY);
 }
Exemple #12
0
 /**
  * Creates a literal representing a flag.
  *
  * @param flag Flag value
  */
 public RexLiteral makeFlag(Enum flag) {
   assert flag != null;
   return makeLiteral(flag, typeFactory.createSqlType(SqlTypeName.SYMBOL), SqlTypeName.SYMBOL);
 }
Exemple #13
0
 /**
  * Retrieves an interval or decimal node's integer representation
  *
  * @param node the interval or decimal value as an opaque type
  * @return an integer representation of the decimal value
  */
 public RexNode decodeIntervalOrDecimal(RexNode node) {
   assert SqlTypeUtil.isDecimal(node.getType()) || SqlTypeUtil.isInterval(node.getType());
   RelDataType bigintType = typeFactory.createSqlType(SqlTypeName.BIGINT);
   return makeReinterpretCast(matchNullability(bigintType, node), node, makeLiteral(false));
 }
Exemple #14
0
 /**
  * Casts a decimal's integer representation to a decimal node. If the expression is not the
  * expected integer type, then it is casted first.
  *
  * <p>An overflow check may be requested to ensure the internal value does not exceed the maximum
  * value of the decimal type.
  *
  * @param value integer representation of decimal
  * @param type type integer will be reinterpreted as
  * @param checkOverflow indicates whether an overflow check is required when reinterpreting this
  *     particular value as the decimal type. A check usually not required for arithmetic, but is
  *     often required for rounding and explicit casts.
  * @return the integer reinterpreted as an opaque decimal type
  */
 public RexNode encodeIntervalOrDecimal(RexNode value, RelDataType type, boolean checkOverflow) {
   RelDataType bigintType = typeFactory.createSqlType(SqlTypeName.BIGINT);
   RexNode cast = ensureType(bigintType, value, true);
   return makeReinterpretCast(type, cast, makeLiteral(checkOverflow));
 }
Exemple #15
0
 /**
  * Creates a literal whose value is NULL, with a particular type.
  *
  * <p>The typing is necessary because RexNodes are strictly typed. For example, in the Rex world
  * the <code>NULL</code> parameter to <code>
  * SUBSTRING(NULL FROM 2 FOR 4)</code> must have a valid VARCHAR type so that the result type can
  * be determined.
  *
  * @param typeName Type to cast NULL to
  * @return NULL literal of given type
  */
 public RexNode makeNullLiteral(SqlTypeName typeName) {
   RelDataType type =
       typeFactory.createTypeWithNullability(typeFactory.createSqlType(typeName), true);
   return makeCast(type, constantNull());
 }
Exemple #16
0
 /** Creates a BIGINT literal. */
 public RexLiteral makeBigintLiteral(BigDecimal bd) {
   RelDataType bigintType = typeFactory.createSqlType(SqlTypeName.BIGINT);
   return makeLiteral(bd, bigintType, SqlTypeName.DECIMAL);
 }
  @Override
  public Prel visitProject(ProjectPrel project, Object unused) throws RelConversionException {

    // Apply the rule to the child
    RelNode originalInput = ((Prel) project.getInput(0)).accept(this, null);
    project = (ProjectPrel) project.copy(project.getTraitSet(), Lists.newArrayList(originalInput));

    List<RexNode> exprList = new ArrayList<>();

    List<RelDataTypeField> relDataTypes = new ArrayList();
    List<RelDataTypeField> origRelDataTypes = new ArrayList();
    int i = 0;
    final int lastColumnReferenced = PrelUtil.getLastUsedColumnReference(project.getProjects());

    if (lastColumnReferenced == -1) {
      return project;
    }

    final int lastRexInput = lastColumnReferenced + 1;
    RexVisitorComplexExprSplitter exprSplitter =
        new RexVisitorComplexExprSplitter(factory, funcReg, lastRexInput);

    for (RexNode rex : project.getChildExps()) {
      origRelDataTypes.add(project.getRowType().getFieldList().get(i));
      i++;
      exprList.add(rex.accept(exprSplitter));
    }
    List<RexNode> complexExprs = exprSplitter.getComplexExprs();

    if (complexExprs.size() == 1 && findTopComplexFunc(project.getChildExps()).size() == 1) {
      return project;
    }

    ProjectPrel childProject;

    List<RexNode> allExprs = new ArrayList();
    int exprIndex = 0;
    List<String> fieldNames = originalInput.getRowType().getFieldNames();
    for (int index = 0; index < lastRexInput; index++) {
      RexBuilder builder = new RexBuilder(factory);
      allExprs.add(
          builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));

      if (fieldNames.get(index).contains(StarColumnHelper.STAR_COLUMN)) {
        relDataTypes.add(
            new RelDataTypeFieldImpl(
                fieldNames.get(index), allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
      } else {
        relDataTypes.add(
            new RelDataTypeFieldImpl(
                "EXPR$" + exprIndex, allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
        exprIndex++;
      }
    }
    RexNode currRexNode;
    int index = lastRexInput - 1;

    // if the projection expressions contained complex outputs, split them into their own individual
    // projects
    if (complexExprs.size() > 0) {
      while (complexExprs.size() > 0) {
        if (index >= lastRexInput) {
          allExprs.remove(allExprs.size() - 1);
          RexBuilder builder = new RexBuilder(factory);
          allExprs.add(
              builder.makeInputRef(
                  new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));
        }
        index++;
        exprIndex++;

        currRexNode = complexExprs.remove(0);
        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;
      }
      // copied from above, find a better way to do this
      allExprs.remove(allExprs.size() - 1);
      RexBuilder builder = new RexBuilder(factory);
      allExprs.add(
          builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));
      relDataTypes.add(
          new RelDataTypeFieldImpl(
              "EXPR$" + index, allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
    }
    return (Prel)
        project.copy(
            project.getTraitSet(), originalInput, exprList, new RelRecordType(origRelDataTypes));
  }