Skip to content

fix(sql): support cross-type numeric coercion and 3-valued NULL logic in IN list (#1659) - #2546

Open
zaidrain06 wants to merge 1 commit into
getdozer:mainfrom
zaidrain06:fix/issue-1659-in-list-cross-type-null
Open

zaidrain06 wants to merge 1 commit into
getdozer:mainfrom
zaidrain06:fix/issue-1659-in-list-cross-type-null

Conversation

@zaidrain06

@zaidrain06 zaidrain06 commented Nov 1, 2026 •

Copy link
Copy Markdown

Summary

Fixes #1659
/claim #1659

This PR resolves SQLLogicTest IN / NOT IN evaluation failures in dozer-sql/expression/src/in_list.rs where cross-type numeric comparisons (Int, UInt, Float, Decimal, numeric String) and three-valued SQL NULL semantics previously returned incorrect results.

Root Cause

evaluate_in_list previously evaluated each candidate expression item in list and compared it against expr.evaluate(record, schema)? using Rust's strict enum equality (item.evaluate(record, schema)? == expr_val):

  1. Cross-type numeric mismatch: Field::Int(1) == Field::Float(OrderedFloat(1.0)) and Field::Int(1) == Field::Decimal(Decimal::new(1, 0)) evaluated to false because the enum variants differ, even though comparison::evaluate_eq already implements Dozer's cross-type numeric/string coercion rules.
  2. Broken 3-valued NULL logic: Under SQL-92 three-valued logic:
    • NULL IN (1, 2) and 1 IN (2, NULL) must evaluate to NULL (not FALSE).
    • 1 NOT IN (2, NULL) must evaluate to NULL (not TRUE), whereas 1 IN (1, NULL) is TRUE and 1 NOT IN (1, NULL) is FALSE.
    • NULL IN () is FALSE and NULL NOT IN () is TRUE.

Solution

  • Delegate element-wise comparison inside evaluate_in_list to crate::comparison::evaluate_eq(schema, &mut left, item, record)? so IN / NOT IN shares identical type coercion semantics with =.
  • Track has_null across candidate evaluations to implement three-valued SQL NULL semantics when no candidate matches Field::Boolean(true).
  • Add unit tests in in_list::tests:
    • test_in_list_cross_type_numeric_coercion
    • test_in_list_three_valued_null_semantics

Verification

$ cargo test -p dozer-sql-expression
running 29 tests
...
test in_list::tests::test_in_list_cross_type_numeric_coercion ... ok
test in_list::tests::test_in_list_three_valued_null_semantics ... ok
...
test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Bounty Payout Details (if direct crypto transfer is preferred alongside Algora):

  • EVM Wallet (Base / Arbitrum One / Optimism / Ethereum): 0x9d66D9cf93776B5244B3C1F39C77696B80199dE2
  • Contact: bydelibozok@gmail.com

@CLAassistant

CLAassistant commented Nov 1, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for IN clause in streaming SQL

2 participants