Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: fix can't find proper physical plan caused by virtual column (#41132) #41243

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions executor/tiflashtest/tiflash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,33 @@ func TestGroupStreamAggOnTiFlash(t *testing.T) {
}
}

// TestIssue41014 test issue that can't find proper physical plan
func TestIssue41014(t *testing.T) {
store := testkit.CreateMockStore(t, withMockTiFlash(2))
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test;")
tk.MustExec("CREATE TABLE `tai1` (\n `aid` int(11) DEFAULT NULL,\n `rid` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")
tk.MustExec("CREATE TABLE `tai2` (\n `rid` int(11) DEFAULT NULL,\n `prilan` varchar(20) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")
tk.MustExec("alter table tai1 set tiflash replica 1")
tk.MustExec("alter table tai2 set tiflash replica 1")
tk.MustExec("alter table tai2 add index idx((lower(prilan)));")
tk.MustExec("set @@tidb_opt_distinct_agg_push_down = 1;")

tk.MustQuery("explain select count(distinct tai1.aid) as cb from tai1 inner join tai2 on tai1.rid = tai2.rid where lower(prilan) LIKE LOWER('%python%');").Check(
testkit.Rows("HashAgg_11 1.00 root funcs:count(distinct test.tai1.aid)->Column#8",
"└─HashJoin_15 9990.00 root inner join, equal:[eq(test.tai2.rid, test.tai1.rid)]",
" ├─Selection_20(Build) 8000.00 root like(lower(test.tai2.prilan), \"%python%\", 92)",
" │ └─Projection_19 10000.00 root test.tai2.rid, lower(test.tai2.prilan)",
" │ └─TableReader_18 9990.00 root data:Selection_17",
" │ └─Selection_17 9990.00 cop[tikv] not(isnull(test.tai2.rid))",
" │ └─TableFullScan_16 10000.00 cop[tikv] table:tai2 keep order:false, stats:pseudo",
" └─TableReader_23(Probe) 9990.00 root data:Selection_22",
" └─Selection_22 9990.00 cop[tikv] not(isnull(test.tai1.rid))",
" └─TableFullScan_21 10000.00 cop[tikv] table:tai1 keep order:false, stats:pseudo"))
tk.MustQuery("select count(distinct tai1.aid) as cb from tai1 inner join tai2 on tai1.rid = tai2.rid where lower(prilan) LIKE LOWER('%python%');").Check(
testkit.Rows("0"))
}

func TestTiflashEmptyDynamicPruneResult(t *testing.T) {
store := testkit.CreateMockStore(t, withMockTiFlash(2))
tk := testkit.NewTestKit(t, store)
Expand Down
17 changes: 15 additions & 2 deletions planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -2682,7 +2682,9 @@ func (la *LogicalAggregation) getStreamAggs(prop *property.PhysicalProperty) []P
if la.HasDistinct() {
// TODO: remove AllowDistinctAggPushDown after the cost estimation of distinct pushdown is implemented.
// If AllowDistinctAggPushDown is set to true, we should not consider RootTask.
if !la.ctx.GetSessionVars().AllowDistinctAggPushDown {
if !la.ctx.GetSessionVars().AllowDistinctAggPushDown || !la.canPushToCop(kv.TiKV) {
// if variable doesn't allow DistinctAggPushDown, just produce root task type.
// if variable does allow DistinctAggPushDown, but OP itself can't be pushed down to tikv, just produce root task type.
taskTypes = []property.TaskType{property.RootTaskType}
} else if !la.distinctArgsMeetsProperty() {
continue
Expand Down Expand Up @@ -2831,6 +2833,15 @@ func (la *LogicalAggregation) tryToGetMppHashAggs(prop *property.PhysicalPropert
return
}

// getHashAggs will generate some kinds of taskType here, which finally converted to different task plan.
// when deciding whether to add a kind of taskType, there is a rule here. [Not is Not, Yes is not Sure]
// eg: which means
//
// 1: when you find something here that block hashAgg to be pushed down to XXX, just skip adding the XXXTaskType.
// 2: when you find nothing here to block hashAgg to be pushed down to XXX, just add the XXXTaskType here.
// for 2, the final result for this physical operator enumeration is chosen or rejected is according to more factors later (hint/variable/partition/virtual-col/cost)
//
// That is to say, the non-complete positive judgement of canPushDownToMPP/canPushDownToTiFlash/canPushDownToTiKV is not that for sure here.
func (la *LogicalAggregation) getHashAggs(prop *property.PhysicalProperty) []PhysicalPlan {
if !prop.IsSortItemEmpty() {
return nil
Expand All @@ -2844,7 +2855,9 @@ func (la *LogicalAggregation) getHashAggs(prop *property.PhysicalProperty) []Phy
canPushDownToMPP := canPushDownToTiFlash && la.ctx.GetSessionVars().IsMPPAllowed() && la.checkCanPushDownToMPP()
if la.HasDistinct() {
// TODO: remove after the cost estimation of distinct pushdown is implemented.
if !la.ctx.GetSessionVars().AllowDistinctAggPushDown {
if !la.ctx.GetSessionVars().AllowDistinctAggPushDown || !la.canPushToCop(kv.TiKV) {
// if variable doesn't allow DistinctAggPushDown, just produce root task type.
// if variable does allow DistinctAggPushDown, but OP itself can't be pushed down to tikv, just produce root task type.
taskTypes = []property.TaskType{property.RootTaskType}
}
} else if !la.aggHints.preferAggToCop {
Expand Down