From 0db5df550b65677006567ca1aff0df4fdca64141 Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Mon, 12 Jul 2021 16:01:32 +0800 Subject: [PATCH] planner: rename stable-result-mode to ordered-result-mode (#26093) --- executor/set_test.go | 18 ++--- planner/core/optimizer.go | 2 +- ...lize_results.go => rule_result_reorder.go} | 28 ++++---- ...ts_test.go => rule_result_reorder_test.go} | 72 +++++++++---------- ...json => ordered_result_mode_suite_in.json} | 12 ++-- ...son => ordered_result_mode_suite_out.json} | 12 ++-- sessionctx/variable/sysvar.go | 2 +- sessionctx/variable/tidb_vars.go | 6 +- 8 files changed, 76 insertions(+), 76 deletions(-) rename planner/core/{rule_stabilize_results.go => rule_result_reorder.go} (81%) rename planner/core/{rule_stabilize_results_test.go => rule_result_reorder_test.go} (76%) rename planner/core/testdata/{stable_result_mode_suite_in.json => ordered_result_mode_suite_in.json} (92%) rename planner/core/testdata/{stable_result_mode_suite_out.json => ordered_result_mode_suite_out.json} (98%) diff --git a/executor/set_test.go b/executor/set_test.go index 4f2b79a988631..e07bfb05f4d40 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -510,15 +510,15 @@ func (s *testSerialSuite1) TestSetVar(c *C) { tk.MustExec("set @@tidb_enable_clustered_index = 'int_only'") tk.MustQuery(`show warnings`).Check(testkit.Rows("Warning 1287 'INT_ONLY' is deprecated and will be removed in a future release. Please use 'ON' or 'OFF' instead")) - // test for tidb_enable_stable_result_mode - tk.MustQuery(`select @@tidb_enable_stable_result_mode`).Check(testkit.Rows("0")) - tk.MustExec(`set global tidb_enable_stable_result_mode = 1`) - tk.MustQuery(`select @@global.tidb_enable_stable_result_mode`).Check(testkit.Rows("1")) - tk.MustExec(`set global tidb_enable_stable_result_mode = 0`) - tk.MustQuery(`select @@global.tidb_enable_stable_result_mode`).Check(testkit.Rows("0")) - tk.MustExec(`set tidb_enable_stable_result_mode=1`) - tk.MustQuery(`select @@global.tidb_enable_stable_result_mode`).Check(testkit.Rows("0")) - tk.MustQuery(`select @@tidb_enable_stable_result_mode`).Check(testkit.Rows("1")) + // test for tidb_enable_ordered_result_mode + tk.MustQuery(`select @@tidb_enable_ordered_result_mode`).Check(testkit.Rows("0")) + tk.MustExec(`set global tidb_enable_ordered_result_mode = 1`) + tk.MustQuery(`select @@global.tidb_enable_ordered_result_mode`).Check(testkit.Rows("1")) + tk.MustExec(`set global tidb_enable_ordered_result_mode = 0`) + tk.MustQuery(`select @@global.tidb_enable_ordered_result_mode`).Check(testkit.Rows("0")) + tk.MustExec(`set tidb_enable_ordered_result_mode=1`) + tk.MustQuery(`select @@global.tidb_enable_ordered_result_mode`).Check(testkit.Rows("0")) + tk.MustQuery(`select @@tidb_enable_ordered_result_mode`).Check(testkit.Rows("1")) } func (s *testSuite5) TestTruncateIncorrectIntSessionVar(c *C) { diff --git a/planner/core/optimizer.go b/planner/core/optimizer.go index aa9e7752de3b5..c8d34f5f70416 100644 --- a/planner/core/optimizer.go +++ b/planner/core/optimizer.go @@ -66,7 +66,7 @@ const ( var optRuleList = []logicalOptRule{ &gcSubstituter{}, &columnPruner{}, - &resultsStabilizer{}, + &resultReorder{}, &buildKeySolver{}, &decorrelateSolver{}, &aggregationEliminator{}, diff --git a/planner/core/rule_stabilize_results.go b/planner/core/rule_result_reorder.go similarity index 81% rename from planner/core/rule_stabilize_results.go rename to planner/core/rule_result_reorder.go index f327bb70a98f3..d97820740dbc1 100644 --- a/planner/core/rule_stabilize_results.go +++ b/planner/core/rule_result_reorder.go @@ -21,30 +21,30 @@ import ( ) /* - resultsStabilizer stabilizes query results. + resultReorder reorder query results. NOTE: it's not a common rule for all queries, it's specially implemented for a few customers. - Results of some queries are not stable, for example: + Results of some queries are not ordered, for example: create table t (a int); insert into t values (1), (2); select a from t; - In the case above, the result can be `1 2` or `2 1`, which is not stable. - This rule stabilizes results by modifying or injecting a Sort operator: + In the case above, the result can be `1 2` or `2 1`, which is not ordered. + This rule reorders results by modifying or injecting a Sort operator: 1. iterate the plan from the root, and ignore all input-order operators (Sel/Proj/Limit); 2. when meeting the first non-input-order operator, 2.1. if it's a Sort, update it by appending all output columns into its order-by list, 2.2. otherwise, inject a new Sort upon this operator. */ -type resultsStabilizer struct { +type resultReorder struct { } -func (rs *resultsStabilizer) optimize(ctx context.Context, lp LogicalPlan) (LogicalPlan, error) { - stable := rs.completeSort(lp) - if !stable { +func (rs *resultReorder) optimize(ctx context.Context, lp LogicalPlan) (LogicalPlan, error) { + ordered := rs.completeSort(lp) + if !ordered { lp = rs.injectSort(lp) } return lp, nil } -func (rs *resultsStabilizer) completeSort(lp LogicalPlan) bool { +func (rs *resultReorder) completeSort(lp LogicalPlan) bool { if rs.isInputOrderKeeper(lp) { return rs.completeSort(lp.Children()[0]) } else if sort, ok := lp.(*LogicalSort); ok { @@ -69,7 +69,7 @@ func (rs *resultsStabilizer) completeSort(lp LogicalPlan) bool { return false } -func (rs *resultsStabilizer) injectSort(lp LogicalPlan) LogicalPlan { +func (rs *resultReorder) injectSort(lp LogicalPlan) LogicalPlan { if rs.isInputOrderKeeper(lp) { lp.SetChildren(rs.injectSort(lp.Children()[0])) return lp @@ -90,7 +90,7 @@ func (rs *resultsStabilizer) injectSort(lp LogicalPlan) LogicalPlan { return sort } -func (rs *resultsStabilizer) isInputOrderKeeper(lp LogicalPlan) bool { +func (rs *resultReorder) isInputOrderKeeper(lp LogicalPlan) bool { switch lp.(type) { case *LogicalSelection, *LogicalProjection, *LogicalLimit: return true @@ -99,7 +99,7 @@ func (rs *resultsStabilizer) isInputOrderKeeper(lp LogicalPlan) bool { } // extractHandleCols does the best effort to get the handle column. -func (rs *resultsStabilizer) extractHandleCol(lp LogicalPlan) *expression.Column { +func (rs *resultReorder) extractHandleCol(lp LogicalPlan) *expression.Column { switch x := lp.(type) { case *LogicalSelection, *LogicalLimit: handleCol := rs.extractHandleCol(lp.Children()[0]) @@ -120,6 +120,6 @@ func (rs *resultsStabilizer) extractHandleCol(lp LogicalPlan) *expression.Column return nil } -func (rs *resultsStabilizer) name() string { - return "stabilize_results" +func (rs *resultReorder) name() string { + return "result_reorder" } diff --git a/planner/core/rule_stabilize_results_test.go b/planner/core/rule_result_reorder_test.go similarity index 76% rename from planner/core/rule_stabilize_results_test.go rename to planner/core/rule_result_reorder_test.go index 00b3cf1fb12e5..9702a81620b1a 100644 --- a/planner/core/rule_stabilize_results_test.go +++ b/planner/core/rule_result_reorder_test.go @@ -29,21 +29,21 @@ import ( "github.com/pingcap/tidb/util/testutil" ) -var _ = Suite(&testRuleStabilizeResults{}) -var _ = SerialSuites(&testRuleStabilizeResultsSerial{}) +var _ = Suite(&testRuleReorderResults{}) +var _ = SerialSuites(&testRuleReorderResultsSerial{}) -type testRuleStabilizeResultsSerial struct { +type testRuleReorderResultsSerial struct { store kv.Storage dom *domain.Domain } -func (s *testRuleStabilizeResultsSerial) SetUpTest(c *C) { +func (s *testRuleReorderResultsSerial) SetUpTest(c *C) { var err error s.store, s.dom, err = newStoreWithBootstrap() c.Assert(err, IsNil) } -func (s *testRuleStabilizeResultsSerial) TestPlanCache(c *C) { +func (s *testRuleReorderResultsSerial) TestPlanCache(c *C) { tk := testkit.NewTestKit(c, s.store) orgEnable := plannercore.PreparedPlanCacheEnabled() defer func() { @@ -57,7 +57,7 @@ func (s *testRuleStabilizeResultsSerial) TestPlanCache(c *C) { c.Assert(err, IsNil) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int primary key, b int, c int, d int, key(b))") tk.MustExec("prepare s1 from 'select * from t where a > ? limit 10'") @@ -68,10 +68,10 @@ func (s *testRuleStabilizeResultsSerial) TestPlanCache(c *C) { tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // plan cache is still working } -func (s *testRuleStabilizeResultsSerial) TestSQLBinding(c *C) { +func (s *testRuleReorderResultsSerial) TestSQLBinding(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int primary key, b int, c int, d int, key(b))") tk.MustQuery("explain select * from t where a > 0 limit 1").Check(testkit.Rows( @@ -90,10 +90,10 @@ func (s *testRuleStabilizeResultsSerial) TestSQLBinding(c *C) { " └─TableRowIDScan_16(Probe) 1.00 cop[tikv] table:t keep order:false, stats:pseudo")) } -func (s *testRuleStabilizeResultsSerial) TestClusteredIndex(c *C) { +func (s *testRuleReorderResultsSerial) TestClusteredIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.Se.GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOn tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE t (a int,b int,c int, PRIMARY KEY (a,b))") @@ -105,27 +105,27 @@ func (s *testRuleStabilizeResultsSerial) TestClusteredIndex(c *C) { tk.Se.GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOff } -type testRuleStabilizeResults struct { +type testRuleReorderResults struct { store kv.Storage dom *domain.Domain testData testutil.TestData } -func (s *testRuleStabilizeResults) SetUpSuite(c *C) { +func (s *testRuleReorderResults) SetUpSuite(c *C) { var err error s.store, s.dom, err = newStoreWithBootstrap() c.Assert(err, IsNil) - s.testData, err = testutil.LoadTestSuiteData("testdata", "stable_result_mode_suite") + s.testData, err = testutil.LoadTestSuiteData("testdata", "ordered_result_mode_suite") c.Assert(err, IsNil) } -func (s *testRuleStabilizeResults) TearDownSuite(c *C) { +func (s *testRuleReorderResults) TearDownSuite(c *C) { c.Assert(s.testData.GenerateOutputIfNeeded(), IsNil) } -func (s *testRuleStabilizeResults) runTestData(c *C, tk *testkit.TestKit, name string) { +func (s *testRuleReorderResults) runTestData(c *C, tk *testkit.TestKit, name string) { var input []string var output []struct { Plan []string @@ -140,62 +140,62 @@ func (s *testRuleStabilizeResults) runTestData(c *C, tk *testkit.TestKit, name s } } -func (s *testRuleStabilizeResults) TestStableResultMode(c *C) { +func (s *testRuleReorderResults) TestOrderedResultMode(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int primary key, b int, c int, d int, key(b))") - s.runTestData(c, tk, "TestStableResultMode") + s.runTestData(c, tk, "TestOrderedResultMode") } -func (s *testRuleStabilizeResults) TestStableResultModeOnDML(c *C) { +func (s *testRuleReorderResults) TestOrderedResultModeOnDML(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int primary key, b int, c int, key(b))") - s.runTestData(c, tk, "TestStableResultModeOnDML") + s.runTestData(c, tk, "TestOrderedResultModeOnDML") } -func (s *testRuleStabilizeResults) TestStableResultModeOnSubQuery(c *C) { +func (s *testRuleReorderResults) TestOrderedResultModeOnSubQuery(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.MustExec("create table t1 (a int primary key, b int, c int, d int, key(b))") tk.MustExec("create table t2 (a int primary key, b int, c int, d int, key(b))") - s.runTestData(c, tk, "TestStableResultModeOnSubQuery") + s.runTestData(c, tk, "TestOrderedResultModeOnSubQuery") } -func (s *testRuleStabilizeResults) TestStableResultModeOnJoin(c *C) { +func (s *testRuleReorderResults) TestOrderedResultModeOnJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.MustExec("create table t1 (a int primary key, b int, c int, d int, key(b))") tk.MustExec("create table t2 (a int primary key, b int, c int, d int, key(b))") - s.runTestData(c, tk, "TestStableResultModeOnJoin") + s.runTestData(c, tk, "TestOrderedResultModeOnJoin") } -func (s *testRuleStabilizeResults) TestStableResultModeOnOtherOperators(c *C) { +func (s *testRuleReorderResults) TestOrderedResultModeOnOtherOperators(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.MustExec("create table t1 (a int primary key, b int, c int, d int, unique key(b))") tk.MustExec("create table t2 (a int primary key, b int, c int, d int, unique key(b))") - s.runTestData(c, tk, "TestStableResultModeOnOtherOperators") + s.runTestData(c, tk, "TestOrderedResultModeOnOtherOperators") } -func (s *testRuleStabilizeResults) TestStableResultModeOnPartitionTable(c *C) { +func (s *testRuleReorderResults) TestOrderedResultModeOnPartitionTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(fmt.Sprintf(`set tidb_partition_prune_mode='%v'`, variable.DefTiDBPartitionPruneMode)) - tk.MustExec("set tidb_enable_stable_result_mode=1") + tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists thash") tk.MustExec("drop table if exists trange") tk.MustExec("create table thash (a int primary key, b int, c int, d int) partition by hash(a) partitions 4") @@ -205,14 +205,14 @@ func (s *testRuleStabilizeResults) TestStableResultModeOnPartitionTable(c *C) { partition p2 values less than (300), partition p3 values less than (400))`) tk.MustQuery("select @@tidb_partition_prune_mode").Check(testkit.Rows("static")) - s.runTestData(c, tk, "TestStableResultModeOnPartitionTable") + s.runTestData(c, tk, "TestOrderedResultModeOnPartitionTable") } -func (s *testRuleStabilizeResults) TestHideStableResultSwitch(c *C) { +func (s *testRuleReorderResults) TestHideStableResultSwitch(c *C) { tk := testkit.NewTestKit(c, s.store) rs := tk.MustQuery("show variables").Rows() for _, r := range rs { - c.Assert(strings.ToLower(r[0].(string)), Not(Equals), "tidb_enable_stable_result_mode") + c.Assert(strings.ToLower(r[0].(string)), Not(Equals), "tidb_enable_ordered_result_mode") } - c.Assert(len(tk.MustQuery("show variables where variable_name like '%tidb_enable_stable_result_mode%'").Rows()), Equals, 0) + c.Assert(len(tk.MustQuery("show variables where variable_name like '%tidb_enable_ordered_result_mode%'").Rows()), Equals, 0) } diff --git a/planner/core/testdata/stable_result_mode_suite_in.json b/planner/core/testdata/ordered_result_mode_suite_in.json similarity index 92% rename from planner/core/testdata/stable_result_mode_suite_in.json rename to planner/core/testdata/ordered_result_mode_suite_in.json index 7629e80fc3630..beabb1e713c3a 100644 --- a/planner/core/testdata/stable_result_mode_suite_in.json +++ b/planner/core/testdata/ordered_result_mode_suite_in.json @@ -1,6 +1,6 @@ [ { - "name": "TestStableResultMode", + "name": "TestOrderedResultMode", "cases": [ "select * from t use index(primary)", "select b from t use index(b)", @@ -19,7 +19,7 @@ ] }, { - "name": "TestStableResultModeOnDML", + "name": "TestOrderedResultModeOnDML", "cases": [ "insert into t select * from t", "insert into t select * from t where a>1", @@ -32,7 +32,7 @@ ] }, { - "name": "TestStableResultModeOnSubQuery", + "name": "TestOrderedResultModeOnSubQuery", "cases": [ "select * from t1 where t1.a in (select b from t2)", "select * from t1 where t1.a not in (select b from t2)", @@ -46,7 +46,7 @@ ] }, { - "name": "TestStableResultModeOnJoin", + "name": "TestOrderedResultModeOnJoin", "cases": [ "select * from t1, t2 where t1.a = t2.a", "select * from t1, t2 where t1.a > t2.a and t1.b = t2.b and t1.c < t2.c", @@ -55,7 +55,7 @@ ] }, { - "name": "TestStableResultModeOnOtherOperators", + "name": "TestOrderedResultModeOnOtherOperators", "cases": [ "select * from t1 where a = 1 or a = 222 or a = 33333", "select * from t1 where a in (1, 2, 3, 4)", @@ -72,7 +72,7 @@ ] }, { - "name": "TestStableResultModeOnPartitionTable", + "name": "TestOrderedResultModeOnPartitionTable", "cases": [ "select * from thash where a in (1, 200)", "select * from thash where a >= 50 and a <= 150", diff --git a/planner/core/testdata/stable_result_mode_suite_out.json b/planner/core/testdata/ordered_result_mode_suite_out.json similarity index 98% rename from planner/core/testdata/stable_result_mode_suite_out.json rename to planner/core/testdata/ordered_result_mode_suite_out.json index 6e00e3e1c65db..b4d8cc32cba43 100644 --- a/planner/core/testdata/stable_result_mode_suite_out.json +++ b/planner/core/testdata/ordered_result_mode_suite_out.json @@ -1,6 +1,6 @@ [ { - "Name": "TestStableResultMode", + "Name": "TestOrderedResultMode", "Cases": [ { "Plan": [ @@ -112,7 +112,7 @@ ] }, { - "Name": "TestStableResultModeOnDML", + "Name": "TestOrderedResultModeOnDML", "Cases": [ { "Plan": [ @@ -178,7 +178,7 @@ ] }, { - "Name": "TestStableResultModeOnSubQuery", + "Name": "TestOrderedResultModeOnSubQuery", "Cases": [ { "Plan": [ @@ -282,7 +282,7 @@ ] }, { - "Name": "TestStableResultModeOnJoin", + "Name": "TestOrderedResultModeOnJoin", "Cases": [ { "Plan": [ @@ -330,7 +330,7 @@ ] }, { - "Name": "TestStableResultModeOnOtherOperators", + "Name": "TestOrderedResultModeOnOtherOperators", "Cases": [ { "Plan": [ @@ -436,7 +436,7 @@ ] }, { - "Name": "TestStableResultModeOnPartitionTable", + "Name": "TestOrderedResultModeOnPartitionTable", "Cases": [ { "Plan": [ diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 6e4df96d0473c..25874ab9ac197 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -1757,7 +1757,7 @@ var defaultSysVars = []*SysVar{ }}, {Scope: ScopeGlobal, Name: SkipNameResolve, Value: Off, Type: TypeBool}, {Scope: ScopeGlobal, Name: DefaultAuthPlugin, Value: mysql.AuthNativePassword, Type: TypeEnum, PossibleValues: []string{mysql.AuthNativePassword, mysql.AuthCachingSha2Password}}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableStableResultMode, Value: BoolToOnOff(DefTiDBEnableStableResultMode), Hidden: true, Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableOrderedResultMode, Value: BoolToOnOff(DefTiDBEnableOrderedResultMode), Hidden: true, Type: TypeBool, SetSession: func(s *SessionVars, val string) error { s.EnableStableResultMode = TiDBOptOn(val) return nil }}, diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 8af53a3a813a5..1fe33360c6b14 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -565,8 +565,8 @@ const ( // TiDBEnableLocalTxn indicates whether to enable Local Txn. TiDBEnableLocalTxn = "tidb_enable_local_txn" - // TiDBEnableStableResultMode indicates if stabilize query results. - TiDBEnableStableResultMode = "tidb_enable_stable_result_mode" + // TiDBEnableOrderedResultMode indicates if stabilize query results. + TiDBEnableOrderedResultMode = "tidb_enable_ordered_result_mode" ) // TiDB vars that have only global scope @@ -721,7 +721,7 @@ const ( DefTiDBEnableGlobalTemporaryTable = false DefTMPTableSize = 16777216 DefTiDBEnableLocalTxn = false - DefTiDBEnableStableResultMode = false + DefTiDBEnableOrderedResultMode = false ) // Process global variables.