feat(lower): nested SQL query functions via derived tables (#27) - #29
Merged
Merged
Conversation
The SQL front end already recurses through the DataFusion `LogicalPlan`, so a nested aggregate/filter/projection chain lowered — but a *derived table* / inline view (`FROM (SELECT …) t`) was rejected: `lower_plan`'s `SubqueryAlias` arm only accepted a `TableScan` (or another alias) as its input. That is the SQL counterpart of the PromQL function nesting added in the sibling change — an aggregate over an aggregate, a filter over a derived aggregate, etc. The `SubqueryAlias` arm now lowers an arbitrary inner plan recursively (`lower_plan` already handles every node a sub-`SELECT` produces). The alias is dropped; a qualified outer reference (`t.col`) resolves by bare name against the derived output schema — the same `Qualified → bare-name` fallback the converter's column resolution already applies for joins. Subquery-*valued* expressions in a predicate (`x > (SELECT …)`, `IN (SELECT …)`, `EXISTS (…)`) still need a subquery node in the L2 expression IR, so they are rejected cleanly with an explicit message rather than the generic catch-all. Tests: derived-table aggregate-over-aggregate, outer-avg-over-inner-percentile, filter-over-derived-aggregate (qualified alias resolution), and a pinned scalar-subquery rejection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
milindsrivastava1997
approved these changes
Jun 21, 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.
What & why
Adds nested query function support for SQL — the SQL counterpart of the PromQL nesting in #28 — closing the SQL part of #27.
SQL's
lower_planalready recurses through the DataFusionLogicalPlan, so a nested aggregate/filter/projection chain lowered. The gap was derived tables / inline views (FROM (SELECT …) t): theSubqueryAliasarm only accepted aTableScan(or another alias) as input, so an aggregate-over-aggregate had nowhere to go.How
lower_plan'sSubqueryAliasarm now lowers an arbitrary inner plan recursively (lower_planalready handles every node a sub-SELECTproduces). The alias is dropped; a qualified outer ref (t.col) resolves by bare name against the derived output schema — the sameQualified → bare-namefallback the converter's column resolution already uses for joins. No L3 IR / converter / Binder changes needed.x > (SELECT …),IN (SELECT …),EXISTS (…)) need a subquery node in the L2 expression IR (+ a correlated/uncorrelated decision), so they're rejected cleanly with an explicit message instead of the generic catch-all.Tests
derived_table_aggregate_over_aggregate_nests— outerMaxover innerSum, schema derivation total across the boundary.derived_table_outer_avg_over_inner_percentile— exactAvgover approximateQuantile(per-node sketch-vs-exact is an L4 decision).filter_over_derived_aggregate_resolves_alias_column—WHERE t.s > 100resolves the qualified alias column.scalar_subquery_in_predicate_is_rejected— pinned rejection.cargo clippy --all-targetsclean.Scope / follow-ups
Scalar /
IN/EXISTSsubqueries in predicates (correlated subqueries) remain rejected — tracked in the updated #27. Relates to #28 (PromQL nesting); the two are independent and don't conflict.Closes the SQL part of #27.
🤖 Generated with Claude Code