From 6959b5fa08e07e621ca713f69d644e9f2c4ad7a9 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 31 Mar 2022 17:02:55 +0800 Subject: [PATCH 1/2] done Signed-off-by: wjhuang2016 --- cmd/explaintest/r/explain_cte.result | 13 +++++++++++++ cmd/explaintest/t/explain_cte.test | 14 ++++++++++++++ planner/core/logical_plan_builder.go | 8 +++++++- planner/core/logical_plans.go | 7 ++++--- planner/core/planbuilder.go | 1 + planner/core/rule_predicate_push_down.go | 3 +++ 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/cmd/explaintest/r/explain_cte.result b/cmd/explaintest/r/explain_cte.result index 241cf76bf001f..250ecc9209be4 100644 --- a/cmd/explaintest/r/explain_cte.result +++ b/cmd/explaintest/r/explain_cte.result @@ -444,3 +444,16 @@ CTE_0 50.00 root Non-Recursive CTE └─IndexLookUp(Probe) 1.00 root ├─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 └─TableRowIDScan(Probe) 1.00 cop[tikv] table:customer keep order:false, stats:pseudo +drop table if exists t1; +create table t1 (id int, bench_type varchar(10),version varchar(10),tps int(20)); +insert into t1 (id,bench_type,version,tps) values (1,'sysbench','5.4.0',1111111); +insert into t1 (id,bench_type,version,tps) values (2,'sysbench','6.0.0',222222); +with all_data as +(select * from t1 +),version1 as (select * from all_data where version ='5.4.0' +),version2 as(select * from all_data where version ='6.0.0') +select v1.tps v1_tps,v2.tps v2_tps +from version1 v1, version2 v2 +where v1.bench_type =v2.bench_type; +v1_tps v2_tps +1111111 222222 diff --git a/cmd/explaintest/t/explain_cte.test b/cmd/explaintest/t/explain_cte.test index c7adb659d9cea..12231e94a683f 100644 --- a/cmd/explaintest/t/explain_cte.test +++ b/cmd/explaintest/t/explain_cte.test @@ -237,3 +237,17 @@ desc format='brief' with year_total as ( ,t_s_secyear.customer_last_name ,t_s_secyear.customer_email_address limit 100; + + +# predicate pushdown +drop table if exists t1; +create table t1 (id int, bench_type varchar(10),version varchar(10),tps int(20)); +insert into t1 (id,bench_type,version,tps) values (1,'sysbench','5.4.0',1111111); +insert into t1 (id,bench_type,version,tps) values (2,'sysbench','6.0.0',222222); +with all_data as +(select * from t1 +),version1 as (select * from all_data where version ='5.4.0' +),version2 as(select * from all_data where version ='6.0.0') +select v1.tps v1_tps,v2.tps v2_tps +from version1 v1, version2 v2 +where v1.bench_type =v2.bench_type; diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index a0a3cb1687002..ee8231be41c30 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -3935,7 +3935,7 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName LimitEnd: limitEnd, pushDownPredicates: make([]expression.Expression, 0), ColumnMap: make(map[string]*expression.Column)} } var p LogicalPlan - lp := LogicalCTE{cteAsName: tn.Name, cte: cte.cteClass, seedStat: cte.seedStat}.Init(b.ctx, b.getSelectOffset()) + lp := LogicalCTE{cteAsName: tn.Name, cte: cte.cteClass, seedStat: cte.seedStat, isOuterMostCTE: !b.buildingCTE}.Init(b.ctx, b.getSelectOffset()) prevSchema := cte.seedLP.Schema().Clone() lp.SetSchema(getResultCTESchema(cte.seedLP.Schema(), b.ctx.GetSessionVars())) for i, col := range lp.schema.Columns { @@ -6386,6 +6386,12 @@ func containDifferentJoinTypes(preferJoinType uint) bool { } func (b *PlanBuilder) buildCte(ctx context.Context, cte *ast.CommonTableExpression, isRecursive bool) (p LogicalPlan, err error) { + saveBuildingCTE := b.buildingCTE + b.buildingCTE = true + defer func() { + b.buildingCTE = saveBuildingCTE + }() + if isRecursive { // buildingRecursivePartForCTE likes a stack. We save it before building a recursive CTE and restore it after building. // We need a stack because we need to handle the nested recursive CTE. And buildingRecursivePartForCTE indicates the innermost CTE. diff --git a/planner/core/logical_plans.go b/planner/core/logical_plans.go index 896f9b60edc71..38502297ba400 100644 --- a/planner/core/logical_plans.go +++ b/planner/core/logical_plans.go @@ -1786,9 +1786,10 @@ type CTEClass struct { type LogicalCTE struct { logicalSchemaProducer - cte *CTEClass - cteAsName model.CIStr - seedStat *property.StatsInfo + cte *CTEClass + cteAsName model.CIStr + seedStat *property.StatsInfo + isOuterMostCTE bool } // LogicalCTETable is for CTE table diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 335a7b44340c6..d933589351d17 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -499,6 +499,7 @@ type PlanBuilder struct { isForUpdateRead bool allocIDForCTEStorage int buildingRecursivePartForCTE bool + buildingCTE bool } type handleColHelper struct { diff --git a/planner/core/rule_predicate_push_down.go b/planner/core/rule_predicate_push_down.go index 82201b74d8f92..9d060ce2bb166 100644 --- a/planner/core/rule_predicate_push_down.go +++ b/planner/core/rule_predicate_push_down.go @@ -933,6 +933,9 @@ func (p *LogicalCTE) PredicatePushDown(predicates []expression.Expression, opt * // Doesn't support recursive CTE yet. return predicates, p.self } + if !p.isOuterMostCTE { + return predicates, p.self + } if len(predicates) == 0 { p.cte.pushDownPredicates = append(p.cte.pushDownPredicates, expression.NewOne()) return predicates, p.self From 31d74b3729d87b27950f471b7f8095db9f990e50 Mon Sep 17 00:00:00 2001 From: wjhuang2016 Date: Thu, 31 Mar 2022 17:28:25 +0800 Subject: [PATCH 2/2] add explain Signed-off-by: wjhuang2016 --- cmd/explaintest/r/explain_cte.result | 22 ++++++++++++++++++++++ cmd/explaintest/t/explain_cte.test | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/cmd/explaintest/r/explain_cte.result b/cmd/explaintest/r/explain_cte.result index 250ecc9209be4..cc8804b4fc077 100644 --- a/cmd/explaintest/r/explain_cte.result +++ b/cmd/explaintest/r/explain_cte.result @@ -457,3 +457,25 @@ from version1 v1, version2 v2 where v1.bench_type =v2.bench_type; v1_tps v2_tps 1111111 222222 +desc format='brief' with all_data as +(select * from t1 +),version1 as (select * from all_data where version ='5.4.0' +),version2 as(select * from all_data where version ='6.0.0') +select v1.tps v1_tps,v2.tps v2_tps +from version1 v1, version2 v2 +where v1.bench_type =v2.bench_type; +id estRows task access object operator info +HashJoin 8000.00 root inner join, equal:[eq(test.t1.bench_type, test.t1.bench_type)] +├─Selection(Build) 6400.00 root not(isnull(test.t1.bench_type)) +│ └─CTEFullScan 8000.00 root CTE:v2 data:CTE_2 +└─Selection(Probe) 6400.00 root not(isnull(test.t1.bench_type)) + └─CTEFullScan 8000.00 root CTE:v1 data:CTE_1 +CTE_2 8000.00 root Non-Recursive CTE +└─Selection(Seed Part) 8000.00 root eq(test.t1.version, "6.0.0"), not(isnull(test.t1.bench_type)) + └─CTEFullScan 10000.00 root CTE:all_data data:CTE_0 +CTE_1 8000.00 root Non-Recursive CTE +└─Selection(Seed Part) 8000.00 root eq(test.t1.version, "5.4.0"), not(isnull(test.t1.bench_type)) + └─CTEFullScan 10000.00 root CTE:all_data data:CTE_0 +CTE_0 10000.00 root Non-Recursive CTE +└─TableReader(Seed Part) 10000.00 root data:TableFullScan + └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo diff --git a/cmd/explaintest/t/explain_cte.test b/cmd/explaintest/t/explain_cte.test index 12231e94a683f..fd6ba042c9fed 100644 --- a/cmd/explaintest/t/explain_cte.test +++ b/cmd/explaintest/t/explain_cte.test @@ -251,3 +251,10 @@ with all_data as select v1.tps v1_tps,v2.tps v2_tps from version1 v1, version2 v2 where v1.bench_type =v2.bench_type; +desc format='brief' with all_data as +(select * from t1 +),version1 as (select * from all_data where version ='5.4.0' +),version2 as(select * from all_data where version ='6.0.0') +select v1.tps v1_tps,v2.tps v2_tps +from version1 v1, version2 v2 +where v1.bench_type =v2.bench_type;