IN LIST: retain short lists with specialized filters - #25187
Draft
geoffreyclaude wants to merge 4 commits into
Draft
IN LIST: retain short lists with specialized filters#25187geoffreyclaude wants to merge 4 commits into
geoffreyclaude wants to merge 4 commits into
Conversation
Treat inline Utf8View and BinaryView values as 128-bit primitive keys and pass them to the shared primitive filter selector. This reuses direct comparisons for short lists and the primitive hash-set path for larger lists without reading backing buffers. Lists containing a non-inline value continue to use the general filter. Exact view types, dictionaries, slices, nulls, IN, and NOT IN keep their existing behavior.
geoffreyclaude
force-pushed
the
codex/in-list-short-rewrite
branch
5 times, most recently
from
September 11, 2026 13:58
0186b14 to
ef1ad44
Compare
12 tasks
geoffreyclaude
force-pushed
the
codex/in-list-short-rewrite
branch
from
September 11, 2026 14:35
ef1ad44 to
11b0a61
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
Rationale for this change
The expression simplifier currently rewrites singleton
INlists, and two- or three-item lists on a column, into left-deepOR/ANDcomparison chains. That rule predates the specialized static filters in this series. For supported types, rewriting two- and three-item lists now prevents them from reaching a substantially faster branchless physical path.The rewrite should therefore depend on the available physical representation, not only on list length. This PR keeps singleton-to-equality simplification, retains static two- and three-item
InListexpressions when a specialized filter can evaluate them, and preserves the existing comparison rewrite for dynamic or generic lists.Although the singleton
InListpath is faster for several representations in isolated evaluation, equality remains the canonical logical form and can benefit other optimizer and pushdown paths that this microbenchmark does not measure.What changes are included in this PR?
OR/ANDexpansion for generic types, out-of-line byte views, and non-constant lists.Are these changes tested?
Coverage includes the retained and expanded boundaries;
INandNOT IN; typed nulls; dynamic lists; nested dictionaries; supported and unsupported fixed-size-binary widths; inline and out-of-lineUtf8View/BinaryViewvalues; and the independent preimage limit.Focused validation:
cargo test -p datafusion-optimizer --lib(796 tests)cargo test -p datafusion-substrait roundtrip_inlist(5 tests)cargo test -p datafusion-sqllogictest --test sqllogictests -- negative_zerocargo check -p datafusion --bench in_list_rewritecargo bench -p datafusion --bench in_list_rewrite -- --noplotAre there any user-facing changes?
Once prerequisite #25186 has landed, no query results or public APIs change. Optimized plans retain two- and three-item
InListexpressions for supported constant-list representations instead of expanding them into comparison chains.Local benchmark snapshot
The new benchmark parses and analyzes both forms from SQL, asserts their physical shapes and equal outputs, then measures only physical-expression evaluation. It covers five representative types; list sizes 1-4; batches of 1, 64, and 8,192 rows; input and list nulls; miss, balanced, and skewed match rates; and both
INandNOT IN: 300 paired scenarios and 600 Criterion functions in total.The table focuses on the two sizes whose optimizer policy changes. Each ratio is the median
comparison chain / retained InListtime across 16 scenarios; values above 1 favor retainingInList.FixedSizeBinary(8)Float64Int32Utf8ViewUtf8OR/ANDGeneric
Utf8remains mixed, including regressions for skewed and null-containing lists, so this PR deliberately leaves it on the existing comparison rewrite. List sizes one and four serve as boundary controls; their optimizer policy is unchanged.