Skip to content

planner: preserve outer refs in window subqueries#66869

Open
hawkingrei wants to merge 12 commits intopingcap:masterfrom
hawkingrei:fix-window-subquery-56532
Open

planner: preserve outer refs in window subqueries#66869
hawkingrei wants to merge 12 commits intopingcap:masterfrom
hawkingrei:fix-window-subquery-56532

Conversation

@hawkingrei
Copy link
Member

@hawkingrei hawkingrei commented Mar 10, 2026

What problem does this PR solve?

Issue Number: close #56532

Problem Summary:

Window function expressions and peer expressions that contain correlated scalar subqueries can lose access to outer columns during the deferred window rewrite path. This makes queries that work in MySQL fail in TiDB with unknown-column errors.

Review also found that the auxiliary-field collection path could rewrite non-scalar subqueries inside window expressions through the scalar-subquery path, incorrectly introducing MaxOneRow for valid IN / ANY cases.

What changed and how does it work?

  • collect outer columns referenced by subqueries inside window expressions, window specs, and related ORDER BY items, and append them as auxiliary fields before window planning
  • keep Apply-produced columns in the projection built for window arguments so ResolveIndices still finds them after pruning
  • preserve EXISTS, IN, and quantified subquery expressions as complete expressions during auxiliary-field extraction so non-scalar subqueries do not get rewritten as scalar subqueries
  • extend the window casetests with a regression that exercises multi-row non-scalar subqueries inside window expressions, and add deferred cleanup for the existing table-based regression

Check List

Tests

  • Unit test
    • make failpoint-enable
    • go test -run 'TestWindowWithCorrelatedSubQuery|TestWindowSubqueryOuterRef|TestWindowNonScalarSubqueryInWindowExpr' -tags=intest,deadlock ./pkg/planner/core/casetest/windows
    • make failpoint-disable
    • make lint
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Fix queries with correlated and non-scalar subqueries inside window expressions that incorrectly report unknown-column or subquery cardinality errors.

Summary by CodeRabbit

  • Bug Fixes

    • Improved correctness of window-function resolution and rewrites for correlated and non-scalar subqueries, fixing cases involving outer-referenced subqueries.
  • Tests

    • Added extensive test suites covering window functions with correlated/non-scalar subqueries and outer references (multiple new cases).
  • Documentation

    • Added planner notes documenting deferred window rewrite and subquery handling.
  • Chores

    • Increased test parallelism for window tests.

@ti-chi-bot ti-chi-bot bot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Mar 10, 2026
@pantheon-ai
Copy link

pantheon-ai bot commented Mar 10, 2026

Failed to Create Project

We encountered an error while creating your project. Please try again or contact support if the issue persists.

@ti-chi-bot ti-chi-bot bot added sig/planner SIG: Planner size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Mar 10, 2026
@pingcap-cla-assistant
Copy link

pingcap-cla-assistant bot commented Mar 10, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds test data and tests plus planner changes to allow subqueries inside window functions to reference outer-query columns by extracting auxiliary fields, preserving outer-correlated columns during window rewrite, and propagating context into window resolution. Also updates planner docs and increases test shard_count.

Changes

