mihaibudiu commented on code in PR #5276:
URL: https://github.com/apache/calcite/pull/5276#discussion_r4067496953


##########
core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java:
##########
@@ -3364,6 +3364,40 @@ static Expression call(Method method, @Nullable 
Expression target,
     }
   }
 
+  /** Base class for the implementors of {@code JSON_VALUE} and
+   * {@code JSON_QUERY}. */
+  private abstract static class JsonImplementor extends MethodImplementor {
+    JsonImplementor(Method method) {
+      super(method, NullPolicy.ARG0, false);
+    }
+
+    /** Calls the runtime method with {@code operands}, followed by the

Review Comment:
   A concrete example of equivalent Java code generated would be easier to read 
than this description.



##########
core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java:
##########
@@ -243,34 +245,54 @@ public JsonPathContext 
jsonApiCommonSyntaxWithCache(String input,
         SqlJsonValueEmptyOrErrorBehavior emptyBehavior,
         Object defaultValueOnEmpty,
         SqlJsonValueEmptyOrErrorBehavior errorBehavior,
-        Object defaultValueOnError) {
+        Object defaultValueOnError,
+        SqlTypeName returningType,

Review Comment:
   These 3 (or even 4) fields seem to be a low-level representation of a 
RelDataType value.
   It's true that this layer should not depend on types from Rel, but maybe an 
abstraction packaging them together could be useful.



##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -5636,6 +5637,194 @@ public static BigDecimal toBigDecimal(Object o) {
         : toBigDecimal(o.toString());
   }
 
+  /** Converts a value to the SQL type {@code typeName}, as {@code CAST}
+   * does, when the type of the value is not known until run time.
+   *
+   * <p>Throws if the value cannot be converted, and for a target type that
+   * this method does not handle, so that a caller such as
+   * {@code JSON_VALUE} can apply its {@code ON ERROR} clause.
+   *
+   * @param value        Value to convert
+   * @param typeName     Type to convert it to; {@link SqlTypeName#ANY}
+   *                     returns the value unchanged
+   * @param precision    Precision of the target type, or negative
+   * @param scale        Scale of the target type, or negative
+   * @param roundingMode Rounding mode of the type system
+   */
+  static @Nullable Object cast(@Nullable Object value,
+      SqlTypeName typeName, int precision, int scale,
+      RoundingMode roundingMode) {

Review Comment:
   I am curious how you decide the roundingMode



##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -5636,6 +5637,194 @@ public static BigDecimal toBigDecimal(Object o) {
         : toBigDecimal(o.toString());
   }
 
+  /** Converts a value to the SQL type {@code typeName}, as {@code CAST}
+   * does, when the type of the value is not known until run time.
+   *
+   * <p>Throws if the value cannot be converted, and for a target type that
+   * this method does not handle, so that a caller such as
+   * {@code JSON_VALUE} can apply its {@code ON ERROR} clause.
+   *
+   * @param value        Value to convert
+   * @param typeName     Type to convert it to; {@link SqlTypeName#ANY}
+   *                     returns the value unchanged
+   * @param precision    Precision of the target type, or negative
+   * @param scale        Scale of the target type, or negative
+   * @param roundingMode Rounding mode of the type system
+   */
+  static @Nullable Object cast(@Nullable Object value,
+      SqlTypeName typeName, int precision, int scale,
+      RoundingMode roundingMode) {
+    if (value == null || typeName == SqlTypeName.ANY) {
+      return value;
+    }
+    switch (typeName) {
+    case BOOLEAN:
+      return toBoolean(value);
+    case TINYINT:
+      return castToExact(value, Primitive.BYTE, roundingMode);
+    case SMALLINT:
+      return castToExact(value, Primitive.SHORT, roundingMode);
+    case INTEGER:
+      return castToExact(value, Primitive.INT, roundingMode);
+    case BIGINT:
+      return castToExact(value, Primitive.LONG, roundingMode);
+    case REAL:
+      return toFloat(value);
+    case FLOAT:
+    case DOUBLE:
+      return toDouble(value);
+    case DECIMAL:
+      return castToDecimal(value, precision, scale, roundingMode);
+    case CHAR:
+      return precision < 0 ? value.toString()
+          : truncateOrPad(value.toString(), precision);
+    case VARCHAR:
+      return precision < 0 ? value.toString()
+          : truncate(value.toString(), precision);
+    case DATE:
+      return DateTimeUtils.dateStringToUnixDate(charValue(value, typeName));
+    case TIME:
+      return (int) truncateFraction(

Review Comment:
   why truncate and not use the roundingMode?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to