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;
}