public RexNode makeCast()

in core/src/main/java/org/apache/calcite/rex/RexBuilder.java [767:855]


  public RexNode makeCast(
      SqlParserPos pos,
      RelDataType type,
      RexNode exp,
      boolean matchNullability,
      boolean safe,
      RexLiteral format) {
    final SqlTypeName sqlType = type.getSqlTypeName();
    if (exp instanceof RexLiteral) {
      RexLiteral literal = (RexLiteral) exp;
      Comparable value = literal.getValueAs(Comparable.class);
      SqlTypeName typeName = literal.getTypeName();

      // Allow casting boolean literals to integer types.
      if (exp.getType().getSqlTypeName() == SqlTypeName.BOOLEAN
          && SqlTypeUtil.isExactNumeric(type)) {
        return makeCastBooleanToExact(type, exp);
      }
      if (canRemoveCastFromLiteral(type, value, typeName)) {
        switch (typeName) {
        case INTERVAL_YEAR:
        case INTERVAL_YEAR_MONTH:
        case INTERVAL_MONTH:
        case INTERVAL_DAY:
        case INTERVAL_DAY_HOUR:
        case INTERVAL_DAY_MINUTE:
        case INTERVAL_DAY_SECOND:
        case INTERVAL_HOUR:
        case INTERVAL_HOUR_MINUTE:
        case INTERVAL_HOUR_SECOND:
        case INTERVAL_MINUTE:
        case INTERVAL_MINUTE_SECOND:
        case INTERVAL_SECOND:
          assert value instanceof BigDecimal;
          typeName = type.getSqlTypeName();
          switch (typeName) {
          case BIGINT:
          case INTEGER:
          case SMALLINT:
          case TINYINT:
          case DOUBLE:
          case FLOAT:
          case REAL:
          case DECIMAL:
            BigDecimal value2 = (BigDecimal) value;
            final BigDecimal multiplier =
                baseUnit(literal.getTypeName()).multiplier;
            final BigDecimal divider =
                literal.getTypeName().getEndUnit().multiplier;
            value = value2.multiply(multiplier)
                .divide(divider, 0, RoundingMode.HALF_DOWN);
            break;
          default:
            break;
          }

          // Not all types are allowed for literals
          switch (typeName) {
          case INTEGER:
            typeName = SqlTypeName.BIGINT;
            break;
          default:
            break;
          }
          break;
        default:
          break;
        }
        final RexLiteral literal2 =
            makeLiteral(value, type, typeName);
        if (type.isNullable()
            && !literal2.getType().isNullable()
            && matchNullability) {
          return makeAbstractCast(pos, type, literal2, safe, format);
        }
        return literal2;
      }
    } else if (SqlTypeUtil.isExactNumeric(type)
        && SqlTypeUtil.isInterval(exp.getType())) {
      return makeCastIntervalToExact(pos, 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(pos, type, exp, safe, format);
  }