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