sql: bound INTERSECT plan size by ordering its inputs - #37897
Merged
Conversation
Planning duplicates an INTERSECT's left input, so a left-deep chain doubles the plan at every level. A 35-way chain needs 2^35 HIR nodes, which exhausted environmentd's memory during planning and wedged the coordinator (incident-1160). INTERSECT is commutative, so put the cheaper input on the left. A subtree is then only duplicated when it is the smaller of the two, which bounds the plan at O(n^log2(3)) instead of O(2^n). The swap is not observable: column names come from the left scope either way, and both inputs are already cast to a common type before this point. The regression test uses a full 35-way chain because a shorter one would pass either way. The unfixed planner still returns the correct answer at 12 levels, so only a chain long enough to exhaust memory distinguishes the two. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011d7RFuATJRYwYDWjZEs2Sg
bosconi
pushed a commit
that referenced
this pull request
Jul 29, 2026
Adds the one user-facing entry from the rc.3 cherry-pick: #37897, which fixes queries with many chained INTERSECT operations exhausting environmentd memory during planning. Dates are unchanged: the provisional estimate is anchored on the rc.1 tag and has not elapsed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
maheshwarip
pushed a commit
that referenced
this pull request
Jul 31, 2026
Adds the one user-facing entry from the rc.3 cherry-pick: #37897, which fixes queries with many chained INTERSECT operations exhausting environmentd memory during planning. Dates are unchanged: the provisional estimate is anchored on the rc.1 tag and has not elapsed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Planning duplicates an INTERSECT's left input, so a left-deep chain doubles the plan at every level. A 35-way chain needs 2^35 HIR nodes, which exhausted environmentd's memory during planning and wedged the coordinator in an incident.
INTERSECT is commutative, so put the cheaper input on the left. A subtree is then only duplicated when it is the smaller of the two, which bounds the plan at O(n^log2(3)) instead of O(2^n). The swap is not observable: column names come from the left scope either way, and both inputs are already cast to a common type before this point.
The regression test uses a full 35-way chain because a shorter one would pass either way. The unfixed planner still returns the correct answer at 12 levels, so only a chain long enough to exhaust memory distinguishes the two.