Skip SQL pushdown for oversized IN-list predicates - #29
Merged
Conversation
Translating a very large is_in([...]) predicate into a SQL IN (...) clause
can exceed a backend's expression-complexity limits — SQL Server raises
error 8632 ("An expression services limit has been reached"). Such lists
arise, for example, when a join materializes one side and pushes its key
set down to the other.
Add DEFAULT_MAX_IN_PREDICATE_SIZE (4096) and skip translating an is_in list
longer than that into SQL: the visitor returns None for the branch, and the
existing AND-folding keeps any remaining (selective) predicates. This is
always correct because the IO source re-applies the full predicate to the
fetched rows; only the pre-filter narrowing (an optimization) is lost. The
limit is configurable via convert_predicate_to_sql / apply_polars_io_source_exprs.
Signed-off-by: Pascal Tomecek <40371786+ptomecek@users.noreply.github.com>
Contributor
ptomecek
marked this pull request as ready for review
August 31, 2026 14:40
feussy
approved these changes
Aug 31, 2026
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.
Summary
Translating a very large
is_in([...])predicate into a SQLIN (...)clause can exceed a backend's expression-complexity limits. In particular, SQL Server raises error 8632 — "An expression services limit has been reached." Such oversized lists arise naturally when a join materializes one side and pushes its key set down to the other source as anis_inpredicate.Change
DEFAULT_MAX_IN_PREDICATE_SIZE = 4096.is_inlist is longer than the limit, skip translating it: the visitor returnsNonefor that branch, and the existing AND-folding logic keeps any remaining (selective) predicates so they still push down.convert_predicate_to_sql(...)andapply_polars_io_source_exprs(...).Why this is safe
Skipping pushdown for an oversized
INnever changes results: the IO source already re-applies the full predicate to the fetched rows. Only the pre-filter narrowing (an optimization) is lost, and for the pathological case (a whole key universe) that narrowing was providing little benefit anyway, since co-pushed selective predicates already scope the scan.Tests
Adds
test_oversized_in_predicate_is_not_pushed_down:INstill pushes down,INis dropped,INAND a selective equality keeps the equality pushdown,max_in_predicate_sizeoverride re-enables pushdown.make lintandmake formatpass; existing SQL-reader tests pass.