Skip to content

planner, executor: support merge sort for IN conditions in IndexMerge partial paths (#67771)#68753

Merged
ti-chi-bot[bot] merged 6 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-67771-to-release-8.5
Jun 4, 2026
Merged

planner, executor: support merge sort for IN conditions in IndexMerge partial paths (#67771)#68753
ti-chi-bot[bot] merged 6 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-67771-to-release-8.5

Conversation

@ti-chi-bot
Copy link
Copy Markdown
Member

@ti-chi-bot ti-chi-bot commented May 29, 2026

This is an automated cherry-pick of #67771

What problem does this PR solve?

Issue Number: ref #65712 close #67775

Problem Summary:

For queries like SELECT * FROM t WHERE (a = 1 OR b IN (1,2)) ORDER BY c LIMIT 5, where indexes idx_a_c(a, c) and idx_b_c(b, c) are available:

  • The a = 1 partial path on idx_a_c can directly satisfy ORDER BY c (PropMatched).
  • The b IN (1,2) partial path on idx_b_c cannot directly satisfy ORDER BY c, because the ranges [1,1] and [2,2] are individually ordered by c but not globally ordered.

Previously, PropMatchedNeedMergeSort (introduced in #62694) was rejected for IndexMerge partial paths, causing the plan to fall back to a global TopN without Limit pushdown. This could scan all matching rows (e.g., ~750K) before sorting, resulting in much worse performance.

This is Solution 3 described in the issue.

What changed and how does it work?

This PR leverages the merge sort infrastructure from #62694 to support PropMatchedNeedMergeSort for IndexMerge partial paths. The IN condition ranges are split into groups, each producing a sorted stream, which are then merged.

After this fix, the plan becomes:

IndexMerge  type: union, limit embedded(offset:0, count:5)
├─Limit(Build)  offset:0, count:5
│ └─IndexRangeScan  range:[1,1], keep order:true
├─Limit(Build)  offset:0, count:5
│ └─IndexRangeScan  range:[1,1], [2,2], keep order:true
└─TableRowIDScan(Probe)  keep order:false
  • planner
    • matchPropForIndexMergeAlternatives() and isMatchPropForIndexMerge(): Accept PropMatchedNeedMergeSort from individual partial paths by using .Matched() instead of == PropMatched. The IndexMerge-level result remains PropMatched (the IndexMerge itself satisfies the order via its own inter-path merge sort).
    • ConvertToPartialIndexScan() and convertToPartialTableScan(): Remove the assertion that blocked PropMatchedNeedMergeSort, and copy GroupedRanges/GroupByColIdxs from the AccessPath to the physical scan when the path needs merge sort.
  • executor
    • Replace separate keyRanges and partitionKeyRanges fields with a unified partialWorkerKVRanges [][]*kvRangesWithPhysicalTblID. Each entry carries a PhysicalTableID alongside its kv ranges, unifying partition mode, grouped ranges (from IN conditions), and the combination of both. This follows the same pattern as IndexLookUpExecutor.groupedKVRanges from planner, executor: support access path keep order with IN conditions using merge sort #62694.
    • New buildPartialWorkerKVRanges() method in Open() builds kv ranges for each partial plan considering both partitions and grouped ranges.
    • rebuildRangeForCorCol(): After rebuilding ranges for correlated columns, also rebuild GroupedRanges using GroupRangesByCols().
    • startPartialTableWorker(): Pass GroupedRanges/GroupByColIdxs to the TableReaderExecutor, which already has full support for grouped ranges.
    • memIndexMergeReader (UnionScan): Updated to use the unified partialWorkerKVRanges field, replacing the previous partitionKVRanges/partitionTables and direct keyRanges access. The PhysicalTableID from each entry is used for partition handle conversion.

Check List

Tests

  • Unit test
  • 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

None

Summary by CodeRabbit

  • Bug Fixes / Improvements

    • IndexMerge now reliably preserves merged ordering for IN/OR predicates with ORDER BY ... LIMIT across partial scans by precomputing and consolidating per-worker scan ranges and broadening which partial paths qualify for merge ordering.
  • Tests

    • Added comprehensive integration tests for IndexMerge with IN lists, ORDER BY ... LIMIT, prepared statements, partitioned/table-path scenarios, transactional visibility, and correlated-subquery cases.

Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@ti-chi-bot ti-chi-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels May 29, 2026
@ti-chi-bot
Copy link
Copy Markdown
Member Author

@time-and-fate This PR has conflicts, I have hold it.
Please resolve them or ask others to resolve them, then comment /unhold to remove the hold label.

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 29, 2026

@ti-chi-bot: ## If you want to know how to resolve it, please read the guide in TiDB Dev Guide.

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 ti-community-infra/tichi repository.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2f21c556-321c-455f-8bba-06f2a22b3aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 04f45a7 and 55f35c7.

📒 Files selected for processing (3)
  • pkg/planner/core/find_best_task.go
  • tests/integrationtest/r/index_merge.result
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
✅ Files skipped from review due to trivial changes (1)
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result

📝 Walkthrough

Walkthrough

This PR centralizes per-worker KV ranges into partialWorkerKVRanges, propagates grouped-range metadata from planner access paths into partial scans, adjusts worker wiring and in-memory readers to use the unified ranges, and adds integration tests and expected-plan updates for IndexMerge with IN predicates plus ORDER BY LIMIT.

Changes

IndexMerge merge-sort support for IN conditions

Layer / File(s) Summary
IndexMergeReaderExecutor unified KV range structure and precomputation
pkg/executor/index_merge_reader.go
IndexMergeReaderExecutor replaces split keyRanges/partitionKeyRanges with partialWorkerKVRanges. buildPartialWorkerKVRanges() precomputes per-worker grouped KV ranges at Open by selecting grouped ranges from the physical plan (when available), choosing physical tables per partition/global-index mode, and converting group×table into KV ranges annotated with physical table IDs.
IndexMergeReaderExecutor correlated column handling and worker wiring
pkg/executor/index_merge_reader.go
rebuildRangeForCorCol now prepares grouped ranges for partial scans. startPartialIndexWorker derives per-worker keyRanges from partialWorkerKVRanges[workID]. startPartialTableWorker passes groupedRanges and groupByColIdxs from the physical plan into TableReaderExecutor.
memIndexMergeReader adaptation to unified KV ranges
pkg/executor/mem_reader.go
memIndexMergeReader now stores partitionMode and partialWorkerKVRanges and builds readers by iterating partialWorkerKVRanges[i]. When partitionMode is enabled, non-partition handles are wrapped using pkr.PhysicalTableID.
Planner property matching and grouped-range propagation
pkg/planner/core/find_best_task.go
matchProperty clears AccessPath.GroupedRanges/GroupByColIdxs before matching. matchPropForIndexMergeAlternatives and isMatchPropForIndexMerge use matchProperty(...).Matched(). When ordering is matched, convertToPartialIndexScan/convertToPartialTableScan copy non-empty GroupedRanges/GroupByColIdxs into produced partial scans.
Integration test: IndexMerge with IN and ORDER BY basic coverage
tests/integrationtest/t/index_merge.test, tests/integrationtest/r/index_merge.result
Adds t_im_in setup and tests validating IndexMerge + IN + ORDER BY LIMIT for mixed partial paths, multiple partial paths, DESC ordering, transactional visibility with rollback, and prepared statement execution.
Integration test: IndexMerge with IN and ORDER BY advanced scenarios
tests/integrationtest/t/planner/core/grouped_ranges_order_by.test, tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
Adds tests for prepared IN parameters, uncommitted UnionScan visibility, correlated subquery Apply cases with limit 1, range-partitioned table coverage, and clustered-PK table-path scenarios; includes EXPLAIN validations and result-order checks.
Expected EXPLAIN output updates for IndexMerge limit pushdown
tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result
Updates expected plans to show IndexMerge type: union, limit embedded(...) with build-side Limit(Build) wrapping IndexRangeScan nodes that are keep order:true, replacing prior IndexMerge type: union layouts.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • pingcap/tidb#67771: Both PRs implement unified partialWorkerKVRanges refactoring and grouped-range propagation for IndexMerge partial paths to enable merge-sort execution with IN conditions.

Suggested labels

needs-cherry-pick-release-8.5

Suggested reviewers

  • qw4990

Poem

🐰 In grouped ranges the carrots hide,
Precomputed paths hop side by side.
Merge-sort hums through IN’s small maze,
ORDER BY LIMIT finds tidy ways,
A rabbit cheers: “Good code-day!” 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% 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 identifies the main change: supporting merge sort for IN conditions in IndexMerge partial paths, which is the core feature added.
Description check ✅ Passed Description follows the template with issue numbers, problem summary, detailed explanation of changes in planner and executor, integration tests included, and release note.
Linked Issues check ✅ Passed Changes fully implement the objective from #67775: enabling PropMatchedNeedMergeSort for IndexMerge partial paths with IN conditions through planner and executor modifications including grouped ranges support.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the linked issue requirements: planner IndexMerge property matching, executor KV range unification, correlated column range rebuilding, and comprehensive integration tests.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


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.

Copy link
Copy Markdown

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result (1)

3566-3627: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve both unresolved merge-conflict blocks before merge.

Line 3566 and Line 3641 still contain <<<<<<<, =======, and >>>>>>> blocks. This leaves the golden result file invalid and will break integration-result verification. Keep one expected branch (the new plan_tree expectations) and remove conflict markers plus discarded branch content in both regions.

🧩 Minimal conflict-resolution shape
-<<<<<<< HEAD
-...old expected output...
-=======
 ...chosen expected output...
->>>>>>> 173eaf24799 (planner, executor: support merge sort for IN conditions in IndexMerge partial paths (`#67771`))

Also applies to: 3641-3681

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result`
around lines 3566 - 3627, The file still contains unresolved git conflict
markers (<<<<<<<, =======, >>>>>>>) around two blocks; open the region
containing the alternative "explain format = 'brief' ..." vs "explain format =
'plan_tree' ..." outputs and remove the conflict markers and the discarded
'brief' branch content, keeping the new plan_tree expectations (the blocks that
show "explain format = 'plan_tree' ...", "Projection", "IndexMerge",
"Limit(Build)", "IndexRangeScan", "TableRowIDScan") for both conflict regions so
the golden result contains only the plan_tree expectations and no leftover
markers.
pkg/executor/index_merge_reader.go (2)

253-282: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Second unresolved git merge conflict must be resolved.

Another merge conflict block exists here. The conflict appears to be between the old table-scan range building logic and the new unified approach with grouped ranges support.

🐛 Proposed resolution

Remove the conflict markers and keep only the new implementation:

-<<<<<<< HEAD
-		_, ok := plan[0].(*plannercore.PhysicalIndexScan)
-		if !ok {
-			firstPartRanges, secondPartRanges := distsql.SplitRangesAcrossInt64Boundary(e.ranges[i], false, e.descs[i], tbl.Meta().IsCommonHandle)
-			firstKeyRanges, err := distsql.TableHandleRangesToKVRanges(dctx, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, firstPartRanges)
-			if err != nil {
-				return nil, err
-			}
-			secondKeyRanges, err := distsql.TableHandleRangesToKVRanges(dctx, []int64{getPhysicalTableID(tbl)}, tbl.Meta().IsCommonHandle, secondPartRanges)
-			if err != nil {
-				return nil, err
-			}
-			keyRanges := append(firstKeyRanges.FirstPartitionRange(), secondKeyRanges.FirstPartitionRange()...)
-			ranges = append(ranges, keyRanges)
-			continue
-=======
+		// Determine grouped ranges: use GroupedRanges from the physical plan if available,
+		// otherwise wrap the flat ranges as a single group.
+		var (
+			groupedRanges [][]*ranger.Range
+			isIdxScan     bool
+		)
+		switch x := plan[0].(type) {
+		case *physicalop.PhysicalIndexScan:
+			isIdxScan = true
+			groupedRanges = x.GroupedRanges
+		case *physicalop.PhysicalTableScan:
+			groupedRanges = x.GroupedRanges
->>>>>>> 173eaf24799 (planner, executor: support merge sort for IN conditions in IndexMerge partial paths (`#67771`))
+		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/executor/index_merge_reader.go` around lines 253 - 282, Remove the
leftover git conflict markers and keep the new unified implementation that
declares groupedRanges and isIdxScan and switches on plan[0] to handle
*physicalop.PhysicalIndexScan (set isIdxScan=true and groupedRanges =
x.GroupedRanges) and *physicalop.PhysicalTableScan (groupedRanges =
x.GroupedRanges); delete the old branch that used
distsql.SplitRangesAcrossInt64Boundary/TableHandleRangesToKVRanges and ensure
subsequent code uses the groupedRanges variable produced by this switch (look
for symbols groupedRanges, isIdxScan, and plan[0] in index_merge_reader.go).

246-335: ⚠️ Potential issue | 🔴 Critical

Fix missing physicalop import in pkg/executor/index_merge_reader.go
This file uses *physicalop.PhysicalIndexScan / *physicalop.PhysicalTableScan, but the import block contains no github.com/pingcap/tidb/pkg/planner/core/operator/physicalop package, so the physicalop selector won’t compile.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/executor/index_merge_reader.go` around lines 246 - 335, The file missing
the physicalop import causes unresolved references to
*physicalop.PhysicalIndexScan and *physicalop.PhysicalTableScan in
IndexMergeReaderExecutor.buildPartialWorkerKVRanges; add the physicalop package
to the import block (import
"github.com/pingcap/tidb/pkg/planner/core/operator/physicalop" or the
repository's equivalent path) so the symbols PhysicalIndexScan and
PhysicalTableScan resolve, then run go build to verify no further missing
imports.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/executor/index_merge_reader.go`:
- Around line 211-234: Resolve the unresolved git conflict markers by removing
the lines "<<<<<<< HEAD", "=======", and ">>>>>>> 173eaf24799" and merge the two
alternate case arms into a single switch handling block that covers the intended
scan types; ensure you keep the shared logic that calls ResolveCorrelatedColumns
and sets GroupedRanges (the code that calls e.ranges[i], err =
x.ResolveCorrelatedColumns() and the subsequent GroupRangesByCols call), and
include both case labels for the correct types (e.g., case
*plannercore.PhysicalTableScan: and case *physicalop.PhysicalTableScan: or
whichever single type is correct after refactor) so the switch in the function
containing this block compiles cleanly and preserves error handling and grouping
behavior.

In `@pkg/planner/core/find_best_task.go`:
- Around line 1119-1130: Remove the cherry-pick conflict markers and keep the
intended merged logic: replace the conflict block with the loop-based check that
iterates over oneAlternative and uses matchProperty(...).Matched() (i.e.,
declare match := true; for _, oneAccessPath := range oneAlternative { if
!noSortItem && !matchProperty(ds, oneAccessPath, prop).Matched() { match =
false; break } } if !match { ... } ), ensuring you reference noSortItem,
matchProperty, oneAlternative/oneAccessPath and prop exactly and remove any
remaining <<<<<<< / ======= / >>>>>>> lines so the file compiles.

In `@pkg/planner/core/operator/physicalop/physical_index_scan.go`:
- Around line 697-701: The code references prop.NeedKeepOrder() and
prop.GetSortDescForKeepOrder() on PhysicalProperty but those methods don't
exist; either add those methods to PhysicalProperty in
pkg/planner/property/physical_property.go (implement NeedKeepOrder() to return
the current keep-order predicate and GetSortDescForKeepOrder() to produce the
sort descriptor from the existing SortItems/PartialOrderInfo fields), or update
physical_index_scan.go to use the existing keep-order APIs on PhysicalProperty
(replace NeedKeepOrder()/GetSortDescForKeepOrder() calls with the actual
existing methods/fields that represent "keep order" and sort descriptors),
ensuring is.Desc and is.KeepOrder are set from the correct existing APIs.

---

Outside diff comments:
In `@pkg/executor/index_merge_reader.go`:
- Around line 253-282: Remove the leftover git conflict markers and keep the new
unified implementation that declares groupedRanges and isIdxScan and switches on
plan[0] to handle *physicalop.PhysicalIndexScan (set isIdxScan=true and
groupedRanges = x.GroupedRanges) and *physicalop.PhysicalTableScan
(groupedRanges = x.GroupedRanges); delete the old branch that used
distsql.SplitRangesAcrossInt64Boundary/TableHandleRangesToKVRanges and ensure
subsequent code uses the groupedRanges variable produced by this switch (look
for symbols groupedRanges, isIdxScan, and plan[0] in index_merge_reader.go).
- Around line 246-335: The file missing the physicalop import causes unresolved
references to *physicalop.PhysicalIndexScan and *physicalop.PhysicalTableScan in
IndexMergeReaderExecutor.buildPartialWorkerKVRanges; add the physicalop package
to the import block (import
"github.com/pingcap/tidb/pkg/planner/core/operator/physicalop" or the
repository's equivalent path) so the symbols PhysicalIndexScan and
PhysicalTableScan resolve, then run go build to verify no further missing
imports.

In
`@tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result`:
- Around line 3566-3627: The file still contains unresolved git conflict markers
(<<<<<<<, =======, >>>>>>>) around two blocks; open the region containing the
alternative "explain format = 'brief' ..." vs "explain format = 'plan_tree' ..."
outputs and remove the conflict markers and the discarded 'brief' branch
content, keeping the new plan_tree expectations (the blocks that show "explain
format = 'plan_tree' ...", "Projection", "IndexMerge", "Limit(Build)",
"IndexRangeScan", "TableRowIDScan") for both conflict regions so the golden
result contains only the plan_tree expectations and no leftover markers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dcf3ca02-1e86-4070-963e-c975de870863

📥 Commits

Reviewing files that changed from the base of the PR and between 651272b and 8e5cf69.

📒 Files selected for processing (9)
  • pkg/executor/index_merge_reader.go
  • pkg/executor/mem_reader.go
  • pkg/planner/core/find_best_task.go
  • pkg/planner/core/operator/physicalop/physical_index_scan.go
  • tests/integrationtest/r/index_merge.result
  • tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
  • tests/integrationtest/t/index_merge.test
  • tests/integrationtest/t/planner/core/grouped_ranges_order_by.test

Comment thread pkg/executor/index_merge_reader.go Outdated
Comment thread pkg/planner/core/find_best_task.go Outdated
Comment thread pkg/planner/core/operator/physicalop/physical_index_scan.go Outdated
@ti-chi-bot ti-chi-bot Bot added cherry-pick-approved Cherry pick PR approved by release team. and removed do-not-merge/cherry-pick-not-approved labels May 29, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

❌ Patch coverage is 74.03846% with 27 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release-8.5@16cc308). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff                @@
##             release-8.5     #68753   +/-   ##
================================================
  Coverage               ?   55.1171%           
================================================
  Files                  ?       1826           
  Lines                  ?     658024           
  Branches               ?          0           
================================================
  Hits                   ?     362684           
  Misses                 ?     268258           
  Partials               ?      27082           
Flag Coverage Δ
integration 38.2742% <74.0384%> (?)
unit 65.0460% <65.3846%> (?)

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

Components Coverage Δ
dumpling 55.1998% <0.0000%> (?)
parser ∅ <0.0000%> (?)
br 54.5307% <0.0000%> (?)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qw4990
Copy link
Copy Markdown
Contributor

qw4990 commented Jun 4, 2026

/unhold

@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 4, 2026
@ti-chi-bot ti-chi-bot Bot added needs-1-more-lgtm Indicates a PR needs 1 more LGTM. approved labels Jun 4, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Jun 4, 2026

[APPROVALNOTIFIER] This PR is APPROVED

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

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 Jun 4, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Jun 4, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-06-04 14:40:37.355033416 +0000 UTC m=+452538.425350806: ☑️ agreed by qw4990.
  • 2026-06-04 15:45:37.738648254 +0000 UTC m=+456438.808965644: ☑️ agreed by terry1purcell.

Copy link
Copy Markdown

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/planner/core/find_best_task.go`:
- Line 1377: Restore the Fix52869 gate when deciding preferMerge: the boolean
should require both the presence of index-merge hints and that the Fix52869
planner gate/feature flag is enabled, not just the hint alone; update the
preferMerge assignment (the line using ds.IndexMergeHints and variable
preferMerge in find_best_task.go) to combine the hint check with the existing
Fix52869 gate check (e.g., preferMerge := len(ds.IndexMergeHints) > 0 &&
Fix52869Enabled() or the equivalent project-specific gate function/flag) so the
behavior only changes when the kill‑switch is not set.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2f21c556-321c-455f-8bba-06f2a22b3aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 04f45a7 and 55f35c7.

📒 Files selected for processing (3)
  • pkg/planner/core/find_best_task.go
  • tests/integrationtest/r/index_merge.result
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
✅ Files skipped from review due to trivial changes (1)
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result

Copy link
Copy Markdown

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/planner/core/find_best_task.go`:
- Line 1377: Restore the Fix52869 gate when deciding preferMerge: the boolean
should require both the presence of index-merge hints and that the Fix52869
planner gate/feature flag is enabled, not just the hint alone; update the
preferMerge assignment (the line using ds.IndexMergeHints and variable
preferMerge in find_best_task.go) to combine the hint check with the existing
Fix52869 gate check (e.g., preferMerge := len(ds.IndexMergeHints) > 0 &&
Fix52869Enabled() or the equivalent project-specific gate function/flag) so the
behavior only changes when the kill‑switch is not set.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2f21c556-321c-455f-8bba-06f2a22b3aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 04f45a7 and 55f35c7.

📒 Files selected for processing (3)
  • pkg/planner/core/find_best_task.go
  • tests/integrationtest/r/index_merge.result
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
✅ Files skipped from review due to trivial changes (1)
  • tests/integrationtest/r/planner/core/grouped_ranges_order_by.result
🛑 Comments failed to post (1)
pkg/planner/core/find_best_task.go (1)

1377-1377: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore the Fix52869 gate on hinted IndexMerge preference.

This line changes preferMerge from a hint-plus-fix-control decision into a hint-only decision. That widens skyline-pruning behavior for every USE_INDEX_MERGE query, not just the new ordered-IN partial-path cases in this PR, and removes the existing release-branch kill switch for regressions. Please keep the fix-control check here or split this planner-behavior change out.

Suggested fix
-	preferMerge := len(ds.IndexMergeHints) > 0
+	preferMerge := len(ds.IndexMergeHints) > 0 &&
+		fixcontrol.GetBoolWithDefault(ds.SCtx().GetSessionVars().OptimizerFixControl, fixcontrol.Fix52869, true)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/planner/core/find_best_task.go` at line 1377, Restore the Fix52869 gate
when deciding preferMerge: the boolean should require both the presence of
index-merge hints and that the Fix52869 planner gate/feature flag is enabled,
not just the hint alone; update the preferMerge assignment (the line using
ds.IndexMergeHints and variable preferMerge in find_best_task.go) to combine the
hint check with the existing Fix52869 gate check (e.g., preferMerge :=
len(ds.IndexMergeHints) > 0 && Fix52869Enabled() or the equivalent
project-specific gate function/flag) so the behavior only changes when the
kill‑switch is not set.

@time-and-fate
Copy link
Copy Markdown
Member

/retest

1 similar comment
@time-and-fate
Copy link
Copy Markdown
Member

/retest

@ti-chi-bot ti-chi-bot Bot merged commit 8323301 into pingcap:release-8.5 Jun 4, 2026
20 checks passed
@ti-chi-bot ti-chi-bot Bot deleted the cherry-pick-67771-to-release-8.5 branch June 4, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved cherry-pick-approved Cherry pick PR approved by release team. lgtm release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants