From 880a9b03747456bc3a384a9fbcd0553d45bd352d Mon Sep 17 00:00:00 2001 From: Kenan Yao Date: Tue, 25 Feb 2020 20:34:30 +0800 Subject: [PATCH] planner: fold constant in projection elimination and TopN push down (#14927) --- cmd/explaintest/r/explain_easy.result | 20 +++++++++----------- cmd/explaintest/r/topn_pushdown.result | 2 +- planner/core/integration_test.go | 8 ++++++++ planner/core/rule_eliminate_projection.go | 2 +- planner/core/rule_topn_push_down.go | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/cmd/explaintest/r/explain_easy.result b/cmd/explaintest/r/explain_easy.result index 9a98707cf9689..d1125f746264a 100644 --- a/cmd/explaintest/r/explain_easy.result +++ b/cmd/explaintest/r/explain_easy.result @@ -506,17 +506,15 @@ EXPLAIN SELECT COUNT(1) FROM (SELECT COALESCE(b.region_name, '不详') region_na id count task operator info StreamAgg_22 1.00 root funcs:count(1)->Column#22 └─HashAgg_25 1.00 root group by:Column#32, Column#33, Column#34, funcs:firstrow(1)->Column#31 - └─Projection_48 0.02 root Column#14, Column#15, coalesce(test.test02.region_name, 不详)->Column#34 - └─IndexMergeJoin_32 0.02 root left outer join, inner:TableReader_30, outer key:Column#16, inner key:test.test02.id - ├─Union_37 0.02 root - │ ├─Projection_38 0.01 root test.test01.stat_date, test.test01.show_date, test.test01.region_id - │ │ └─TableReader_41 0.01 root data:Selection_40 - │ │ └─Selection_40 0.01 cop[tikv] eq(test.test01.period, 1), ge(test.test01.stat_date, 20191202), ge(test.test01.stat_date, 20191202), gt(cast(0), 0), le(test.test01.stat_date, 20191202), le(test.test01.stat_date, 20191202) - │ │ └─TableFullScan_39 10000.00 cop[tikv] table:test01, keep order:false, stats:pseudo - │ └─Projection_42 0.01 root test.test01.stat_date, test.test01.show_date, test.test01.region_id - │ └─TableReader_45 0.01 root data:Selection_44 - │ └─Selection_44 0.01 cop[tikv] eq(test.test01.period, 1), ge(test.test01.stat_date, 20191202), ge(test.test01.stat_date, 20191202), gt(cast(test.test01.registration_num), 0), le(test.test01.stat_date, 20191202), le(test.test01.stat_date, 20191202) - │ └─TableFullScan_43 10000.00 cop[tikv] table:test01, keep order:false, stats:pseudo + └─Projection_46 0.01 root Column#14, Column#15, coalesce(test.test02.region_name, 不详)->Column#34 + └─IndexMergeJoin_32 0.01 root left outer join, inner:TableReader_30, outer key:Column#16, inner key:test.test02.id + ├─Union_37 0.01 root + │ ├─Projection_38 0.00 root test.test01.stat_date, test.test01.show_date, test.test01.region_id + │ │ └─TableDual_39 0.00 root rows:0 + │ └─Projection_40 0.01 root test.test01.stat_date, test.test01.show_date, test.test01.region_id + │ └─TableReader_43 0.01 root data:Selection_42 + │ └─Selection_42 0.01 cop[tikv] eq(test.test01.period, 1), ge(test.test01.stat_date, 20191202), ge(test.test01.stat_date, 20191202), gt(cast(test.test01.registration_num), 0), le(test.test01.stat_date, 20191202), le(test.test01.stat_date, 20191202) + │ └─TableFullScan_41 10000.00 cop[tikv] table:test01, keep order:false, stats:pseudo └─TableReader_30 1.00 root data:TableRangeScan_29 └─TableRangeScan_29 1.00 cop[tikv] table:b, range: decided by [Column#16], keep order:true, stats:pseudo drop table if exists t; diff --git a/cmd/explaintest/r/topn_pushdown.result b/cmd/explaintest/r/topn_pushdown.result index 47d876a60c149..ad86dde957ef7 100644 --- a/cmd/explaintest/r/topn_pushdown.result +++ b/cmd/explaintest/r/topn_pushdown.result @@ -2,7 +2,7 @@ explain select * from ((select 4 as a) union all (select 33 as a)) tmp order by id count task operator info TopN_17 1.00 root Column#3:desc, offset:0, count:1 └─Union_21 2.00 root - ├─Projection_22 1.00 root cast(4)->Column#3 + ├─Projection_22 1.00 root 4->Column#3 │ └─TableDual_23 1.00 root rows:1 └─Projection_24 1.00 root 33->Column#3 └─TableDual_25 1.00 root rows:1 diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 556e372b717c4..5c66457d474f9 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -506,3 +506,11 @@ func (s *testIntegrationSuite) TestIndexMerge(c *C) { tk.MustQuery(tt).Check(testkit.Rows(output[i].Plan...)) } } + +func (s *testIntegrationSuite) TestTopNByConstFunc(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustQuery("select max(t.col) from (select 'a' as col union all select '' as col) as t").Check(testkit.Rows( + "a", + )) +} diff --git a/planner/core/rule_eliminate_projection.go b/planner/core/rule_eliminate_projection.go index 9b286c815b2a5..404c5e01dd77c 100644 --- a/planner/core/rule_eliminate_projection.go +++ b/planner/core/rule_eliminate_projection.go @@ -144,7 +144,7 @@ func (pe *projectionEliminator) eliminate(p LogicalPlan, replace map[string]*exp if isProj { if child, ok := p.Children()[0].(*LogicalProjection); ok && !ExprsHasSideEffects(child.Exprs) { for i := range proj.Exprs { - proj.Exprs[i] = ReplaceColumnOfExpr(proj.Exprs[i], child, child.Schema()) + proj.Exprs[i] = expression.FoldConstant(ReplaceColumnOfExpr(proj.Exprs[i], child, child.Schema())) } p.Children()[0] = child.Children()[0] } diff --git a/planner/core/rule_topn_push_down.go b/planner/core/rule_topn_push_down.go index ad01d191ac658..53663713ef17a 100644 --- a/planner/core/rule_topn_push_down.go +++ b/planner/core/rule_topn_push_down.go @@ -114,7 +114,7 @@ func (p *LogicalProjection) pushDownTopN(topN *LogicalTopN) LogicalPlan { } if topN != nil { for _, by := range topN.ByItems { - by.Expr = expression.ColumnSubstitute(by.Expr, p.schema, p.Exprs) + by.Expr = expression.FoldConstant(expression.ColumnSubstitute(by.Expr, p.schema, p.Exprs)) } // remove meaningless constant sort items.