Skip to content

Conversation

@markuspf
Copy link
Contributor

@markuspf markuspf commented Dec 3, 2025

Scope & Purpose

Customer reported problems when executing a complex query that involved modification operations inside nested subqueries.

The added regression test shows that the problem occurs when a modification executor is nested within 3 subqueries.

During AQL execution, modification executors are special: they always request to see all their inputs, even if a subsequent LIMIT would otherwise mean that rows aren't fetched.

At some point during execution, it can happen that a subquery call on the modification executors' callstack is empty.

Execution then runs into an assertion on current devel, because the check whether the modification executor needs to be handled specially during sideEffectShadowRowForwarding tries to peek the next call of the call stack at every level (in needToCountSubquery).

This solution merges shadowRowForwarding and sideEffectShadowRowForwarding into one function that handles the side effect case inline; I hope that makes it slightly more transparent.

When the callstack contains an empty call, the executor cannot know what to do, so it is not allowed to do anything and just returns ExecState::DONE now.

  • 💩 Bugfix
  • 🍕 New feature
  • 🔥 Performance improvement
  • 🔨 Refactoring/simplification

Checklist

  • Tests
    • Regression tests
    • C++ Unit tests
    • integration tests
    • resilience tests
  • 📖 CHANGELOG entry made
  • 📚 documentation written (release notes, API changes, ...)
  • Backports
    • Backport for 3.12.0: (Please link PR)
    • Backport for 3.11: (Please link PR)
    • Backport for 3.10: (Please link PR)

@cla-bot cla-bot bot added the cla-signed label Dec 3, 2025
@markuspf markuspf force-pushed the bug-fix/es-2763-nested-subquery-modification branch 2 times, most recently from 5bf37dc to 8867a41 Compare December 10, 2025 13:13
@markuspf markuspf changed the title [ES-2763] Fix crash on nested subqueries with modification [ES-2763] [COR-51] Fix crash on nested subqueries with modification Dec 11, 2025
@markuspf markuspf force-pushed the bug-fix/es-2763-nested-subquery-modification branch 3 times, most recently from 643965f to b1d4825 Compare December 17, 2025 10:22
@markuspf markuspf force-pushed the bug-fix/es-2763-nested-subquery-modification branch from 6feba92 to 5100f56 Compare December 18, 2025 17:10
@markuspf markuspf marked this pull request as ready for review December 19, 2025 13:25
Comment on lines +1398 to +1405
// TODO: the original sideEffectShadowRowForwarding returns
// ExecState::DONE in this case. It is likely correct
// to just return ExecState::NEXTSUBQUERY and remove this
// case distinction.
// Let's do that in a separate PR. In particular keep UPSERT in mind.
if constexpr (executorHasSideEffects<Executor>) {
return ExecState::DONE;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we want to address this in a follow-up PR I suggest we create a ticket and reference it here.

return shadowRowForwardingSubqueryStart(stack);
} else if constexpr (std::is_same_v<Executor, SubqueryEndExecutor>) {
return shadowRowForwardingSubqueryEnd(stack);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should leave this else here in place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure I understand; you mean wrap the whole rest of the function into the {} after the else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants