@@ -105,28 +105,29 @@ public RexNode makeCast(
105105 boolean safe ,
106106 RexLiteral format ) {
107107 final SqlTypeName sqlType = type .getSqlTypeName ();
108+ RelDataType sourceType = exp .getType ();
108109 // Calcite bug which doesn't consider to cast literal to boolean
109110 if (exp instanceof RexLiteral && sqlType == SqlTypeName .BOOLEAN ) {
110111 if (exp .equals (makeLiteral ("1" , typeFactory .createSqlType (SqlTypeName .CHAR , 1 )))) {
111112 return makeLiteral (true , type );
112113 } else if (exp .equals (makeLiteral ("0" , typeFactory .createSqlType (SqlTypeName .CHAR , 1 )))) {
113114 return makeLiteral (false , type );
114- } else if (SqlTypeUtil .isExactNumeric (exp . getType () )) {
115+ } else if (SqlTypeUtil .isExactNumeric (sourceType )) {
115116 return makeCall (
116117 type ,
117118 SqlStdOperatorTable .NOT_EQUALS ,
118- ImmutableList .of (exp , makeZeroLiteral (exp . getType () )));
119+ ImmutableList .of (exp , makeZeroLiteral (sourceType )));
119120 // TODO https://github.com/opensearch-project/sql/issues/3443
120121 // Current, we align the behaviour of Spark and Postgres, to align with OpenSearch V2,
121122 // enable following commented codes.
122123 // } else {
123124 // return makeCall(type,
124125 // SqlStdOperatorTable.NOT_EQUALS,
125- // ImmutableList.of(exp, makeZeroLiteral(exp.getType() )));
126+ // ImmutableList.of(exp, makeZeroLiteral(sourceType )));
126127 }
127128 } else if (OpenSearchTypeFactory .isUserDefinedType (type )) {
128129 var udt = ((AbstractExprRelDataType <?>) type ).getUdt ();
129- var argExprType = OpenSearchTypeFactory .convertRelDataTypeToExprType (exp . getType () );
130+ var argExprType = OpenSearchTypeFactory .convertRelDataTypeToExprType (sourceType );
130131 return switch (udt ) {
131132 case EXPR_DATE -> makeCall (type , PPLBuiltinOperators .DATE , List .of (exp ));
132133 case EXPR_TIME -> makeCall (type , PPLBuiltinOperators .TIME , List .of (exp ));
@@ -150,9 +151,10 @@ public RexNode makeCast(
150151 String .format (Locale .ROOT , "Cannot cast from %s to %s" , argExprType , udt .name ()));
151152 };
152153 }
153- // Use a custom operator when casting an approximate numeric (e.g. double) to a character type.
154- // This patch is necessary because Calcite's built-in CAST converts 0.0 to 0E0 as string.
155- else if (SqlTypeUtil .isApproximateNumeric (exp .getType ()) && SqlTypeUtil .isCharacter (type )) {
154+ // Use a custom operator when casting floating point or decimal number to a character type.
155+ // This patch is necessary because in Calcite, 0.0F is cast to 0E0, decimal 0.x to x
156+ else if ((SqlTypeUtil .isApproximateNumeric (sourceType ) || SqlTypeUtil .isDecimal (sourceType ))
157+ && SqlTypeUtil .isCharacter (type )) {
156158 // NUMBER_TO_STRING uses java's built-in method to get the string representation of a number
157159 return makeCall (type , PPLBuiltinOperators .NUMBER_TO_STRING , List .of (exp ));
158160 }
0 commit comments