Fix: SubqueryFilterChecker stack-empty crash#478
Open
snaumenko-st wants to merge 4 commits intomaster-servicetitanfrom
Open
Fix: SubqueryFilterChecker stack-empty crash#478snaumenko-st wants to merge 4 commits intomaster-servicetitanfrom
snaumenko-st wants to merge 4 commits intomaster-servicetitanfrom
Conversation
…cates
SubqueryFilterChecker.VisitBinary unconditionally called Pop() on its
meaningfulLefts/meaningfulRights correlation stacks whenever it saw a
"tuple[i] == null" comparison. If the checker visited a FilterProvider
whose predicate started with a bare null-check before any correlation
equality had pushed anything onto the stacks, Pop() threw
InvalidOperationException("Stack empty.") during LINQ translation.
This shape surfaces naturally from:
Query.All<T>()
.GroupBy(p => p.Id)
.Select(g => g.Count(x => x.Field == null))
.ToArray();
where VisitAggregate takes the "use grouping AggregateProvider"
optimization path and runs SubqueryFilterRemover over an origin data
source whose top FilterProvider carries the bare "x.Field == null"
predicate.
Guard Pop() with a Count==0 check and treat an empty-stack null-check
as "not a subquery-correlation filter" (fall through to
base.VisitFilter), which is the conservative, behavior-preserving
choice.
Covered by a new e2e regression test in
Orm/Xtensive.Orm.Tests/Linq/SubqueryFilterCheckerTest.cs using an
inline model; the test fails with "Stack empty." on the unfixed code
and passes with the guard.
Made-with: Cursor
Co-authored-by: Sergei Pavlov <spavlov@servicetitan.com>
SergeiPavlov
approved these changes
Apr 22, 2026
botinko
approved these changes
Apr 22, 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.
SubqueryFilterChecker.VisitBinaryunconditionally calledPop()on itsmeaningfulLefts/meaningfulRightscorrelation stacks whenever it saw a"tuple[i] == null"comparison. If the checker visited aFilterProviderwhose predicate started with a bare null-check before any correlation equality had pushed anything onto the stacks,Pop()threwInvalidOperationException("Stack empty.")during LINQ translation.This shape surfaces naturally from:
where
VisitAggregatetakes the "use grouping AggregateProvider" optimization path and runsSubqueryFilterRemoverover an origin data source whose topFilterProvidercarries the bare"x.Field == null"predicate.Guard
Pop()with aCount==0check and treat an empty-stack null-check as "not a subquery-correlation filter" (fall through tobase.VisitFilter), which is the conservative, behavior-preserving choice.Covered by a new e2e regression test in
Orm/Xtensive.Orm.Tests/Linq/SubqueryFilterCheckerTest.cs using an inline model; the test fails with "Stack empty." on the unfixed code and passes with the guard.
Made-with: Cursor