[CALCITE-7437] Type coercion for quantifier operators is incomplete#4877
[CALCITE-7437] Type coercion for quantifier operators is incomplete#4877Dwrite wants to merge 7 commits intoapache:mainfrom
Conversation
|
This appears to be an AI-generated solution. We don't object to using AI to solve problems, but it's necessary to confirm that the code changes and comments meet review criteria before submission. For example, the title should be [CALCITE-7437], and the PR description should ideally follow the existing template. |
yeah. The initial draft of this description was generated with the assistance of Gemini to ensure clarity and professional phrasing, then reviewed and refined by me to accurately reflect the technical implementation. The core solution and logic were developed by myself. |
| collectionWidenType = | ||
| binding.getTypeFactory() | ||
| .enforceTypeWithNullability(collectionWidenType, type2.isNullable()); | ||
| if (coerceOperandType(scope, binding.getCall(), 1, collectionWidenType)) { |
There was a problem hiding this comment.
Can you please make sure there is test coverage for both cases (subquery and collections)?
If there are already tests, fine, but if not, please write some.
In particular, this will be tricky when the row type on the RHS contains nested collections or ROW, e.g., ROW(ROW()) or ROW(MAP<VARCHAR, INT ARRAY>>.
|



Summary
Fix RuntimeException when using SOME/ANY/ALL with mismatched types and all quantifiers should work in the same way, like IN.
The issue:
Calcite currently crashes with a RuntimeException when a quantifier operator (like SOME, ANY, or ALL) compares columns with different types—for example, a VARCHAR on the left and a SMALLINT from the subquery.
The error (SELECT deptno, dname > SOME(SELECT empno FROM emp) AS b FROM dept):
'java.lang.RuntimeException: while resolving method 'gt[class java.lang.String, short]' in c org.apache.calcite.runtime.SqlFunctions This happens because the SqlValidator doesn't trigger TypeCoercion for these operators, so no CAST is inserted. When it gets to code generation, Linq4j can't find a way to compare a raw String with a primitive short.
The fix:
I updated TypeCoercionImpl to handle these quantifier operators. Now, it follows the same implicit cast rules we use for standard comparisons or the IN operator.
Testing:
Added a case in sub-query.iq. The plan now correctly shows a CAST (e.g., CAST($1):SMALLINT) before the join condition.
Note: If the data itself is a non-numeric string (like "ACCOUNTING"), you'll still get a NumberFormatException at runtime, but this is expected behavior (similar to how CAST('A' AS INT) behaves in other engines). The fix ensures the engine can at least generate the correct execution plan instead of crashing during the validation or code-gen phase.