Cohort / File(s) Summary
Window Function Subquery Test Data
pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json, pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json, pkg/planner/core/casetest/windows/testdata/window_push_down_suite_xut.json
Add new TestWindowSubqueryOuterRef suite with multiple cases (SQL, expected plans, and results) covering window functions containing subqueries that reference outer-query columns.
Window Function Test Cases
pkg/planner/core/casetest/windows/widow_with_exist_subquery_test.go
Add tests TestWindowSubqueryRewrite and TestWindowSubqueryOuterRef that set up tables, load testdata, assert planned explains and execution results for the new suite.
Query Planning Logic
pkg/planner/core/logical_plan_builder.go
Introduce subqueryExprExtractor, findColumnNameByUniqueID, appendAuxiliaryFieldsForSubqueries; make resolveWindowFunction context-aware and update projection/schema handling so rewritten window arguments expose required auxiliary columns.
Planner Notes
docs/note/planner/README.md, docs/note/planner/window_subquery_notes.md
Add documentation describing deferred window rewrite handling for correlated and non-scalar subqueries, the extraction/rewriting strategy, and regression coverage.
Test BUILD
pkg/planner/core/casetest/windows/BUILD.bazel
Increase windows_test shard_count from 4 to 6 to adjust test parallelism.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(200,220,255,0.5)
    participant Client as Client
    participant Parser as Parser
    participant PlanBuilder as PlanBuilder
    participant Extractor as subqueryExprExtractor
    participant LogicalPlan as LogicalPlan
    end

    Client->>Parser: submit SQL with window + subquery
    Parser->>PlanBuilder: AST (SelectStmt)
    PlanBuilder->>Extractor: traverse window args, WINDOW specs, ORDER BY
    Extractor-->>PlanBuilder: collected subqueries & outer refs
    PlanBuilder->>LogicalPlan: append auxiliary select fields for outer-correlated cols
    PlanBuilder->>LogicalPlan: build projection/schema aligned with rewritten window args
    LogicalPlan-->>Client: planned query (explain/result used by tests)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Suggested labels

size/XL

Suggested reviewers

  • qw4990
  • winoros
  • AilinKid
  • guo-shaoge

Poem

🐇 I hopped through plans and fields so sly,
Pulled outer refs where subqueries lie.
Windows now see what once was lost,
Tests in tow to count the cost.
Hooray — the planner wiggled a grin.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: preserving outer references in window subqueries to fix the planner bug described in issue #56532.
Description check ✅ Passed Description comprehensively covers problem statement with linked issue, detailed explanation of changes, test instructions, and release note.
Linked Issues check ✅ Passed All code changes directly address issue #56532 objectives: collecting outer columns from subqueries in window expressions, preserving non-scalar subquery handling, and adding comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are in scope: window subquery handling improvements, test data for regression coverage, planner documentation, and build configuration adjustments directly support the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hawkingrei hawkingrei closed this Mar 10, 2026
@hawkingrei hawkingrei reopened this Mar 10, 2026
@hawkingrei
Copy link
Member Author

Follow-up for the review items from #66823:

  • The remaining P1 review point is addressed in commit 5d05ab3dcb by changing deferred window auxiliary-field extraction to rewrite the smallest complete subquery-bearing expression instead of always rewriting the inner *ast.SubqueryExpr as scalar.
  • This keeps EXISTS, IN, and quantified subqueries on their original rewrite paths and avoids introducing MaxOneRow for valid multi-row subqueries inside window expressions.
  • Added regression coverage in TestWindowNonScalarSubqueryInWindowExpr for:
    • count(1 in (select t2.c1 from t2)) over ()
    • count(1 = any (select t2.c1 from t2)) over ()
  • Also added a planner note under docs/note/planner/window_subquery_notes.md to record the root cause and debugging takeaway for future window/subquery fixes.

Validation:

  • make failpoint-enable
  • go test -run 'TestWindowWithCorrelatedSubQuery|TestWindowSubqueryOuterRef|TestWindowNonScalarSubqueryInWindowExpr' -tags=intest,deadlock ./pkg/planner/core/casetest/windows
  • make failpoint-disable
  • make lint

Not verified locally:

  • make bazel_prepare could not run in the current environment because neither bazel nor bazelisk is installed.

