mihaibudiu commented on code in PR #4353:
URL: https://github.com/apache/calcite/pull/4353#discussion_r2069886810
##########
core/src/main/java/org/apache/calcite/sql/SqlOperator.java:
##########
@@ -114,10 +114,10 @@ public abstract class SqlOperator {
private final int rightPrec;
/** Used to infer the return type of a call to this operator. */
- private final @Nullable SqlReturnTypeInference returnTypeInference;
+ protected final @Nullable SqlReturnTypeInference returnTypeInference;
Review Comment:
why is this change needed?
There are get functions to access these fields.
##########
core/src/main/java/org/apache/calcite/sql/fun/SqlCoalesceFunction.java:
##########
@@ -80,4 +94,52 @@ public SqlCoalesceFunction() {
assert call.getFunctionQuantifier() == null;
return SqlCase.createSwitched(pos, null, whenList, thenList, elseExpr);
}
+
+ @Override @NonNull public RelDataType inferReturnType(
+ SqlOperatorBinding opBinding) {
+ if (returnTypeInference == null) {
+ throw Util.needToImplement(this);
+ }
+
+ RelDataType returnType = returnTypeInference.inferReturnType(opBinding);
+ if (returnType == null
+ && opBinding instanceof SqlCallBinding
+ && ((SqlCallBinding) opBinding).isTypeCoercionEnabled()) {
+ SqlCallBinding callBinding = (SqlCallBinding) opBinding;
+ List<RelDataType> argTypes = new ArrayList<>();
+ for (SqlNode operand : callBinding.operands()) {
+ RelDataType type = SqlTypeUtil.deriveType(callBinding, operand);
+ argTypes.add(type);
+ }
+ TypeCoercion typeCoercion = callBinding.getValidator().getTypeCoercion();
+ RelDataType commonType = typeCoercion.getWiderTypeFor(argTypes, true);
+ if (null != commonType) {
+ boolean coerced = typeCoercion.caseWhenCoercion(callBinding);
+ if (coerced) {
+ return SqlTypeUtil.deriveType(callBinding);
+ }
+ }
+ throw callBinding.newValidationError(RESOURCE.illegalMixingOfTypes());
+ }
+
+ if (returnType == null) {
+ throw new IllegalArgumentException(
+ "Cannot infer return type for " + opBinding.getOperator() + ";
operand types: "
+ + opBinding.collectOperandTypes());
+ }
+
+ if (operandTypeInference != null && opBinding instanceof SqlCallBinding) {
+ final SqlCallBinding callBinding = (SqlCallBinding) opBinding;
+ final List<RelDataType> operandTypes = opBinding.collectOperandTypes();
+ if (operandTypes.stream().anyMatch(t -> t.getSqlTypeName() ==
SqlTypeName.ANY)) {
+ final RelDataType[] operandTypes2 = operandTypes.toArray(new
RelDataType[0]);
+ operandTypeInference.inferOperandTypes(callBinding, returnType,
operandTypes2);
+ ((SqlValidatorImpl) callBinding.getValidator())
+ .callToOperandTypesMap
+ .put(callBinding.getCall(), ImmutableList.copyOf(operandTypes2));
Review Comment:
I am not sure that inferReturnType is allowed to change the callBinding.
This leads to bugs such https://issues.apache.org/jira/browse/CALCITE-6743
The change to the callBinding has to be done in inferOperandTypes.
--
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]