clintropolis commented on code in PR #12968:
URL: https://github.com/apache/druid/pull/12968#discussion_r956462642


##########
sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/NestedDataOperatorConversions.java:
##########
@@ -395,24 +465,182 @@ public DruidExpression toDruidExpression(
             )
         );
       }
-      return DruidExpression.ofExpression(ColumnType.STRING, builder, 
druidExpressions);
+      return DruidExpression.ofExpression(druidType, builder, 
druidExpressions);
+    }
+
+    static SqlFunction buildFunction(String functionName, SqlTypeName typeName)
+    {
+      return OperatorConversions.operatorBuilder(functionName)
+                                .operandTypeChecker(
+                                    OperandTypes.sequence(
+                                        "(expr,path)",
+                                        OperandTypes.family(SqlTypeFamily.ANY),
+                                        
OperandTypes.family(SqlTypeFamily.STRING)
+                                    )
+                                )
+                                .returnTypeInference(
+                                    ReturnTypes.cascade(
+                                        opBinding -> 
opBinding.getTypeFactory().createSqlType(typeName),
+                                        SqlTypeTransforms.FORCE_NULLABLE
+                                    )
+                                )
+                                
.functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
+                                .build();
+    }
+  }
+
+  public static class JsonValueBigintOperatorConversion extends 
JsonValueReturningTypeOperatorConversion
+  {
+    private static final SqlFunction FUNCTION = 
buildFunction("JSON_VALUE_BIGINT", SqlTypeName.BIGINT);
+
+    public JsonValueBigintOperatorConversion()
+    {
+      super(FUNCTION, ColumnType.LONG);
+    }
+  }
+
+  public static class JsonValueDoubleOperatorConversion extends 
JsonValueReturningTypeOperatorConversion
+  {
+    private static final SqlFunction FUNCTION = 
buildFunction("JSON_VALUE_DOUBLE", SqlTypeName.DOUBLE);
+
+    public JsonValueDoubleOperatorConversion()
+    {
+      super(FUNCTION, ColumnType.DOUBLE);
     }
   }
 
-  // calcite converts JSON_VALUE to JSON_VALUE_ANY so we have to wire that up 
too...
-  public static class JsonValueAnyOperatorConversion extends 
AliasedOperatorConversion
+  public static class JsonValueStringOperatorConversion extends 
JsonValueReturningTypeOperatorConversion
   {
-    private static final String FUNCTION_NAME = 
StringUtils.toUpperCase("json_value_any");
+    private static final SqlFunction FUNCTION = 
buildFunction("JSON_VALUE_VARCHAR", SqlTypeName.VARCHAR);
 
-    public JsonValueAnyOperatorConversion()
+    public JsonValueStringOperatorConversion()
     {
-      super(new JsonValueOperatorConversion(), FUNCTION_NAME);
+      super(FUNCTION, ColumnType.STRING);
     }
+  }
+
+  /**
+   * Calcites {@link org.apache.calcite.sql2rel.StandardConvertletTable} 
translates JSON_VALUE
+   */
+  public static class JsonValueAnyOperatorConversion implements 
SqlOperatorConversion
+  {
+    private static final SqlFunction FUNCTION =
+        OperatorConversions.operatorBuilder("JSON_VALUE_ANY")
+                           .operandTypeChecker(
+                               OperandTypes.or(
+                                   OperandTypes.sequence(
+                                       "(expr,path)",
+                                       OperandTypes.family(SqlTypeFamily.ANY),
+                                       
OperandTypes.family(SqlTypeFamily.STRING)
+                                   ),
+                                   OperandTypes.family(
+                                       SqlTypeFamily.ANY,
+                                       SqlTypeFamily.CHARACTER,
+                                       SqlTypeFamily.ANY,
+                                       SqlTypeFamily.ANY,
+                                       SqlTypeFamily.ANY,
+                                       SqlTypeFamily.ANY,
+                                       SqlTypeFamily.ANY
+                                   )
+                               )
+                           )
+                           .operandTypeInference((callBinding, returnType, 
operandTypes) -> {
+                             RelDataTypeFactory typeFactory = 
callBinding.getTypeFactory();
+                             if (operandTypes.length > 5) {
+                               operandTypes[3] = 
typeFactory.createSqlType(SqlTypeName.ANY);
+                               operandTypes[5] = 
typeFactory.createSqlType(SqlTypeName.ANY);
+                             }
+                           })
+                           .returnTypeInference(
+                               ReturnTypes.cascade(
+                                   opBinding -> 
opBinding.getTypeFactory().createTypeWithNullability(
+                                       // STRING is the closest thing we have 
to an ANY type
+                                       // however, this should really be using 
SqlTypeName.ANY.. someday
+                                       
opBinding.getTypeFactory().createSqlType(SqlTypeName.VARCHAR),
+                                       true
+                                   ),
+                                   SqlTypeTransforms.FORCE_NULLABLE
+                               )
+                           )
+                           .functionCategory(SqlFunctionCategory.SYSTEM)
+                           .build();
 
     @Override
     public SqlOperator calciteOperator()
     {
-      return SqlStdOperatorTable.JSON_VALUE_ANY;
+      return FUNCTION;
+    }
+
+    @Nullable
+    @Override
+    public DruidExpression toDruidExpression(
+        PlannerContext plannerContext,
+        RowSignature rowSignature,
+        RexNode rexNode
+    )
+    {
+      final RexCall call = (RexCall) rexNode;
+
+      // calcite parser can allow for a bunch of junk in here that we don't 
care about right now, so the call looks

Review Comment:
   ended up adding checks in this PR that only the default parameters are 
allowed (which thankfully matches the behavior we have implemented)



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to