Skip to content

fix: erase extract() bound symbol in UsedSymbolsCollector - #4081

Merged
DavIvek merged 2 commits into
masterfrom
fix/issue-2023
Aug 17, 2026
Merged

fix: erase extract() bound symbol in UsedSymbolsCollector #4081
DavIvek merged 2 commits into
masterfrom
fix/issue-2023

Conversation

@DavIvek

@DavIvek DavIvek commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Description

Closes #2023

A WHERE clause that uses extract(v IN list | expr) (and exercises the bound iterator inside expr) crashes the planner with the internal error:

Expected to generate all filters! Please contact Memgraph support as this scenario should not happen and is very likely a bug in the query engine!

Repro

CREATE (:Actor {domain:'test.com', infringes:[{brand:'Customer A'}]});

MATCH (i:Actor {domain:'test.com'})
WHERE 'Customer A' IN extract(v IN i.infringes | v.brand)
RETURN i.domain;
--throws "Expected to generate all filters!"

The user-reported workaround (lifting extract(...) into a WITH and filtering on the alias) still works.

Root cause

UsedSymbolsCollector in src/query/plan/preprocess.hpp defines PostVisit overrides that erase the lambda-bound symbol for All, Any, Single, None, Reduce, and ListComprehension. The override for Extract was missing, so the iterator v of extract(v IN list | expr) ended up in the filter's used_symbols. Because no logical operator ever binds v, the filter is never matched against any expansion and PlanMatching ends with a non-empty filters set, tripping the guard in rule_based_planner.hpp:813.

UsedSymbolsCollector erases lambda-bound symbols in PostVisit overrides
for All, Any, Single, None, Reduce and ListComprehension, but the
override for Extract was missing.

When extract() appears inside a WHERE expression, the bound iterator is
incorrectly counted as a free symbol of the filter, so the filter never
matches any expansion's bound symbols and PlanMatching ends with a
non-empty filters set, throwing "Expected to generate all filters!".

Adds the missing PostVisit(Extract&) override and a behave regression
test covering both matching and non-matching IN extract() predicates.

Closes #2023
@sonarqubecloud

Copy link
Copy Markdown

@DavIvek
DavIvek marked this pull request as ready for review August 17, 2026 07:03
Copilot AI lite review requested due to automatic review settings August 17, 2026 07:03
@DavIvek DavIvek added this to the mg-v3.13.0 milestone Aug 17, 2026
@DavIvek DavIvek added the CI -build=coverage -test=core Run coverage build and core tests on push label Aug 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a planner crash triggered by extract(v IN list | expr) used inside a WHERE clause by ensuring the lambda-bound iterator symbol (v) is treated as bound (not “free”) during symbol collection, so filter matching does not retain an unbindable symbol and trip an internal guard.

Changes:

  • Add UsedSymbolsCollector::PostVisit(Extract&) to erase the iterator symbol bound by extract(...).
  • Add new Gherkin/behave coverage reproducing the crash and validating correct behavior for matching and non-matching membership predicates.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/query/plan/preprocess.hpp Erases extract’s bound iterator symbol from UsedSymbolsCollector results, aligning with existing handling for other lambda-like expressions.
tests/gql_behave/tests/memgraph_V1/features/issue_2023_extract_in_where.feature Adds regression scenarios covering IN extract(...) in WHERE for both matching and non-matching cases.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@DavIvek
DavIvek enabled auto-merge August 17, 2026 18:27
@DavIvek

DavIvek commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Tracking

  • [Link to Epic/Issue]

Standard development

CI Testing Labels

  • Select the appropriate CI test labels (CI -build=build-name -test=test-suite)

Documentation checklist

  • Add the documentation label
  • Add the bug / feature label
  • Add the milestone for which this feature is intended
    • If not known, set for a later milestone
  • Write a release note, including added/changed clauses
    • Fixes a query planning crash when using extract() with a bound iterator inside a WHERE clause. Queries using this pattern now execute correctly without requiring users to rewrite them using an intermediate WITH. #4081

@DavIvek DavIvek changed the title fix: erase extract() bound symbol in UsedSymbolsCollector (#2023) fix: erase extract() bound symbol in UsedSymbolsCollector Aug 17, 2026
@DavIvek
DavIvek added this pull request to the merge queue Aug 17, 2026
Merged via the queue into master with commit 4b4dc88 Aug 17, 2026
37 checks passed
@DavIvek
DavIvek deleted the fix/issue-2023 branch August 17, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI -build=coverage -test=clang_tidy CI -build=coverage -test=core Run coverage build and core tests on push Docs - changelog only Docs - changelog only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memgraph crashes on specific query

3 participants