From 5eb41eb43102be28a999843f9f181a4a64423d35 Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 8 Apr 2019 14:59:55 +0800 Subject: [PATCH 1/5] planner: scalar function `rand` skip pruning --- executor/sort_test.go | 38 +++++++++++++++++++++++++++++ planner/core/rule_column_pruning.go | 5 ++++ 2 files changed, 43 insertions(+) create mode 100644 executor/sort_test.go diff --git a/executor/sort_test.go b/executor/sort_test.go new file mode 100644 index 0000000000000..464189157b61f --- /dev/null +++ b/executor/sort_test.go @@ -0,0 +1,38 @@ +// Copyright 2019 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor_test + +import ( + . "github.com/pingcap/check" + "github.com/pingcap/tidb/util/testkit" +) + +func (s *testSuite2) TestSortRand(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int);") + + tk.MustQuery("explain select a from t order by rand()").Check(testkit.Rows( + "Projection_8 10000.00 root test.t.a", + "└─Sort_4 10000.00 root col_1:asc", + " └─Projection_9 10000.00 root test.t.a, rand()", + " └─TableReader_7 10000.00 root data:TableScan_6", + " └─TableScan_6 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo", + )) + + tk.MustQuery("explain select a, b from t order by abs(2)").Check(testkit.Rows( + "TableReader_8 10000.00 root data:TableScan_7", + "└─TableScan_7 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo")) +} diff --git a/planner/core/rule_column_pruning.go b/planner/core/rule_column_pruning.go index 34f74d1eca006..385a69ab03f2d 100644 --- a/planner/core/rule_column_pruning.go +++ b/planner/core/rule_column_pruning.go @@ -139,6 +139,11 @@ func (ls *LogicalSort) PruneColumns(parentUsedCols []*expression.Column) error { for i := len(ls.ByItems) - 1; i >= 0; i-- { cols := expression.ExtractColumns(ls.ByItems[i].Expr) if len(cols) == 0 { + if sf, ok := ls.ByItems[i].Expr.(*expression.ScalarFunction); ok { + if sf.FuncName.L == "rand" { + continue + } + } ls.ByItems = append(ls.ByItems[:i], ls.ByItems[i+1:]...) } else { parentUsedCols = append(parentUsedCols, cols...) From 0b2244e2090e5b38c57e7b4995f1f3f7861ee8ce Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 15 Apr 2019 14:17:26 +0800 Subject: [PATCH 2/5] use ConstItem to determine pruning --- executor/sort_test.go | 8 ++++++++ planner/core/rule_column_pruning.go | 6 ++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/executor/sort_test.go b/executor/sort_test.go index 464189157b61f..83da697db84ff 100644 --- a/executor/sort_test.go +++ b/executor/sort_test.go @@ -35,4 +35,12 @@ func (s *testSuite2) TestSortRand(c *C) { tk.MustQuery("explain select a, b from t order by abs(2)").Check(testkit.Rows( "TableReader_8 10000.00 root data:TableScan_7", "└─TableScan_7 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo")) + + tk.MustQuery("explain select a from t order by abs(rand())+1").Check(testkit.Rows( + "Projection_8 10000.00 root test.t.a", + "└─Sort_4 10000.00 root col_1:asc", + " └─Projection_9 10000.00 root test.t.a, plus(abs(rand()), 1)", + " └─TableReader_7 10000.00 root data:TableScan_6", + " └─TableScan_6 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo", + )) } diff --git a/planner/core/rule_column_pruning.go b/planner/core/rule_column_pruning.go index 385a69ab03f2d..77651fffef1f8 100644 --- a/planner/core/rule_column_pruning.go +++ b/planner/core/rule_column_pruning.go @@ -139,10 +139,8 @@ func (ls *LogicalSort) PruneColumns(parentUsedCols []*expression.Column) error { for i := len(ls.ByItems) - 1; i >= 0; i-- { cols := expression.ExtractColumns(ls.ByItems[i].Expr) if len(cols) == 0 { - if sf, ok := ls.ByItems[i].Expr.(*expression.ScalarFunction); ok { - if sf.FuncName.L == "rand" { - continue - } + if !ls.ByItems[i].Expr.ConstItem() { + continue } ls.ByItems = append(ls.ByItems[:i], ls.ByItems[i+1:]...) } else { From d7c67b3aff641fa77226376708a83097a84f9b9c Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 15 Apr 2019 14:31:38 +0800 Subject: [PATCH 3/5] fix case --- cmd/explaintest/r/topn_push_down.result | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/explaintest/r/topn_push_down.result b/cmd/explaintest/r/topn_push_down.result index eff152a4d793e..922f60f5d92ad 100644 --- a/cmd/explaintest/r/topn_push_down.result +++ b/cmd/explaintest/r/topn_push_down.result @@ -194,16 +194,16 @@ create table t1(a bigint, b bigint); create table t2(a bigint, b bigint); desc select * from t1 where t1.a in (select t2.a as a from t2 where t2.b > t1.b order by t1.b limit 1); id count task operator info -Apply_15 9990.00 root semi join, inner:Selection_19, equal:[eq(test.t1.a, test.t2.a)] -├─TableReader_18 9990.00 root data:Selection_17 -│ └─Selection_17 9990.00 cop not(isnull(test.t1.a)) -│ └─TableScan_16 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo -└─Selection_19 0.80 root not(isnull(test.t2.a)) - └─Limit_20 1.00 root offset:0, count:1 - └─TableReader_26 1.00 root data:Limit_25 - └─Limit_25 1.00 cop offset:0, count:1 - └─Selection_24 1.00 cop gt(test.t2.b, test.t1.b) - └─TableScan_23 1.25 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo +Apply_14 9990.00 root semi join, inner:Selection_18, equal:[eq(test.t1.a, test.t2.a)] +├─TableReader_17 9990.00 root data:Selection_16 +│ └─Selection_16 9990.00 cop not(isnull(test.t1.a)) +│ └─TableScan_15 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo +└─Selection_18 0.80 root not(isnull(test.t2.a)) + └─TopN_19 1.00 root test.t1.b:asc, offset:0, count:1 + └─TableReader_25 1.00 root data:TopN_24 + └─TopN_24 1.00 cop test.t1.b:asc, offset:0, count:1 + └─Selection_23 8000.00 cop gt(test.t2.b, test.t1.b) + └─TableScan_22 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo desc select * from t1 where t1.a in (select a from (select t2.a as a, t1.b as b from t2 where t2.b > t1.b) x order by b limit 1); id count task operator info Apply_17 9990.00 root semi join, inner:Selection_21, equal:[eq(test.t1.a, x.a)] From e1efc281a7a4218f4fe4f0d7c1901ef59a649923 Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 15 Apr 2019 15:15:38 +0800 Subject: [PATCH 4/5] fix CorrelatedColumn's ConstItem --- cmd/explaintest/r/topn_push_down.result | 20 ++++++++++---------- expression/column.go | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/explaintest/r/topn_push_down.result b/cmd/explaintest/r/topn_push_down.result index 922f60f5d92ad..eff152a4d793e 100644 --- a/cmd/explaintest/r/topn_push_down.result +++ b/cmd/explaintest/r/topn_push_down.result @@ -194,16 +194,16 @@ create table t1(a bigint, b bigint); create table t2(a bigint, b bigint); desc select * from t1 where t1.a in (select t2.a as a from t2 where t2.b > t1.b order by t1.b limit 1); id count task operator info -Apply_14 9990.00 root semi join, inner:Selection_18, equal:[eq(test.t1.a, test.t2.a)] -├─TableReader_17 9990.00 root data:Selection_16 -│ └─Selection_16 9990.00 cop not(isnull(test.t1.a)) -│ └─TableScan_15 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo -└─Selection_18 0.80 root not(isnull(test.t2.a)) - └─TopN_19 1.00 root test.t1.b:asc, offset:0, count:1 - └─TableReader_25 1.00 root data:TopN_24 - └─TopN_24 1.00 cop test.t1.b:asc, offset:0, count:1 - └─Selection_23 8000.00 cop gt(test.t2.b, test.t1.b) - └─TableScan_22 10000.00 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo +Apply_15 9990.00 root semi join, inner:Selection_19, equal:[eq(test.t1.a, test.t2.a)] +├─TableReader_18 9990.00 root data:Selection_17 +│ └─Selection_17 9990.00 cop not(isnull(test.t1.a)) +│ └─TableScan_16 10000.00 cop table:t1, range:[-inf,+inf], keep order:false, stats:pseudo +└─Selection_19 0.80 root not(isnull(test.t2.a)) + └─Limit_20 1.00 root offset:0, count:1 + └─TableReader_26 1.00 root data:Limit_25 + └─Limit_25 1.00 cop offset:0, count:1 + └─Selection_24 1.00 cop gt(test.t2.b, test.t1.b) + └─TableScan_23 1.25 cop table:t2, range:[-inf,+inf], keep order:false, stats:pseudo desc select * from t1 where t1.a in (select a from (select t2.a as a, t1.b as b from t2 where t2.b > t1.b) x order by b limit 1); id count task operator info Apply_17 9990.00 root semi join, inner:Selection_21, equal:[eq(test.t1.a, x.a)] diff --git a/expression/column.go b/expression/column.go index 1c4ec9ab49bda..99b94e0ea4414 100644 --- a/expression/column.go +++ b/expression/column.go @@ -125,7 +125,7 @@ func (col *CorrelatedColumn) IsCorrelated() bool { // ConstItem implements Expression interface. func (col *CorrelatedColumn) ConstItem() bool { - return false + return true } // Decorrelate implements Expression interface. From d3debcc0c8428ee5aca4161dde6c85eabf600bea Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 15 Apr 2019 15:21:06 +0800 Subject: [PATCH 5/5] fix case -- --- expression/column_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/column_test.go b/expression/column_test.go index 5f0ffdb2c9b46..6d8e04e754227 100644 --- a/expression/column_test.go +++ b/expression/column_test.go @@ -43,7 +43,7 @@ func (s *testEvaluatorSuite) TestColumn(c *C) { c.Assert(corCol.Equal(nil, corCol), IsTrue) c.Assert(corCol.Equal(nil, invalidCorCol), IsFalse) c.Assert(corCol.IsCorrelated(), IsTrue) - c.Assert(corCol.ConstItem(), IsFalse) + c.Assert(corCol.ConstItem(), IsTrue) c.Assert(corCol.Decorrelate(schema).Equal(nil, col), IsTrue) c.Assert(invalidCorCol.Decorrelate(schema).Equal(nil, invalidCorCol), IsTrue)