Skip to content

Conversation

@hawkingrei
Copy link
Member

@hawkingrei hawkingrei commented Dec 25, 2025

What problem does this PR solve?

Issue Number: close #65335

Problem Summary:

What changed and how does it work?

checkCanPushDownToMPP will be called twice in the following code. The other problem is that if tables without tiflash replications are used in the query, we don't need to check the mpp task.

func getHashAggs(lp base.LogicalPlan, prop *property.PhysicalProperty) []base.PhysicalPlan {
la := lp.(*logicalop.LogicalAggregation)
if !prop.IsSortItemEmpty() {
return nil
}
if prop.TaskTp == property.MppTaskType && !checkCanPushDownToMPP(la) {
return nil
}
hashAggs := make([]base.PhysicalPlan, 0, len(prop.GetAllPossibleChildTaskTypes()))
taskTypes := []property.TaskType{property.CopSingleReadTaskType, property.CopMultiReadTaskType, property.RootTaskType}
// aggregation has a special case that it can be pushed down to TiKV which is indicated by the prop.NoCopPushDown
if prop.NoCopPushDown {
taskTypes = []property.TaskType{property.RootTaskType}
}
// lift the recursive check of canPushToCop(tiFlash)
canPushDownToMPP := la.SCtx().GetSessionVars().IsMPPAllowed() && checkCanPushDownToMPP(la)
if canPushDownToMPP {
taskTypes = append(taskTypes, property.MppTaskType)
} else {
hasMppHints := false
var errMsg string
if la.PreferAggType&h.PreferMPP1PhaseAgg > 0 {
errMsg = "The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid"
hasMppHints = true
}
if la.PreferAggType&h.PreferMPP2PhaseAgg > 0 {
errMsg = "The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid"
hasMppHints = true
}
if hasMppHints {
la.SCtx().GetSessionVars().StmtCtx.SetHintWarning(errMsg)
}
}
if prop.IsFlashProp() {
taskTypes = []property.TaskType{prop.TaskTp}
}
taskTypes = admitIndexJoinTypes(taskTypes, prop)
for _, taskTp := range taskTypes {
if taskTp == property.MppTaskType {
mppAggs := tryToGetMppHashAggs(la, prop)
if len(mppAggs) > 0 {
hashAggs = append(hashAggs, mppAggs...)
}
} else {
childProp := &property.PhysicalProperty{ExpectedCnt: math.MaxFloat64, TaskTp: taskTp, CTEProducerStatus: prop.CTEProducerStatus, NoCopPushDown: prop.NoCopPushDown}
// mainly to fill indexJoinProp to childProp.
childProp = admitIndexJoinProp(childProp, prop)
if childProp == nil {
continue
}
agg := NewPhysicalHashAgg(la, la.StatsInfo().ScaleByExpectCnt(la.SCtx().GetSessionVars(), prop.ExpectedCnt), childProp)
agg.SetSchema(la.Schema().Clone())
hashAggs = append(hashAggs, agg)
}
}
return hashAggs
}

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

Please refer to Release Notes Language Style Guide to write a quality release note.

None

@ti-chi-bot ti-chi-bot bot added do-not-merge/needs-linked-issue do-not-merge/needs-tests-checked release-note-none Denotes a PR that doesn't merit a release note. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. sig/planner SIG: Planner and removed do-not-merge/needs-tests-checked labels Dec 25, 2025
@codecov
Copy link

codecov bot commented Dec 25, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.8974%. Comparing base (e8a60bd) to head (74c7d31).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #65250        +/-   ##
================================================
+ Coverage   77.7750%   78.8974%   +1.1223%     
================================================
  Files          2001       1922        -79     
  Lines        545527     532954     -12573     
================================================
- Hits         424284     420487      -3797     
+ Misses       119581     111014      -8567     
+ Partials       1662       1453       -209     
Flag Coverage Δ
integration 48.9488% <ø> (+0.7840%) ⬆️

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

Components Coverage Δ
dumpling 56.7974% <ø> (ø)
parser ∅ <ø> (∅)
br 66.0791% <ø> (+5.0887%) ⬆️
🚀 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.

@ti-chi-bot ti-chi-bot bot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Dec 25, 2025
@hawkingrei hawkingrei force-pushed the cannot_call_checkCanPushDownToMPP_twice branch from 4728a02 to e3b9c98 Compare December 30, 2025 05:02
@hawkingrei
Copy link
Member Author

/retest

@hawkingrei
Copy link
Member Author

/retest

@hawkingrei hawkingrei changed the title planner: cannot call checkCanPushDownToMPP twice planner: cannot call checkCanPushDownToMPP twice | tidb-test=pr/2660 Dec 30, 2025
@hawkingrei
Copy link
Member Author

/retest

1 similar comment
@hawkingrei
Copy link
Member Author

/retest

@hawkingrei hawkingrei changed the title planner: cannot call checkCanPushDownToMPP twice | tidb-test=pr/2660 planner: don't call checkCanPushDownToMPP twice | tidb-test=pr/2660 Dec 30, 2025
@hawkingrei hawkingrei changed the title planner: don't call checkCanPushDownToMPP twice | tidb-test=pr/2660 planner: improve checkCanPushDownToMPP | tidb-test=pr/2660 Dec 30, 2025
@hawkingrei hawkingrei force-pushed the cannot_call_checkCanPushDownToMPP_twice branch from b114bb3 to e949bd4 Compare December 30, 2025 14:20
@hawkingrei
Copy link
Member Author

/retest

