From 0972a6f0129c21462eecd756b411c44e54d2ad17 Mon Sep 17 00:00:00 2001 From: lysu Date: Mon, 15 Apr 2019 16:02:27 +0800 Subject: [PATCH] planner: keep unfoldable exprs when pruning columns for ORDER BY items (#10064) --- executor/sort_test.go | 46 +++++++++++++++++++++++++++++ expression/column.go | 2 +- expression/column_test.go | 2 +- planner/core/rule_column_pruning.go | 3 ++ 4 files changed, 51 insertions(+), 2 deletions(-) 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..83da697db84ff --- /dev/null +++ b/executor/sort_test.go @@ -0,0 +1,46 @@ +// 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")) + + 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/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. 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) diff --git a/planner/core/rule_column_pruning.go b/planner/core/rule_column_pruning.go index 34f74d1eca006..77651fffef1f8 100644 --- a/planner/core/rule_column_pruning.go +++ b/planner/core/rule_column_pruning.go @@ -139,6 +139,9 @@ 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 !ls.ByItems[i].Expr.ConstItem() { + continue + } ls.ByItems = append(ls.ByItems[:i], ls.ByItems[i+1:]...) } else { parentUsedCols = append(parentUsedCols, cols...)