@ti-chi-bot ti-chi-bot bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Mar 10, 2026
@hawkingrei hawkingrei force-pushed the fix-window-subquery-56532 branch from 1d28639 to 2e6b187 Compare March 10, 2026 07:27
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/planner/core/logical_plan_builder.go`:
- Around line 2529-2555: The helper findColumnNameByUniqueID currently only
inspects the current plan node and a top-level *logicalop.LogicalJoin; update it
to walk down wrapper/plan layers (e.g., LogicalSelection, LogicalProjection,
LogicalAggregation, LogicalSort, LogicalLimit, LogicalWindow, etc.) to find an
inner *logicalop.LogicalJoin that may hold the FullSchema/FullNames for the
requested uniqueID; once you locate such a join, perform the same
FullSchema/FullNames lookup as the existing join branch and return the
ast.ColumnName if found, otherwise fall back to the existing return nil
behavior. Ensure you keep references to the function name
findColumnNameByUniqueID and the type *logicalop.LogicalJoin so reviewers can
locate the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 49bafa21-0eb5-4b73-ad5f-2cec8237b377

📥 Commits

Reviewing files that changed from the base of the PR and between 88db262 and 5d05ab3.

📒 Files selected for processing (5)
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_xut.json
  • pkg/planner/core/casetest/windows/widow_with_exist_subquery_test.go
  • pkg/planner/core/logical_plan_builder.go

@hawkingrei hawkingrei force-pushed the fix-window-subquery-56532 branch from 2e6b187 to 359d687 Compare March 10, 2026 07:34
Copy link
Contributor

@AilinKid AilinKid left a comment

Choose a reason for hiding this comment

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

rest LGTM

@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

❌ Patch coverage is 77.58621% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.0993%. Comparing base (88db262) to head (2665eee).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #66869        +/-   ##
================================================
- Coverage   77.6754%   77.0993%   -0.5762%     
================================================
  Files          2009       1930        -79     
  Lines        550314     538215     -12099     
================================================
- Hits         427459     414960     -12499     
- Misses       121147     123248      +2101     
+ Partials       1708          7      -1701     
Flag Coverage Δ
integration 41.1159% <46.9565%> (-7.0711%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 56.7974% <ø> (ø)
parser ∅ <ø> (∅)
br 48.8598% <ø> (-12.0517%) ⬇️
🚀 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
pkg/planner/core/logical_plan_builder.go (1)

2559-2585: ⚠️ Potential issue | 🟠 Major

Walk through pass-through wrappers before falling back from FullSchema.

findColumnNameByUniqueID still only inspects the current node and a top-level *logicalop.LogicalJoin. A shape like LogicalSelection -> LogicalJoin (from an inner JOIN ... ON ...) can leave redundant USING/NATURAL columns only in the child join’s FullSchema, so this returns nil and the new window-subquery flow still skips the auxiliary field. Mirroring the wrapper walk in findColFromNaturalUsingJoin should close that hole.

💡 Suggested change
 func findColumnNameByUniqueID(p base.LogicalPlan, uniqueID int64) *ast.ColumnName {
 	for idx, pCol := range p.Schema().Columns {
 		if uniqueID != pCol.UniqueID {
 			continue
 		}
 		pName := p.OutputNames()[idx]
 		return &ast.ColumnName{
 			Schema: pName.DBName,
 			Table:  pName.TblName,
 			Name:   pName.ColName,
 		}
 	}
-	// USING/NATURAL JOIN can keep table-qualified outer references only in FullSchema/FullNames.
-	if join, ok := p.(*logicalop.LogicalJoin); ok && join.FullSchema != nil && len(join.FullNames) != 0 {
-		for idx, pCol := range join.FullSchema.Columns {
+	switch x := p.(type) {
+	case *logicalop.LogicalLimit, *logicalop.LogicalSelection, *logicalop.LogicalTopN, *logicalop.LogicalSort, *logicalop.LogicalMaxOneRow:
+		return findColumnNameByUniqueID(x.Children()[0], uniqueID)
+	case *logicalop.LogicalJoin:
+		if x.FullSchema == nil || len(x.FullNames) == 0 {
+			return nil
+		}
+		// USING/NATURAL JOIN can keep table-qualified outer references only in FullSchema/FullNames.
+		for idx, pCol := range x.FullSchema.Columns {
 			if uniqueID != pCol.UniqueID {
 				continue
 			}
-			pName := join.FullNames[idx]
+			pName := x.FullNames[idx]
 			return &ast.ColumnName{
 				Schema: pName.DBName,
 				Table:  pName.TblName,
 				Name:   pName.ColName,
 			}
 		}
 	}
 	return nil
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/logical_plan_builder.go` around lines 2559 - 2585,
findColumnNameByUniqueID currently only checks the current plan node and a
top-level *logicalop.LogicalJoin, so it misses cases where a join with
FullSchema/FullNames is wrapped by pass-through operators (e.g.,
LogicalSelection) as handled by findColFromNaturalUsingJoin; update
findColumnNameByUniqueID to walk through pass-through wrappers (mirror the
wrapper traversal logic in findColFromNaturalUsingJoin) until you locate the
underlying *logicalop.LogicalJoin with FullSchema/FullNames, then inspect
join.FullSchema.Columns and join.FullNames for the matching uniqueID and return
the ast.ColumnName as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@pkg/planner/core/logical_plan_builder.go`:
- Around line 2559-2585: findColumnNameByUniqueID currently only checks the
current plan node and a top-level *logicalop.LogicalJoin, so it misses cases
where a join with FullSchema/FullNames is wrapped by pass-through operators
(e.g., LogicalSelection) as handled by findColFromNaturalUsingJoin; update
findColumnNameByUniqueID to walk through pass-through wrappers (mirror the
wrapper traversal logic in findColFromNaturalUsingJoin) until you locate the
underlying *logicalop.LogicalJoin with FullSchema/FullNames, then inspect
join.FullSchema.Columns and join.FullNames for the matching uniqueID and return
the ast.ColumnName as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f8224853-c786-4e46-bba7-b4104537fea2

📥 Commits

Reviewing files that changed from the base of the PR and between 5d05ab3 and 44e999a.

📒 Files selected for processing (8)
  • docs/note/planner/README.md
  • docs/note/planner/window_subquery_notes.md
  • pkg/planner/core/casetest/windows/BUILD.bazel
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_xut.json
  • pkg/planner/core/casetest/windows/widow_with_exist_subquery_test.go
  • pkg/planner/core/logical_plan_builder.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json

@hawkingrei
Copy link
Member Author

/retest

@hawkingrei
Copy link
Member Author

@pantheon-bot review

@pantheon-ai
Copy link

pantheon-ai bot commented Mar 10, 2026

Failed to Create Project

We encountered an error while creating your project. Please try again or contact support if the issue persists.

@ti-chi-bot ti-chi-bot bot added the approved label Mar 10, 2026
@ti-chi-bot ti-chi-bot bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Mar 10, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json (1)

45-54: Add one regression for correlated subqueries in window ORDER BY.

These cases cover window arguments and PARTITION BY, but the PR also changes outer-ref preservation for window ORDER BY items. A focused OVER (ORDER BY <correlated-subquery>) case would keep that path protected too.

Example addition
   "cases": [
     "select count((select /* issue:56532 */ ref_1.c2 from t1 limit 1)) over (partition by ref_1.c1) from t2 as ref_1 order by ref_1.c1, ref_1.c2",
     "select coalesce(count(*) over (partition by ref_1.c1), (select /* issue:56532 */ ref_1.c2 from t1)) from t2 as ref_1 order by ref_1.c1, ref_1.c2",
     "select count(exists(select /* issue:56532 */ 1 from t1 where ref_1.c1 is not null)) over (partition by ref_1.c1) from t2 as ref_1 order by ref_1.c1, ref_1.c2",
     "select count((select /* issue:56532 */ 1 from t1 where ref_1.c1 is not null limit 1)) over (partition by ref_1.c1) from t2 as ref_1 join t3 using (c1) order by ref_1.c1, ref_1.c2",
     "select count(*) over w from t2 as ref_1 join t3 using (c1) window w as (partition by exists(select /* issue:56532 */ 1 from t1 where ref_1.c1 is not null)) order by ref_1.c1, ref_1.c2",
+    "select count(*) over (order by (select /* issue:56532 */ ref_1.c2 from t1 limit 1)) from t2 as ref_1 order by ref_1.c1, ref_1.c2",
     "select count((select /* issue:56532 */ 1 from t1 where t3.c1 is not null limit 1)) over (partition by ref_1.c1) from t2 as ref_1 join t3 using (c1) where ref_1.c2 is not null order by ref_1.c1, ref_1.c2"
   ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json`
