Skip to content

fix(array): between over a constant null array is null, not false - #10744

Open
gitRasheed wants to merge 1 commit into
vortex-data:developfrom
gitRasheed:not-between-all-null
Open

gitRasheed wants to merge 1 commit into
vortex-data:developfrom
gitRasheed:not-between-all-null

Conversation

@gitRasheed

Copy link
Copy Markdown
Contributor

Summary

In DataFusion, a NOT IN (1, 2, 3, 4, 5) counted null rows that sit in an all-null chunk.

Data: id Int32 0..999. a Int32 nullable, null for rows 0..499 and id % 20 for rows 500..999. Written as ten 100-row chunks (WriteStrategyBuilder with with_row_block_size(100) and with_data_block_target_bytes(None)), so rows 0..499 are five all-null chunks.

SELECT count(*) FROM t WHERE a NOT IN (1, 2, 3, 4, 5)

A DataFusion MemTable with the same data returns 375. On develop Vortex returns 875, so it counts all 500 null rows. With this change it returns 375.

vortex-datafusion turns a NOT IN of consecutive integers into not(between(...)) (in_list_of in vortex-array/src/expr/exprs.rs) and reports the filter as pushed, so DataFusion does not check it again. Each all-null chunk is a ConstantArray. The Constant BetweenReduce rule compared it with the constant bounds using Scalar's ordering, which puts null below every value. So between returned false instead of null, and not turned that into true. In normal dispatch null bounds are handled earlier by short_circuit, so a null array value is the case that got through.

Changes

When the array constant is null, the Constant BetweenReduce rule now returns a null Bool constant with the combined nullability of the array and both bounds.

The new test scalar_fn::fns::between::tests::constant_null_array checks that between and not(between) are all null for f64 and i32.

Checked locally: cargo test -p vortex-array --lib between (46 passed, and the new test fails on develop), the DataFusion query above (875 on develop, 375 with this change), clippy with -D warnings, and nightly fmt.

I used AI tools to help write and review this change.

The Constant between reduce rule compared the constant scalar with the
bounds directly. Scalar orders null below every value, so an all-null
chunk (which compression stores as a ConstantArray) gave a non-null
false, and not(between(x, a, b)) over it selected every row instead of
none. Return a null constant when the array constant is null.

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>

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.

1 participant