boolean canRemoveCastFromLiteral()

in core/src/main/java/org/apache/calcite/rex/RexBuilder.java [868:939]


  boolean canRemoveCastFromLiteral(RelDataType toType,
      @SuppressWarnings("rawtypes") @Nullable Comparable value,
      SqlTypeName fromTypeName) {
    if (value == null) {
      return true;
    }
    final SqlTypeName sqlType = toType.getSqlTypeName();
    if (sqlType == SqlTypeName.MEASURE
        || sqlType == SqlTypeName.VARIANT
        || sqlType == SqlTypeName.UUID) {
      return false;
    }
    if (!RexLiteral.valueMatchesType(value, sqlType, false)) {
      return false;
    }
    if (toType.getSqlTypeName() != fromTypeName
        && (SqlTypeFamily.DATETIME.getTypeNames().contains(fromTypeName)
        || SqlTypeFamily.INTERVAL_DAY_TIME.getTypeNames().contains(fromTypeName)
        || SqlTypeFamily.INTERVAL_YEAR_MONTH.getTypeNames().contains(fromTypeName))) {
      return false;
    }
    if (value instanceof NlsString) {
      final int length = ((NlsString) value).getValue().length();
      switch (toType.getSqlTypeName()) {
      case CHAR:
        return SqlTypeUtil.comparePrecision(toType.getPrecision(), length) == 0;
      case VARCHAR:
        return SqlTypeUtil.comparePrecision(toType.getPrecision(), length) >= 0;
      default:
        throw new AssertionError(toType);
      }
    }
    if (value instanceof ByteString) {
      final int length = ((ByteString) value).length();
      switch (toType.getSqlTypeName()) {
      case BINARY:
        return SqlTypeUtil.comparePrecision(toType.getPrecision(), length) == 0;
      case VARBINARY:
        return SqlTypeUtil.comparePrecision(toType.getPrecision(), length) >= 0;
      default:
        throw new AssertionError(toType);
      }
    }

    if (toType.getSqlTypeName() == SqlTypeName.DECIMAL
        && fromTypeName.getFamily() == SqlTypeFamily.NUMERIC) {
      final BigDecimal decimalValue = (BigDecimal) value;
      return SqlTypeUtil.canBeRepresentedExactly(decimalValue, toType);
    }

    if (SqlTypeName.INT_TYPES.contains(sqlType)) {
      final BigDecimal decimalValue = (BigDecimal) value;
      try {
        // Will throw ArithmeticException if the value cannot be represented using a 'long'
        long l = decimalValue.longValueExact();
        switch (sqlType) {
        case TINYINT:
          return l >= Byte.MIN_VALUE && l <= Byte.MAX_VALUE;
        case SMALLINT:
          return l >= Short.MIN_VALUE && l <= Short.MAX_VALUE;
        case INTEGER:
          return l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE;
        case BIGINT:
        default:
          return true;
        }
      } catch (ArithmeticException ex) {
        return false;
      }
    }
    return true;
  }