Skip to content

fix: SQL bind a scalar subquery's aggregate to its own relation - #28939

Merged
ritchie46 merged 2 commits into
mainfrom
sql-scalar-subquery-projection
Aug 24, 2026
Merged

ritchie46 merged 2 commits into
mainfrom
sql-scalar-subquery-projection

Conversation

@ritchie46

Copy link
Copy Markdown
Member

Made with opus 5

The correlated scalar-subquery lowering parsed its aggregate projection
directly, without the check every other conjunct it handles goes through. A
qualifier naming a registered table the subquery does not read was therefore
dropped rather than refused, and the aggregate silently took a column of the
subquery's own relation:

  SELECT k, (SELECT SUM(foo.a) FROM t2 x WHERE x.b = t1.k) FROM t1

summed `x.a`, giving an answer for a question that was never asked. DuckDB
rejects the same query.

Parse the projection through `try_parse_inner_only_expr`, as the WHERE
conjuncts already are, so a qualifier that names no relation of the subquery
declines the lowering instead. That subsumes the separate nested-subquery
check, which the same helper already makes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PeS5DzwijVsijK68XXPsw
@github-actions github-actions Bot added A-sql Area: Polars SQL functionality fix Bug fix python Related to Python Polars rust Related to Rust Polars labels Aug 24, 2026
The two decorrelators that take an outer-query operand (`IN` as a join and
`IN` as a correlated lowering) each repeated the same parse-then-validate
block; both now go through `try_parse_outer_only_expr`, mirroring the
existing `try_parse_inner_only_expr`.

`binds_to_inner_relation` walked the expression twice, once to reject nested
subqueries and once to resolve identifiers. Both are per-node decisions, so
they fold into a single walk; the subquery match moves to a shared
`is_subquery_expr` that `expr_contains_subquery` also uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PeS5DzwijVsijK68XXPsw
@github-actions

Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 60.9203 MB.

@github-actions

Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 60.9200 MB.

@ritchie46
ritchie46 merged commit 80a55c3 into main Aug 24, 2026
30 of 32 checks passed
@ritchie46
ritchie46 deleted the sql-scalar-subquery-projection branch August 24, 2026 12:54
@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.15385% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 81.60%. Comparing base (7f63d86) to head (0047fc0).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
crates/polars-sql/src/subquery.rs 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #28939      +/-   ##
==========================================
+ Coverage   81.56%   81.60%   +0.04%     
==========================================
  Files        1888     1889       +1     
  Lines      268247   268577     +330     
  Branches     3263     3263              
==========================================
+ Hits       218785   219169     +384     
+ Misses      48617    48563      -54     
  Partials      845      845              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

A-sql Area: Polars SQL functionality fix Bug fix python Related to Python Polars rust Related to Rust Polars

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant