Repository navigation
Conversation
|
Thank you for opening this pull request! Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch). Details |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #26274 +/- ##
========================================
Coverage 82.87% 82.88%
========================================
Files 1153 1153
Lines 457101 457958 +857
Branches 457101 457958 +857
========================================
+ Hits 378818 379556 +738
- Misses 55268 55320 +52
- Partials 23015 23082 +67 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
adriangb
force-pushed
the
mcte-column-pruning
branch
3 times, most recently
from
October 16, 2026 14:58
e93f908 to
00200fa
Compare
Replace the `MaterializedCte` and `MaterializedCteScan` extension nodes with the variants `LogicalPlan::MaterializedCte` and `LogicalPlan::MaterializedCteScan`. Each rule now states what it does with the nodes in its `match`, and the downcasts are removed from `PushDownFilter`, `PullUpCorrelatedExpr`, `head_output_expr` and the physical planner. `MaterializedCte::try_new` checks that the scans have the schema of the body, and `MaterializedCteScan::find_in` finds the scans of one CTE, also in subquery expressions. The unparser, the Substrait producer and the protobuf serializer return a "not implemented" error for the two variants. Plans and results do not change. Closes apache#26238. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The body of a `MaterializedCte` kept all its columns, because each `MaterializedCteScan` was a leaf with the full schema of the body. A `MaterializedCteScan` now has a `projection`: the indexes of the columns of the body that it outputs. `OptimizeProjections` narrows each scan to the columns that its parent needs, as it does for a `TableScan`. At the `MaterializedCte` node it optimizes the continuation first, computes the union of the columns of all the scans of the CTE (also in subquery expressions and in the bodies of other CTEs), projects the body to this union, and gives each scan the new positions of its columns. `MaterializedCteScanExec` applies the projection to the shared buffered batches. The physical planner checks that each scan agrees with the schema of its body when it binds the scan. Closes apache#26240. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adriangb
force-pushed
the
mcte-column-pruning
branch
from
October 16, 2026 16:57
00200fa to
8acc60b
Compare
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.
Which issue does this PR close?
Stacked on #26269. Only the last commit is new.
Rationale for this change
The body of a materialized CTE kept all its columns, also when no reference read them.
Before, all five columns were read and buffered:
After, only
aandbare read and buffered:What changes are included in this PR?
MaterializedCteScanhas a new fieldprojection: Option<Vec<usize>>: the indexes of the columns of the CTE body that the scan outputs.OptimizeProjectionsnarrows eachMaterializedCteScanto the columns that its parent needs, as it does for aTableScan.MaterializedCte,OptimizeProjectionsoptimizes the continuation first. It then computes the union of the columns of all the scans of the CTE, projects the body to this union, and gives each scan the new positions of its columns. Scans in subquery expressions and in the bodies of other CTEs are counted.MaterializedCteScanExecapplies the projection to the shared buffered batches.The projection in the scan makes the intermediate state (a narrow scan and a wide body) a valid plan, so no separate rule is necessary.
Notes:
SELECT count(*) FROM c) getsprojection=[]. If no reference reads a column, the body keeps its first column.DISTINCTor a recursive query are not removed.Comparison with PostgreSQL and DuckDB. This is what DuckDB does:
RemoveUnusedColumnsprunes the body to the columns that its references read (remove_unused_columns.cpp). PostgreSQL plans a CTE for full retrieval and does not prune (subselect.c).Are these changes tested?
Yes.
cte_materialized.slt:EXPLAINand result checks for the example above, a column that only a filter reads,count(*), a CTE that another CTE reads, references in subqueries, a volatile body, aDISTINCTbody, aliased columns, a self join, a recursive body and a CTE that nothing reads. Unit tests for the scan projection, nested CTEs, idempotence and the zero-column case.Are there any user-facing changes?
EXPLAINshowsprojection=[...]onMaterializedCteScanandMaterializedCteScanExecwhen the scan does not read all the columns.MaterializedCteScanhas the new public fieldprojection. The upgrade guide for 56.0.0 says this.