around lines 45 - 54, Add a focused regression case to the "cases" array of
TestWindowSubqueryOuterRef that exercises an OVER (ORDER BY
<correlated-subquery>) expression so the change to preserve outer refs for
window ORDER BY items is covered; update the "cases" array (in the same JSON
object under "name": "TestWindowSubqueryOuterRef") by appending a SQL test that
uses a correlated subquery inside an OVER (ORDER BY ...) clause (refer to the
existing cases for naming and ordering style).
pkg/planner/core/logical_plan_builder.go (1)

2741-2769: Consider batching these auxiliary-field scans.

appendAuxiliaryFieldsForSubqueries already accepts variadic nodes, so the three loops here repeat AST walks, rewrites, and dedup scans over the same sel.Fields.Fields. Collecting the window field exprs, specs, and windowed ORDER BY exprs first and making one call would keep the behavior while trimming the extra pre-build work.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/planner/core/logical_plan_builder.go` around lines 2741 - 2769, The three
loops each call appendAuxiliaryFieldsForSubqueries separately causing repeated
AST walks; instead gather all window-related nodes into a single slice and call
appendAuxiliaryFieldsForSubqueries once. Concretely, iterate over
sel.Fields.Fields, sel.WindowSpecs, and sel.OrderBy.Items, collect
expressions/nodes that satisfy ast.HasWindowFlag (and the WindowSpec pointers)
into one []ast.Node (or the expected variadic type), then replace the three
separate calls with a single call: sel.Fields.Fields, err =
b.appendAuxiliaryFieldsForSubqueries(ctx, p, sel.Fields.Fields,
collectedNodes...), handling error as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json`:
- Around line 45-54: Add a focused regression case to the "cases" array of
TestWindowSubqueryOuterRef that exercises an OVER (ORDER BY
<correlated-subquery>) expression so the change to preserve outer refs for
window ORDER BY items is covered; update the "cases" array (in the same JSON
object under "name": "TestWindowSubqueryOuterRef") by appending a SQL test that
uses a correlated subquery inside an OVER (ORDER BY ...) clause (refer to the
existing cases for naming and ordering style).

