Skip to content

Commit 36a9810

Browse files
authored
planner: fix CTE predicate pushdown (pingcap#33627) (pingcap#33630)
close pingcap#33622
1 parent 238f79b commit 36a9810

6 files changed

+70
-4
lines changed

cmd/explaintest/r/explain_cte.result

+35
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,38 @@ CTE_0 50.00 root Non-Recursive CTE
444444
└─IndexLookUp(Probe) 1.00 root
445445
├─IndexRangeScan(Build) 1.00 cop[tikv] table:customer, index:PRIMARY(c_customer_sk) range: decided by [eq(test.customer.c_customer_sk, test.web_sales.ws_bill_customer_sk)], keep order:false, stats:pseudo
446446
└─TableRowIDScan(Probe) 1.00 cop[tikv] table:customer keep order:false, stats:pseudo
447+
drop table if exists t1;
448+
create table t1 (id int, bench_type varchar(10),version varchar(10),tps int(20));
449+
insert into t1 (id,bench_type,version,tps) values (1,'sysbench','5.4.0',1111111);
450+
insert into t1 (id,bench_type,version,tps) values (2,'sysbench','6.0.0',222222);
451+
with all_data as
452+
(select * from t1
453+
),version1 as (select * from all_data where version ='5.4.0'
454+
),version2 as(select * from all_data where version ='6.0.0')
455+
select v1.tps v1_tps,v2.tps v2_tps
456+
from version1 v1, version2 v2
457+
where v1.bench_type =v2.bench_type;
458+
v1_tps v2_tps
459+
1111111 222222
460+
desc format='brief' with all_data as
461+
(select * from t1
462+
),version1 as (select * from all_data where version ='5.4.0'
463+
),version2 as(select * from all_data where version ='6.0.0')
464+
select v1.tps v1_tps,v2.tps v2_tps
465+
from version1 v1, version2 v2
466+
where v1.bench_type =v2.bench_type;
467+
id estRows task access object operator info
468+
HashJoin 8000.00 root inner join, equal:[eq(test.t1.bench_type, test.t1.bench_type)]
469+
├─Selection(Build) 6400.00 root not(isnull(test.t1.bench_type))
470+
│ └─CTEFullScan 8000.00 root CTE:v2 data:CTE_2
471+
└─Selection(Probe) 6400.00 root not(isnull(test.t1.bench_type))
472+
└─CTEFullScan 8000.00 root CTE:v1 data:CTE_1
473+
CTE_2 8000.00 root Non-Recursive CTE
474+
└─Selection(Seed Part) 8000.00 root eq(test.t1.version, "6.0.0"), not(isnull(test.t1.bench_type))
475+
└─CTEFullScan 10000.00 root CTE:all_data data:CTE_0
476+
CTE_1 8000.00 root Non-Recursive CTE
477+
└─Selection(Seed Part) 8000.00 root eq(test.t1.version, "5.4.0"), not(isnull(test.t1.bench_type))
478+
└─CTEFullScan 10000.00 root CTE:all_data data:CTE_0
479+
CTE_0 10000.00 root Non-Recursive CTE
480+
└─TableReader(Seed Part) 10000.00 root data:TableFullScan
481+
└─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo

cmd/explaintest/t/explain_cte.test

+20
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,23 @@ desc format='brief' with year_total as (
237237
,t_s_secyear.customer_last_name
238238
,t_s_secyear.customer_email_address
239239
limit 100;
240+
241+
# predicate pushdown
242+
drop table if exists t1;
243+
create table t1 (id int, bench_type varchar(10),version varchar(10),tps int(20));
244+
insert into t1 (id,bench_type,version,tps) values (1,'sysbench','5.4.0',1111111);
245+
insert into t1 (id,bench_type,version,tps) values (2,'sysbench','6.0.0',222222);
246+
with all_data as
247+
(select * from t1
248+
),version1 as (select * from all_data where version ='5.4.0'
249+
),version2 as(select * from all_data where version ='6.0.0')
250+
select v1.tps v1_tps,v2.tps v2_tps
251+
from version1 v1, version2 v2
252+
where v1.bench_type =v2.bench_type;
253+
desc format='brief' with all_data as
254+
(select * from t1
255+
),version1 as (select * from all_data where version ='5.4.0'
256+
),version2 as(select * from all_data where version ='6.0.0')
257+
select v1.tps v1_tps,v2.tps v2_tps
258+
from version1 v1, version2 v2
259+
where v1.bench_type =v2.bench_type;

planner/core/logical_plan_builder.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -3935,7 +3935,7 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName
39353935
LimitEnd: limitEnd, pushDownPredicates: make([]expression.Expression, 0), ColumnMap: make(map[string]*expression.Column)}
39363936
}
39373937
var p LogicalPlan
3938-
lp := LogicalCTE{cteAsName: tn.Name, cte: cte.cteClass, seedStat: cte.seedStat}.Init(b.ctx, b.getSelectOffset())
3938+
lp := LogicalCTE{cteAsName: tn.Name, cte: cte.cteClass, seedStat: cte.seedStat, isOuterMostCTE: !b.buildingCTE}.Init(b.ctx, b.getSelectOffset())
39393939
prevSchema := cte.seedLP.Schema().Clone()
39403940
lp.SetSchema(getResultCTESchema(cte.seedLP.Schema(), b.ctx.GetSessionVars()))
39413941
for i, col := range lp.schema.Columns {
@@ -6383,6 +6383,12 @@ func containDifferentJoinTypes(preferJoinType uint) bool {
63836383
}
63846384

63856385
func (b *PlanBuilder) buildCte(ctx context.Context, cte *ast.CommonTableExpression, isRecursive bool) (p LogicalPlan, err error) {
6386+
saveBuildingCTE := b.buildingCTE
6387+
b.buildingCTE = true
6388+
defer func() {
6389+
b.buildingCTE = saveBuildingCTE
6390+
}()
6391+
63866392
if isRecursive {
63876393
// buildingRecursivePartForCTE likes a stack. We save it before building a recursive CTE and restore it after building.
63886394
// We need a stack because we need to handle the nested recursive CTE. And buildingRecursivePartForCTE indicates the innermost CTE.

planner/core/logical_plans.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -1786,9 +1786,10 @@ type CTEClass struct {
17861786
type LogicalCTE struct {
17871787
logicalSchemaProducer
17881788

1789-
cte *CTEClass
1790-
cteAsName model.CIStr
1791-
seedStat *property.StatsInfo
1789+
cte *CTEClass
1790+
cteAsName model.CIStr
1791+
seedStat *property.StatsInfo
1792+
isOuterMostCTE bool
17921793
}
17931794

17941795
// LogicalCTETable is for CTE table

planner/core/planbuilder.go

+1
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ type PlanBuilder struct {
499499
isForUpdateRead bool
500500
allocIDForCTEStorage int
501501
buildingRecursivePartForCTE bool
502+
buildingCTE bool
502503
}
503504

504505
type handleColHelper struct {

planner/core/rule_predicate_push_down.go

+3
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,9 @@ func (p *LogicalCTE) PredicatePushDown(predicates []expression.Expression, opt *
933933
// Doesn't support recursive CTE yet.
934934
return predicates, p.self
935935
}
936+
if !p.isOuterMostCTE {
937+
return predicates, p.self
938+
}
936939
if len(predicates) == 0 {
937940
p.cte.pushDownPredicates = append(p.cte.pushDownPredicates, expression.NewOne())
938941
return predicates, p.self

0 commit comments

Comments
 (0)