[BugFix] Fix COALESCE(null, 42) returning wrong type string instead of int (#5175)#5310
Conversation
…f int (opensearch-project#5175) In PPL, null is parsed as a QualifiedName (field name), not a literal. When COALESCE encounters an unresolvable field, it falls back to replaceWithNullLiteralInCoalesce() which created a null literal typed as VARCHAR. This caused leastRestrictive([VARCHAR, INTEGER]) to return VARCHAR, making COALESCE(null, 42) return string type instead of int. Fix: Change the null literal type from SqlTypeName.VARCHAR to SqlTypeName.NULL (Calcite's bottom type, compatible with any type). Also add defense-in-depth: filter out NULL-typed operands in EnhancedCoalesceFunction's return type inference before calling leastRestrictive. Signed-off-by: Heng Qian <qianheng@amazon.com>
Decision LogRoot Cause: In PPL, Approach: Two-part fix:
Alternatives Rejected:
Pitfalls:
Things to Watch:
|
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
Description
Fix COALESCE returning wrong type
stringinstead ofintwhen called with null and integer literals.Root Cause: In PPL,
nullis parsed as aQualifiedName(field name), not aLiteral. When COALESCE encounters an unresolvable field name likenull, it falls back toreplaceWithNullLiteralInCoalesce()which incorrectly created a null literal typed asVARCHAR. This causedleastRestrictive([VARCHAR, INTEGER])to returnVARCHAR, makingCOALESCE(null, 42)returnstringtype.Fix: Two-part fix:
QualifiedNameResolver.java): Changed the null literal type fromSqlTypeName.VARCHARtoSqlTypeName.NULL(Calcite's bottom type, compatible with any type). This makesleastRestrictive([NULL, INTEGER])correctly returnINTEGER.EnhancedCoalesceFunction.java): Filter outNULL-typed operands in the return type inference before callingleastRestrictive, ensuring correct type even if NULL types slip through.Related Issues
Resolves #5175
Check List
-s)spotlessCheckpassed.g4files synced (N/A - no grammar changes)