In `@pkg/planner/core/logical_plan_builder.go`:
- Around line 2741-2769: The three loops each call
appendAuxiliaryFieldsForSubqueries separately causing repeated AST walks;
instead gather all window-related nodes into a single slice and call
appendAuxiliaryFieldsForSubqueries once. Concretely, iterate over
sel.Fields.Fields, sel.WindowSpecs, and sel.OrderBy.Items, collect
expressions/nodes that satisfy ast.HasWindowFlag (and the WindowSpec pointers)
into one []ast.Node (or the expected variadic type), then replace the three
separate calls with a single call: sel.Fields.Fields, err =
b.appendAuxiliaryFieldsForSubqueries(ctx, p, sel.Fields.Fields,
collectedNodes...), handling error as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ec0a8d12-d204-4800-8421-53cb0e095151

📥 Commits

Reviewing files that changed from the base of the PR and between 44e999a and c92d584.

📒 Files selected for processing (4)
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_in.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_xut.json
  • pkg/planner/core/logical_plan_builder.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/planner/core/casetest/windows/testdata/window_push_down_suite_out.json

Copy link
Contributor

@qw4990 qw4990 left a comment

Choose a reason for hiding this comment

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

Could you also add this as a test case?
This case is from #57594

func TestCorrelatedExistsWithWindowFunction(t *testing.T) {
	store := testkit.CreateMockStore(t)
	tk := testkit.NewTestKit(t, store)
	tk.MustExec("use test")
	tk.MustExec("create table t1 (c1 int)")

	// Empty table should return no rows.
	tk.MustQuery("select case when (EXISTS (select 1 where ref_0.c1)) then count(*) over () else 1 end from t1 as ref_0").Check(testkit.Rows())

	tk.MustExec("insert into t1 values (1), (null), (0), (2)")
	// c1=1 → EXISTS true → count(*) over () = 4
	// c1=null → EXISTS false → 1
	// c1=0 → EXISTS false → 1
	// c1=2 → EXISTS true → count(*) over () = 4
	tk.MustQuery("select c1, case when (EXISTS (select 1 where ref_0.c1)) then count(*) over () else 1 end as res from t1 as ref_0 order by c1").Check(testkit.Rows(
		"<nil> 1",
		"0 1",
		"1 4",
		"2 4",
	))

	// Correlated EXISTS with window function using PARTITION BY.
	tk.MustQuery("select c1, case when (EXISTS (select 1 where ref_0.c1 > 0)) then sum(c1) over () else 0 end as res from t1 as ref_0 order by c1").Check(testkit.Rows(
		"<nil> 0",
		"0 0",
		"1 3",
		"2 3",
	))

	// Correlated EXISTS with a text column (original bug reproduction from issue).
	tk.MustExec("drop table t1")
	tk.MustExec("create table t1 (c1 text)")
	tk.MustQuery("select case when (EXISTS (select 1 where ref_0.c1)) then count(*) over (partition by 1) else 1 end from t1 as ref_0").Check(testkit.Rows())
}