@hawkingrei hawkingrei force-pushed the cannot_call_checkCanPushDownToMPP_twice branch from 78144ef to 9b4552a Compare December 30, 2025 15:39
@hawkingrei hawkingrei changed the title planner: improve checkCanPushDownToMPP | tidb-test=pr/2660 planner: improve getHashAggs | tidb-test=pr/2660 Dec 30, 2025
@hawkingrei
Copy link
Member Author

/retest

return nil, err
}
tableInfo := tbl.Meta()
sessionVars.StmtCtx.HasTiflash = sessionVars.StmtCtx.HasTiflash || b.ctx.GetSessionVars().IsMPPAllowed() &&
Copy link
Member

Choose a reason for hiding this comment

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

I think we don't need to add this together in this pr.
Current physical optimization needs to generate the mpp task type first because we don't know whether its children can be converted to mpp plan.
If we want to do the pruning completely, we'll need to change the physical opt framework itself.

Copy link
Member Author

Choose a reason for hiding this comment

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

But under the current circumstances, most users actually won't have TiFlash replicas. So when building the data source, it can quickly determine whether it contains TiFlash based on the table metadata.

@hawkingrei hawkingrei changed the title planner: improve getHashAggs | tidb-test=pr/2660 planner: add HasTiflash to avoid generating unnecessary mpp task | tidb-test=pr/2660 Dec 30, 2025
@hawkingrei
Copy link
Member Author

/retest

Copilot AI review requested due to automatic review settings January 27, 2026 05:56
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 99 out of 99 changed files in this pull request and generated 4 comments.

Comment on lines +89 to 93
func (*TiKVSingleGather) PreparePossibleProperties(_ *expression.Schema, childrenProperties ...*base.PossiblePropertiesInfo) *base.PossiblePropertiesInfo {
return &base.PossiblePropertiesInfo{
Order: childrenProperties[0].Order,
}
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

TiKVSingleGather.PreparePossibleProperties drops HasTiflash from its child (it only forwards Order). This will make upstream GetHasTiFlash() calculations incorrectly become false after a gather, potentially preventing MPP/TiFlash plan generation. Consider propagating childrenProperties[0].HasTiflash as well.

Copilot uses AI. Check for mistakes.
Comment on lines +805 to +806
// UsedHypoTiFlashReplicas is to use wether this table will use HypoTiFlashReplicas
func UsedHypoTiFlashReplicas(ctx *variable.SessionVars, dbName ast.CIStr, tblInfo *model.TableInfo) bool {
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Typo in comment: "wether" should be "whether".

Copilot uses AI. Check for mistakes.
Comment on lines +269 to +273
// SetHasTiFlashSetHasTiFlash sets whether the plan has tiflash replica.
SetHasTiFlash(hasTiFlash bool)

// GetHasTiFlash gets whether the plan has tiflash replica.
GetHasTiFlash() bool
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Doc comment has a duplicated word ("SetHasTiFlashSetHasTiFlash"). Consider renaming it to "SetHasTiFlash" for clarity.

Copilot uses AI. Check for mistakes.
Comment on lines +257 to +264
func (p *BaseLogicalPlan) PreparePossibleProperties(_ *expression.Schema, info ...*base.PossiblePropertiesInfo) *base.PossiblePropertiesInfo {
hasTiflash := true
for _, childInfo := range info {
hasTiflash = hasTiflash && childInfo.HasTiflash
}
p.hasTiflash = hasTiflash
return &base.PossiblePropertiesInfo{
HasTiflash: p.hasTiflash,
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

PreparePossibleProperties can panic when any childInfo is nil (childInfo.HasTiflash dereference). Also, returning nil here causes preparePossibleProperties() to propagate nil upwards, which can lead to nil dereferences in callers that access .Order/.HasTiflash. Consider treating nil child infos as HasTiflash=false and returning a non-nil PossiblePropertiesInfo (even when no order properties), so HasTiFlash can propagate safely through operators that rely on the base implementation.

Copilot uses AI. Check for mistakes.
@hawkingrei hawkingrei force-pushed the cannot_call_checkCanPushDownToMPP_twice branch from a227ae2 to a33dfae Compare January 28, 2026 07:06
hawkingrei and others added 21 commits January 29, 2026 23:08
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
*
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <hawking.rei@gmail.com>
@hawkingrei hawkingrei force-pushed the cannot_call_checkCanPushDownToMPP_twice branch from a33dfae to 275cff6 Compare January 29, 2026 15:08
hawkingrei and others added 2 commits January 30, 2026 00:25
Signed-off-by: Weizhen Wang <wangweizhen@pingcap.com>
Signed-off-by: Weizhen Wang <hawking.rei@gmail.com>
@tiprow
Copy link

tiprow bot commented Jan 29, 2026

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

Test name Commit Details Required Rerun command
fast_test_tiprow 74c7d31 link true /test fast_test_tiprow

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.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Jan 29, 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
idc-jenkins-ci-tidb/mysql-test 74c7d31 link true /test mysql-test
pull-mysql-client-test-next-gen 74c7d31 link true /test pull-mysql-client-test-next-gen
idc-jenkins-ci-tidb/unit-test 74c7d31 link true /test unit-test
idc-jenkins-ci-tidb/check_dev 74c7d31 link true /test check-dev
pull-unit-test-next-gen 74c7d31 link true /test pull-unit-test-next-gen
idc-jenkins-ci-tidb/check_dev_2 74c7d31 link true /test check-dev2

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

component/statistics ok-to-test Indicates a PR is ready to be tested. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wrongly generate the intermediate results for MPP in the optimizor

2 participants