예제 #1
0
 /**
  * Creates a call to the CAST operator, expanding if possible.
  *
  * @param type Type to cast to
  * @param exp Expression being cast
  * @return Call to CAST operator
  */
 public RexNode makeCast(RelDataType type, RexNode exp) {
   final SqlTypeName sqlType = type.getSqlTypeName();
   if (exp instanceof RexLiteral) {
     RexLiteral literal = (RexLiteral) exp;
     Comparable value = literal.getValue();
     if (RexLiteral.valueMatchesType(value, sqlType, false)
         && (!(value instanceof NlsString)
             || (type.getPrecision() >= ((NlsString) value).getValue().length()))
         && (!(value instanceof ByteString)
             || (type.getPrecision() >= ((ByteString) value).length()))) {
       switch (literal.getTypeName()) {
         case CHAR:
           if (value instanceof NlsString) {
             value = ((NlsString) value).rtrim();
           }
           break;
         case TIMESTAMP:
         case TIME:
           final Calendar calendar = (Calendar) value;
           int scale = type.getScale();
           if (scale == RelDataType.SCALE_NOT_SPECIFIED) {
             scale = 0;
           }
           calendar.setTimeInMillis(
               SqlFunctions.round(
                   calendar.getTimeInMillis(), DateTimeUtils.powerX(10, 3 - scale)));
           break;
         case INTERVAL_DAY_TIME:
           BigDecimal value2 = (BigDecimal) value;
           final long multiplier =
               literal.getType().getIntervalQualifier().getStartUnit().multiplier;
           SqlTypeName typeName = type.getSqlTypeName();
           // Not all types are allowed for literals
           switch (typeName) {
             case INTEGER:
               typeName = SqlTypeName.BIGINT;
           }
           return makeLiteral(
               value2.divide(BigDecimal.valueOf(multiplier), 0, BigDecimal.ROUND_HALF_DOWN),
               type,
               typeName);
       }
       return makeLiteral(value, type, literal.getTypeName());
     }
   } else if (SqlTypeUtil.isInterval(type) && SqlTypeUtil.isExactNumeric(exp.getType())) {
     return makeCastExactToInterval(type, exp);
   } else if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.isInterval(exp.getType())) {
     return makeCastIntervalToExact(type, exp);
   } else if (sqlType == SqlTypeName.BOOLEAN && SqlTypeUtil.isExactNumeric(exp.getType())) {
     return makeCastExactToBoolean(type, exp);
   } else if (exp.getType().getSqlTypeName() == SqlTypeName.BOOLEAN
       && SqlTypeUtil.isExactNumeric(type)) {
     return makeCastBooleanToExact(type, exp);
   }
   return makeAbstractCast(type, exp);
 }
예제 #2
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));
 }