@Mini256
Copy link
Member

Mini256 commented Mar 10, 2026

@pantheon-bot review

@pantheon-ai
Copy link

pantheon-ai bot commented Mar 10, 2026

@Mini256 I've received your request and will start reviewing the pull request. I'll conduct a thorough review covering code quality, potential issues, and implementation details.

⏳ This process typically takes 10-30 minutes depending on the complexity of the changes.

ℹ️ Learn more details on Pantheon AI.


Validation commands:
- `make failpoint-enable`
- `go test -run 'TestWindowWithCorrelatedSubQuery|TestWindowSubqueryOuterRef|TestWindowNonScalarSubqueryInWindowExpr' -tags=intest,deadlock ./pkg/planner/core/casetest/windows`
Copy link

Choose a reason for hiding this comment

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

[P2] Stale validation command references non-existent test functions

Why: The documented go test -run command references TestWindowWithCorrelatedSubQuery and TestWindowNonScalarSubqueryInWindowExpr, neither of which exists in the package. Only TestWindowSubqueryOuterRef matches an actual test. The intended non-scalar regression coverage lives inside TestWindowSubqueryRewrite (see pkg/planner/core/casetest/windows/widow_with_exist_subquery_test.go:86-87). This means a developer following the checklist validation command would silently miss running the non-scalar subquery regression tests.

Evidence: docs/note/planner/window_subquery_notes.md:32 and docs/note/planner/window_subquery_notes.md:38 — the -run regex TestWindowWithCorrelatedSubQuery|TestWindowSubqueryOuterRef|TestWindowNonScalarSubqueryInWindowExpr only matches TestWindowSubqueryOuterRef in the target package.

Suggestion: Replace with -run 'TestWindowSubqueryRewrite|TestWindowSubqueryOuterRef' (or rename/split the test to match the documented name).

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch. The note was still using the old test names after I merged the hand-written regressions into TestWindowSubqueryRewrite.

Updated docs/note/planner/window_subquery_notes.md to keep the documented coverage and validation command aligned with the current package tests:

  • TestWindowSubqueryRewrite
  • TestWindowSubqueryOuterRef

The command is now:
go test -run 'TestWindowSubqueryRewrite|TestWindowSubqueryOuterRef' -tags=intest,deadlock ./pkg/planner/core/casetest/windows

Fixed in commit e4799aa.

Copy link

@pantheon-ai pantheon-ai bot Mar 10, 2026

Choose a reason for hiding this comment

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

Thanks for the quick fix! Confirmed — the updated command correctly maps to the two existing test functions. LGTM.

ℹ️ Learn more details on Pantheon AI.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 10, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: AilinKid, qw4990

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Mar 10, 2026
@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 10, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-03-10 10:05:28.14405128 +0000 UTC m=+344559.656108941: ☑️ agreed by AilinKid.
  • 2026-03-10 12:26:36.940055508 +0000 UTC m=+353028.452113179: ☑️ agreed by qw4990.

@hawkingrei hawkingrei added the AI-Correction Bugfix by AI label Mar 10, 2026
@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 10, 2026

@hawkingrei: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-unit-test-next-gen 2c6fa1a link true /test pull-unit-test-next-gen
pull-mysql-client-test 2665eee link true /test pull-mysql-client-test

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

AI-Correction Bugfix by AI approved lgtm release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subquery in window function cannot reference column outside, while mysql can

4 participants