Skip to content

Push single-variable WHERE predicates across all MATCH clauses#4

Merged
paracycle merged 1 commit into
mainfrom
cross-clause-pushdown
Jul 8, 2026
Merged

Push single-variable WHERE predicates across all MATCH clauses#4
paracycle merged 1 commit into
mainfrom
cross-clause-pushdown

Conversation

@paracycle

Copy link
Copy Markdown
Member

Builds the pushdown map once from every non-optional MATCH's WHERE, so a single-variable predicate prunes the scan that first binds its variable even when the WHERE is written on a later clause. MATCH (t)-[:R]->(c) MATCH (c)-..-(x) WHERE t.name = ... previously materialized the whole (t)-[:R]->(c) relation before filtering t.

Review note / correctness fix

The original patch made the pushdown map global and always-on, which introduced a latent correctness bug: it would then be applied inside OPTIONAL MATCH and EXISTS. A pushed t IS NULL predicate on an optionally-bound t would prune every real t, null-fill every row, and wrongly keep them all (breaking the anti-join). This PR keeps the global map but gates application to non-optional MATCH pattern evaluation (pushdown_active), restoring the pre-existing invariant that pushdown never fires in OPTIONAL MATCH / EXISTS.

Includes the cross-clause regression test and a new pushdown_optional_safety test that fails against the always-on variant.

Co-authored-by: River shopify.river@shopify.com

Build the pushdown map once from every non-optional MATCH's WHERE so a
single-variable predicate prunes the scan that first binds its variable,
even when the WHERE is written on a later clause. Previously pushdown was
per-clause, so `MATCH (t)-[:R]->(c) MATCH (c)-..-(x) WHERE t.name = ...`
materialized the entire (t)-[:R]->(c) relation before filtering t.

The global map is only applied while evaluating non-optional MATCH
patterns (gated by pushdown_active); it must stay off during OPTIONAL
MATCH expansion and EXISTS subqueries, where pruning a candidate that
fails a single-variable predicate can change results — e.g. an
`OPTIONAL MATCH ... WHERE t IS NULL` anti-join would otherwise null-fill
every row and wrongly keep them all.

Adds the cross-clause pushdown regression test and a pushdown/OPTIONAL
MATCH safety test.

Co-authored-by: River <shopify.river@shopify.com>
@paracycle paracycle added the performance Performance improvement label Jul 8, 2026
@paracycle paracycle merged commit a45fcd4 into main Jul 8, 2026
2 checks passed
@paracycle paracycle deleted the cross-clause-pushdown branch July 8, 2026 19:54
@paracycle paracycle mentioned this pull request Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant