mihaibudiu commented on code in PR #4353:
URL: https://github.com/apache/calcite/pull/4353#discussion_r2072480416
##########
core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java:
##########
@@ -422,6 +439,34 @@ protected boolean booleanEquality(SqlCallBinding binding,
return false;
}
+ /**
+ * COALESCE type coercion, collect all the branches types to find a common
type,
+ * then cast the operands to the common type when needed.
+ */
+ private boolean coalesceCoercion(SqlCallBinding callBinding) {
+ List<RelDataType> argTypes = new ArrayList<>();
+ SqlValidatorScope scope = getScope(callBinding);
+ for (SqlNode node : callBinding.operands()) {
+ argTypes.add(validator.deriveType(scope, node));
+ }
+ RelDataType widerType = getWiderTypeFor(argTypes, true);
+ if (null != widerType) {
+ return coerceOperandsType(scope, callBinding.getCall(), widerType);
+ }
+ return false;
+ }
+
+ /**
+ * NULLIF type coercion, cast the second operand type to the first operand
type when needed.
Review Comment:
Are you sure this is right?
When you translate this to a CASE statement the wider type will be used by
coercion.
You have to preserve this behavior.
##########
core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java:
##########
@@ -383,11 +383,28 @@ protected boolean booleanEquality(SqlCallBinding binding,
}
/**
- * CASE and COALESCE type coercion, collect all the branches types including
then
- * operands and else operands to find a common type, then cast the operands
to the common type
- * when needed.
+ * Coerces CASE WHEN, COALESCE and NULLIF statement branches to a unified
type.
+ *
+ * @deprecated Use {@link #caseOrEquivalentCoercion} instead.
+ */
+ @Deprecated @Override public boolean caseWhenCoercion(SqlCallBinding
callBinding) {
+ return caseOrEquivalentCoercion(callBinding);
+ }
+
+ /**
+ * Coerces CASE WHEN, COALESCE and NULLIF statement branches to a unified
type.
*/
- @Override public boolean caseWhenCoercion(SqlCallBinding callBinding) {
+ @Override public boolean caseOrEquivalentCoercion(SqlCallBinding
callBinding) {
+ if (callBinding.getCall().getKind() == SqlKind.COALESCE) {
+ // For sql statement like: `coalesce(a, b, c)`
+ return coalesceCoercion(callBinding);
+ }
+
+ if (callBinding.getCall().getKind() == SqlKind.NULLIF) {
+ // For sql statement like: `nullif(a, b)`
+ return nullifCoercion(callBinding);
+ }
+
Review Comment:
can you also add an assertion here that the remaining call is CASE?
##########
core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java:
##########
@@ -382,12 +383,22 @@ protected boolean booleanEquality(SqlCallBinding binding,
return false;
}
+ @Deprecated @Override public boolean caseWhenCoercion(SqlCallBinding
callBinding) {
+ return caseOrEquivalentCoercion(callBinding);
Review Comment:
I don't think we promise to preserve the original functionality for
deprecated methods, just their signature.
But there is an argument to be made for preserving the original
functionality too.
##########
core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java:
##########
@@ -383,11 +383,28 @@ protected boolean booleanEquality(SqlCallBinding binding,
}
/**
- * CASE and COALESCE type coercion, collect all the branches types including
then
- * operands and else operands to find a common type, then cast the operands
to the common type
- * when needed.
+ * Coerces CASE WHEN, COALESCE and NULLIF statement branches to a unified
type.
+ *
+ * @deprecated Use {@link #caseOrEquivalentCoercion} instead.
+ */
+ @Deprecated @Override public boolean caseWhenCoercion(SqlCallBinding
callBinding) {
+ return caseOrEquivalentCoercion(callBinding);
+ }
+
+ /**
+ * Coerces CASE WHEN, COALESCE and NULLIF statement branches to a unified
type.
*/
- @Override public boolean caseWhenCoercion(SqlCallBinding callBinding) {
+ @Override public boolean caseOrEquivalentCoercion(SqlCallBinding
callBinding) {
+ if (callBinding.getCall().getKind() == SqlKind.COALESCE) {
+ // For sql statement like: `coalesce(a, b, c)`
+ return coalesceCoercion(callBinding);
+ }
+
+ if (callBinding.getCall().getKind() == SqlKind.NULLIF) {
+ // For sql statement like: `nullif(a, b)`
+ return nullifCoercion(callBinding);
+ }
+
Review Comment:
for symmetry you may also want to move this code into a separate private
function
--
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]