in modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/RexToLixTranslator.java [798:908]
public static Expression translateLiteral(
RexLiteral literal,
RelDataType type,
JavaTypeFactory typeFactory,
RexImpTable.NullAs nullAs) {
if (literal.isNull()) {
switch (nullAs) {
case TRUE:
case IS_NULL:
return RexImpTable.TRUE_EXPR;
case FALSE:
case IS_NOT_NULL:
return RexImpTable.FALSE_EXPR;
case NOT_POSSIBLE:
throw new ControlFlowException();
case NULL:
default:
return RexImpTable.NULL_EXPR;
}
} else {
switch (nullAs) {
case IS_NOT_NULL:
return RexImpTable.TRUE_EXPR;
case IS_NULL:
return RexImpTable.FALSE_EXPR;
default:
break;
}
}
Type javaClass = typeFactory.getJavaClass(type);
final Object value2;
switch (literal.getType().getSqlTypeName()) {
case DECIMAL:
final BigDecimal bd = literal.getValueAs(BigDecimal.class);
if (javaClass == float.class) {
return Expressions.constant(bd, javaClass);
} else if (javaClass == double.class) {
return Expressions.constant(bd, javaClass);
}
assert javaClass == BigDecimal.class;
return Expressions.call(
IgniteSqlFunctions.class,
"toBigDecimal",
/*
The ConstantExpression class, when converting from BigDecimal to Bigdecimal,
removes trailing zeros from the original object, regardless of the original scale value.
Therefore, BigDecimal must be converted to a string to avoid this.
*/
Expressions.constant(bd.toString()),
Expressions.constant(type.getPrecision()),
Expressions.constant(type.getScale())
);
case DATE:
case TIME:
case TIME_WITH_LOCAL_TIME_ZONE:
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
value2 = literal.getValueAs(Integer.class);
javaClass = int.class;
break;
case TIMESTAMP:
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
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:
value2 = literal.getValueAs(Long.class);
javaClass = long.class;
break;
case CHAR:
case VARCHAR:
value2 = literal.getValueAs(String.class);
break;
case BINARY:
case VARBINARY:
return Expressions.new_(
ByteString.class,
Expressions.constant(
literal.getValueAs(byte[].class),
byte[].class));
case GEOMETRY:
final Geometry geom =
requireNonNull(literal.getValueAs(Geometry.class),
() -> "getValueAs(Geometries.Geom) for " + literal);
final String wkt = SpatialTypeFunctions.ST_AsWKT(geom);
return Expressions.call(null, BuiltInMethod.ST_GEOM_FROM_EWKT.method,
Expressions.constant(wkt));
case SYMBOL:
value2 =
requireNonNull(literal.getValueAs(Enum.class),
() -> "getValueAs(Enum.class) for " + literal);
javaClass = value2.getClass();
break;
default:
final Primitive primitive = Primitive.ofBoxOr(javaClass);
final Comparable value = literal.getValueAs(Comparable.class);
if (primitive != null && value instanceof Number) {
value2 = primitive.number((Number) value);
} else {
value2 = value;
}
}
return Expressions.constant(value2, javaClass);
}