gianm commented on code in PR #12968:
URL: https://github.com/apache/druid/pull/12968#discussion_r955620788
##########
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:
It doesn't need to block this PR. I'd encourage it as a follow up.
Btw, the "expect the default parameters" thing is what I was imagining. That
way, if someone explicitly specifies the default, it still works fine. But if
they try to use a different option, they get an error.
--
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]