diff --git a/planner/cascades/optimize.go b/planner/cascades/optimize.go index 98a7ac3fa1e3b..c447f5f8912a4 100644 --- a/planner/cascades/optimize.go +++ b/planner/cascades/optimize.go @@ -30,22 +30,22 @@ var DefaultOptimizer = NewOptimizer() // Optimizer is the struct for cascades optimizer. type Optimizer struct { - transformationRuleMap map[memo.Operand][]Transformation - implementationRuleMap map[memo.Operand][]ImplementationRule + transformationRuleBatches []TransformationRuleBatch + implementationRuleMap map[memo.Operand][]ImplementationRule } // NewOptimizer returns a cascades optimizer with default transformation // rules and implementation rules. func NewOptimizer() *Optimizer { return &Optimizer{ - transformationRuleMap: defaultTransformationMap, - implementationRuleMap: defaultImplementationMap, + transformationRuleBatches: DefaultRuleBatches, + implementationRuleMap: defaultImplementationMap, } } -// ResetTransformationRules resets the transformationRuleMap of the optimizer, and returns the optimizer. -func (opt *Optimizer) ResetTransformationRules(rules map[memo.Operand][]Transformation) *Optimizer { - opt.transformationRuleMap = rules +// ResetTransformationRules resets the transformationRuleBatches of the optimizer, and returns the optimizer. +func (opt *Optimizer) ResetTransformationRules(ruleBatches ...TransformationRuleBatch) *Optimizer { + opt.transformationRuleBatches = ruleBatches return opt } @@ -55,12 +55,6 @@ func (opt *Optimizer) ResetImplementationRules(rules map[memo.Operand][]Implemen return opt } -// GetTransformationRules gets the all the candidate Transformation rules of the optimizer -// based on the logical plan node. -func (opt *Optimizer) GetTransformationRules(node plannercore.LogicalPlan) []Transformation { - return opt.transformationRuleMap[memo.GetOperand(node)] -} - // GetImplementationRules gets all the candidate implementation rules of the optimizer // for the logical plan node. func (opt *Optimizer) GetImplementationRules(node plannercore.LogicalPlan) []ImplementationRule { @@ -129,38 +123,40 @@ func (opt *Optimizer) onPhasePreprocessing(sctx sessionctx.Context, plan planner } func (opt *Optimizer) onPhaseExploration(sctx sessionctx.Context, g *memo.Group) error { - for !g.Explored { - err := opt.exploreGroup(g) - if err != nil { - return err + for round, ruleBatch := range opt.transformationRuleBatches { + for !g.Explored(round) { + err := opt.exploreGroup(g, round, ruleBatch) + if err != nil { + return err + } } } return nil } -func (opt *Optimizer) exploreGroup(g *memo.Group) error { - if g.Explored { +func (opt *Optimizer) exploreGroup(g *memo.Group, round int, ruleBatch TransformationRuleBatch) error { + if g.Explored(round) { return nil } - g.Explored = true + g.SetExplored(round) for elem := g.Equivalents.Front(); elem != nil; elem = elem.Next() { curExpr := elem.Value.(*memo.GroupExpr) - if curExpr.Explored { + if curExpr.Explored(round) { continue } - curExpr.Explored = true + curExpr.SetExplored(round) // Explore child groups firstly. for _, childGroup := range curExpr.Children { - for !childGroup.Explored { - if err := opt.exploreGroup(childGroup); err != nil { + for !childGroup.Explored(round) { + if err := opt.exploreGroup(childGroup, round, ruleBatch); err != nil { return err } } } - eraseCur, err := opt.findMoreEquiv(g, elem) + eraseCur, err := opt.findMoreEquiv(g, elem, round, ruleBatch) if err != nil { return err } @@ -172,11 +168,12 @@ func (opt *Optimizer) exploreGroup(g *memo.Group) error { } // findMoreEquiv finds and applies the matched transformation rules. -func (opt *Optimizer) findMoreEquiv(g *memo.Group, elem *list.Element) (eraseCur bool, err error) { +func (opt *Optimizer) findMoreEquiv(g *memo.Group, elem *list.Element, round int, ruleBatch TransformationRuleBatch) (eraseCur bool, err error) { expr := elem.Value.(*memo.GroupExpr) - for _, rule := range opt.GetTransformationRules(expr.ExprNode) { + operand := memo.GetOperand(expr.ExprNode) + for _, rule := range ruleBatch[operand] { pattern := rule.GetPattern() - if !pattern.Operand.Match(memo.GetOperand(expr.ExprNode)) { + if !pattern.Operand.Match(operand) { continue } // Create a binding of the current Group expression and the pattern of @@ -198,7 +195,7 @@ func (opt *Optimizer) findMoreEquiv(g *memo.Group, elem *list.Element) (eraseCur g.Insert(e) } // If we delete all of the other GroupExprs, we can break the search. - g.Explored = true + g.SetExplored(round) return false, nil } @@ -210,7 +207,7 @@ func (opt *Optimizer) findMoreEquiv(g *memo.Group, elem *list.Element) (eraseCur // If the new Group expression is successfully inserted into the // current Group, mark the Group as unexplored to enable the exploration // on the new Group expressions. - g.Explored = false + g.SetUnexplored(round) } } } diff --git a/planner/cascades/optimize_test.go b/planner/cascades/optimize_test.go index 5b39d2b1f40ce..3fbceccf3feee 100644 --- a/planner/cascades/optimize_test.go +++ b/planner/cascades/optimize_test.go @@ -106,7 +106,7 @@ func (s *testCascadesSuite) TestPreparePossibleProperties(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() stmt, err := s.ParseOneStmt("select f, sum(a) from t group by f", "", "") c.Assert(err, IsNil) @@ -187,7 +187,7 @@ func (s *testCascadesSuite) TestAppliedRuleSet(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() stmt, err := s.ParseOneStmt("select 1", "", "") c.Assert(err, IsNil) diff --git a/planner/cascades/stringer_test.go b/planner/cascades/stringer_test.go index ae961832d605c..85314983548c9 100644 --- a/planner/cascades/stringer_test.go +++ b/planner/cascades/stringer_test.go @@ -61,7 +61,7 @@ func (s *testStringerSuite) TestGroupStringer(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { diff --git a/planner/cascades/testdata/integration_suite_in.json b/planner/cascades/testdata/integration_suite_in.json index cde7d9903a653..446b0049d95a3 100644 --- a/planner/cascades/testdata/integration_suite_in.json +++ b/planner/cascades/testdata/integration_suite_in.json @@ -53,7 +53,8 @@ "select b from t order by b limit 3", "select a from t order by a limit 1 offset 2", "select * from ((select a as aa from t t1) union all (select b as aa from t t2)) as t3 order by aa", - "select a, b, lag(a,1) over (order by b) from t order by b" + "select a, b, lag(a,1) over (order by b) from t order by b", + "select * from (select a+1 as c, a+b as d from t) as t1 order by c+d limit 10" ] }, { diff --git a/planner/cascades/testdata/integration_suite_out.json b/planner/cascades/testdata/integration_suite_out.json index 8139cc31b1fba..08aebb58887f1 100644 --- a/planner/cascades/testdata/integration_suite_out.json +++ b/planner/cascades/testdata/integration_suite_out.json @@ -212,10 +212,10 @@ { "SQL": "select max(a+b) from t", "Plan": [ - "HashAgg_16 1.00 root funcs:max(Column#4)->Column#3", - "└─TableReader_17 1.00 root data:HashAgg_18", - " └─HashAgg_18 1.00 cop[tikv] funcs:max(plus(test.t.a, test.t.b))->Column#4", - " └─TableFullScan_14 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "HashAgg_19 1.00 root funcs:max(Column#4)->Column#3", + "└─TableReader_20 1.00 root data:HashAgg_21", + " └─HashAgg_21 1.00 cop[tikv] funcs:max(plus(test.t.a, test.t.b))->Column#4", + " └─TableFullScan_17 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": [ "48" @@ -241,13 +241,13 @@ { "SQL": "select b, sum(a) from t group by b having b > 1 order by b", "Plan": [ - "Projection_19 6400.00 root test.t.b, Column#3", - "└─Sort_33 6400.00 root test.t.b:asc", - " └─HashAgg_26 6400.00 root group by:test.t.b, funcs:sum(Column#6)->Column#3, funcs:firstrow(test.t.b)->test.t.b", - " └─TableReader_27 6400.00 root data:HashAgg_28", - " └─HashAgg_28 6400.00 cop[tikv] group by:test.t.b, funcs:sum(test.t.a)->Column#6", - " └─Selection_23 8000.00 cop[tikv] gt(test.t.b, 1)", - " └─TableFullScan_24 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "Projection_14 6400.00 root test.t.b, Column#3", + "└─Sort_24 6400.00 root test.t.b:asc", + " └─HashAgg_21 6400.00 root group by:test.t.b, funcs:sum(Column#4)->Column#3, funcs:firstrow(test.t.b)->test.t.b", + " └─TableReader_22 6400.00 root data:HashAgg_23", + " └─HashAgg_23 6400.00 cop[tikv] group by:test.t.b, funcs:sum(test.t.a)->Column#4", + " └─Selection_18 8000.00 cop[tikv] gt(test.t.b, 1)", + " └─TableFullScan_19 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": [ "11 1", @@ -259,13 +259,13 @@ { "SQL": "select c, sum(a) from (select a+b as c, a from t) t1 group by c having c > 1 order by c", "Plan": [ - "Projection_20 6400.00 root Column#3, Column#4", - "└─Sort_32 6400.00 root Column#3:asc", - " └─HashAgg_28 6400.00 root group by:Column#10, funcs:sum(Column#8)->Column#4, funcs:firstrow(Column#10)->Column#3", - " └─TableReader_29 6400.00 root data:HashAgg_30", - " └─HashAgg_30 6400.00 cop[tikv] group by:plus(test.t.a, test.t.b), funcs:sum(test.t.a)->Column#8", - " └─Selection_25 8000.00 cop[tikv] gt(plus(test.t.a, test.t.b), 1)", - " └─TableFullScan_26 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "Projection_18 6400.00 root Column#3, Column#4", + "└─Sort_30 6400.00 root Column#3:asc", + " └─HashAgg_26 6400.00 root group by:Column#7, funcs:sum(Column#5)->Column#4, funcs:firstrow(Column#7)->Column#3", + " └─TableReader_27 6400.00 root data:HashAgg_28", + " └─HashAgg_28 6400.00 cop[tikv] group by:plus(test.t.a, test.t.b), funcs:sum(test.t.a)->Column#5", + " └─Selection_23 8000.00 cop[tikv] gt(plus(test.t.a, test.t.b), 1)", + " └─TableFullScan_24 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": [ "12 1", @@ -277,11 +277,11 @@ { "SQL": "select max(a.a) from t a left join t b on a.a = b.a", "Plan": [ - "HashAgg_53 1.00 root funcs:max(test.t.a)->Column#5", - "└─Limit_55 1.00 root offset:0, count:1", - " └─TableReader_59 1.00 root data:Limit_60", - " └─Limit_60 1.00 cop[tikv] offset:0, count:1", - " └─TableFullScan_31 1.00 cop[tikv] table:a, keep order:true, desc, stats:pseudo" + "HashAgg_64 1.00 root funcs:max(test.t.a)->Column#5", + "└─Limit_66 1.00 root offset:0, count:1", + " └─TableReader_70 1.00 root data:Limit_71", + " └─Limit_71 1.00 cop[tikv] offset:0, count:1", + " └─TableFullScan_34 1.00 cop[tikv] table:a, keep order:true, desc, stats:pseudo" ], "Result": [ "4" @@ -290,10 +290,10 @@ { "SQL": "select avg(a.b) from t a left join t b on a.a = b.a", "Plan": [ - "HashAgg_16 1.00 root funcs:avg(Column#6, Column#7)->Column#5", - "└─TableReader_17 1.00 root data:HashAgg_18", - " └─HashAgg_18 1.00 cop[tikv] funcs:avg(test.t.b)->Column#6", - " └─TableFullScan_14 10000.00 cop[tikv] table:a, keep order:false, stats:pseudo" + "HashAgg_14 1.00 root funcs:avg(Column#6, Column#7)->Column#5", + "└─TableReader_15 1.00 root data:HashAgg_16", + " └─HashAgg_16 1.00 cop[tikv] funcs:avg(test.t.b)->Column#6", + " └─TableFullScan_12 10000.00 cop[tikv] table:a, keep order:false, stats:pseudo" ], "Result": [ "27.5000" @@ -302,12 +302,12 @@ { "SQL": "select t1.a, max(t1.b) from t as t1 left join (select * from t) as t2 on t1.a = t2.a and t1.b = 3 group by t1.a order by a", "Plan": [ - "Projection_15 8000.00 root test.t.a, Column#5", - "└─Sort_23 8000.00 root test.t.a:asc", - " └─HashAgg_20 8000.00 root group by:test.t.a, funcs:max(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", - " └─TableReader_21 8000.00 root data:HashAgg_22", - " └─HashAgg_22 8000.00 cop[tikv] group by:test.t.a, funcs:max(test.t.b)->Column#6", - " └─TableFullScan_19 10000.00 cop[tikv] table:t1, keep order:false, stats:pseudo" + "Projection_13 8000.00 root test.t.a, Column#5", + "└─Sort_21 8000.00 root test.t.a:asc", + " └─HashAgg_18 8000.00 root group by:test.t.a, funcs:max(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─TableReader_19 8000.00 root data:HashAgg_20", + " └─HashAgg_20 8000.00 cop[tikv] group by:test.t.a, funcs:max(test.t.b)->Column#6", + " └─TableFullScan_17 10000.00 cop[tikv] table:t1, keep order:false, stats:pseudo" ], "Result": [ "1 11", @@ -319,12 +319,12 @@ { "SQL": "select t1.a, sum(distinct t1.b) from t as t1 left join (select * from t) as t2 on t1.b = t2.b group by t1.a order by a", "Plan": [ - "Projection_13 8000.00 root test.t.a, Column#5", - "└─Sort_19 8000.00 root test.t.a:asc", - " └─HashAgg_15 8000.00 root group by:Column#8, funcs:sum(distinct Column#6)->Column#5, funcs:firstrow(Column#7)->test.t.a", - " └─Projection_18 10000.00 root cast(test.t.b, decimal(65,0) BINARY)->Column#6, test.t.a, test.t.a", - " └─TableReader_16 10000.00 root data:TableFullScan_17", - " └─TableFullScan_17 10000.00 cop[tikv] table:t1, keep order:false, stats:pseudo" + "Projection_11 8000.00 root test.t.a, Column#5", + "└─Sort_17 8000.00 root test.t.a:asc", + " └─HashAgg_13 8000.00 root group by:Column#8, funcs:sum(distinct Column#6)->Column#5, funcs:firstrow(Column#7)->test.t.a", + " └─Projection_16 10000.00 root cast(test.t.b, decimal(65,0) BINARY)->Column#6, test.t.a, test.t.a", + " └─TableReader_14 10000.00 root data:TableFullScan_15", + " └─TableFullScan_15 10000.00 cop[tikv] table:t1, keep order:false, stats:pseudo" ], "Result": [ "1 11", @@ -336,12 +336,12 @@ { "SQL": "select t2.a, max(t2.b) from t as t1 right join (select * from t) as t2 on t1.a = t2.a group by t2.a order by a", "Plan": [ - "Projection_15 8000.00 root test.t.a, Column#5", - "└─Sort_23 8000.00 root test.t.a:asc", - " └─HashAgg_20 8000.00 root group by:test.t.a, funcs:max(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", - " └─TableReader_21 8000.00 root data:HashAgg_22", - " └─HashAgg_22 8000.00 cop[tikv] group by:test.t.a, funcs:max(test.t.b)->Column#6", - " └─TableFullScan_19 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "Projection_13 8000.00 root test.t.a, Column#5", + "└─Sort_21 8000.00 root test.t.a:asc", + " └─HashAgg_18 8000.00 root group by:test.t.a, funcs:max(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─TableReader_19 8000.00 root data:HashAgg_20", + " └─HashAgg_20 8000.00 cop[tikv] group by:test.t.a, funcs:max(test.t.b)->Column#6", + " └─TableFullScan_17 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": [ "1 11", @@ -366,10 +366,10 @@ { "SQL": "select sum(case when a > 0 and a <= 1000 then b else 0 end) from t", "Plan": [ - "HashAgg_22 1.00 root funcs:sum(Column#5)->Column#3", - "└─TableReader_23 1.00 root data:HashAgg_24", - " └─HashAgg_24 1.00 cop[tikv] funcs:sum(test.t.b)->Column#5", - " └─TableRangeScan_16 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" + "HashAgg_16 1.00 root funcs:sum(Column#4)->Column#3", + "└─TableReader_17 1.00 root data:HashAgg_18", + " └─HashAgg_18 1.00 cop[tikv] funcs:sum(test.t.b)->Column#4", + " └─TableRangeScan_14 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" ], "Result": [ "110" @@ -378,10 +378,10 @@ { "SQL": "select sum(case when a > 0 then (case when a <= 1000 then b end) else 0 end) from t", "Plan": [ - "HashAgg_32 1.00 root funcs:sum(Column#6)->Column#3", - "└─TableReader_33 1.00 root data:HashAgg_34", - " └─HashAgg_34 1.00 cop[tikv] funcs:sum(test.t.b)->Column#6", - " └─TableRangeScan_22 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" + "HashAgg_19 1.00 root funcs:sum(Column#4)->Column#3", + "└─TableReader_20 1.00 root data:HashAgg_21", + " └─HashAgg_21 1.00 cop[tikv] funcs:sum(test.t.b)->Column#4", + " └─TableRangeScan_17 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" ], "Result": [ "110" @@ -390,10 +390,10 @@ { "SQL": "select sum(case when a <= 0 or a > 1000 then 0.0 else b end) from t", "Plan": [ - "HashAgg_22 1.00 root funcs:sum(Column#5)->Column#3", - "└─TableReader_23 1.00 root data:HashAgg_24", - " └─HashAgg_24 1.00 cop[tikv] funcs:sum(cast(test.t.b))->Column#5", - " └─TableRangeScan_16 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" + "HashAgg_16 1.00 root funcs:sum(Column#4)->Column#3", + "└─TableReader_17 1.00 root data:HashAgg_18", + " └─HashAgg_18 1.00 cop[tikv] funcs:sum(cast(test.t.b))->Column#4", + " └─TableRangeScan_14 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" ], "Result": [ "110.0" @@ -402,10 +402,10 @@ { "SQL": "select count(case when a > 0 and a <= 1000 then b end) from t", "Plan": [ - "HashAgg_21 1.00 root funcs:count(Column#5)->Column#3", - "└─TableReader_22 1.00 root data:HashAgg_23", - " └─HashAgg_23 1.00 cop[tikv] funcs:count(test.t.b)->Column#5", - " └─TableRangeScan_16 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" + "HashAgg_15 1.00 root funcs:count(Column#4)->Column#3", + "└─TableReader_16 1.00 root data:HashAgg_17", + " └─HashAgg_17 1.00 cop[tikv] funcs:count(test.t.b)->Column#4", + " └─TableRangeScan_14 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" ], "Result": [ "4" @@ -414,10 +414,10 @@ { "SQL": "select count(case when a <= 0 or a > 1000 then null else b end) from t", "Plan": [ - "HashAgg_21 1.00 root funcs:count(Column#5)->Column#3", - "└─TableReader_22 1.00 root data:HashAgg_23", - " └─HashAgg_23 1.00 cop[tikv] funcs:count(test.t.b)->Column#5", - " └─TableRangeScan_16 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" + "HashAgg_15 1.00 root funcs:count(Column#4)->Column#3", + "└─TableReader_16 1.00 root data:HashAgg_17", + " └─HashAgg_17 1.00 cop[tikv] funcs:count(test.t.b)->Column#4", + " └─TableRangeScan_14 250.00 cop[tikv] table:t, range:(0,1000], keep order:false, stats:pseudo" ], "Result": [ "4" @@ -527,6 +527,23 @@ "3 33 2", "4 44 3" ] + }, + { + "SQL": "select * from (select a+1 as c, a+b as d from t) as t1 order by c+d limit 10", + "Plan": [ + "Projection_22 10.00 root plus(test.t.a, 1)->Column#3, plus(test.t.a, test.t.b)->Column#4", + "└─TopN_23 10.00 root Column#5:asc, offset:0, count:10", + " └─Projection_25 10.00 root test.t.a, test.t.b, plus(plus(test.t.a, 1), plus(test.t.a, test.t.b))->Column#5", + " └─TableReader_26 10.00 root data:TopN_27", + " └─TopN_27 10.00 cop[tikv] plus(plus(test.t.a, 1), plus(test.t.a, test.t.b)):asc, offset:0, count:10", + " └─TableFullScan_28 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + ], + "Result": [ + "2 12", + "3 24", + "4 36", + "5 48" + ] } ] }, @@ -536,8 +553,8 @@ { "SQL": "select b from t", "Plan": [ - "IndexReader_11 10000.00 root index:IndexFullScan_12", - "└─IndexFullScan_12 10000.00 cop[tikv] table:t, index:b, keep order:false, stats:pseudo" + "IndexReader_13 10000.00 root index:IndexFullScan_14", + "└─IndexFullScan_14 10000.00 cop[tikv] table:t, index:b, keep order:false, stats:pseudo" ], "Result": [ "2", @@ -549,8 +566,8 @@ "SQL": "select a from t order by b", "Plan": [ "Projection_11 10000.00 root test.t.a", - "└─IndexReader_14 10000.00 root index:IndexFullScan_15", - " └─IndexFullScan_15 10000.00 cop[tikv] table:t, index:b, keep order:true, stats:pseudo" + "└─IndexReader_15 10000.00 root index:IndexFullScan_16", + " └─IndexFullScan_16 10000.00 cop[tikv] table:t, index:b, keep order:true, stats:pseudo" ], "Result": [ "1", @@ -586,8 +603,8 @@ { "SQL": "select a, b from t where b > 5 order by b", "Plan": [ - "IndexReader_20 8000.00 root index:IndexRangeScan_21", - "└─IndexRangeScan_21 3333.33 cop[tikv] table:t, index:b, range:(5,+inf], keep order:true, stats:pseudo" + "IndexReader_18 8000.00 root index:IndexRangeScan_19", + "└─IndexRangeScan_19 3333.33 cop[tikv] table:t, index:b, range:(5,+inf], keep order:true, stats:pseudo" ], "Result": [ "7 8" @@ -789,12 +806,12 @@ { "SQL": "select a from (select a from t where b > 2 order by a limit 3 offset 1) as t1 order by a limit 2 offset 1", "Plan": [ - "Projection_25 2.00 root test.t.a", - "└─Limit_27 2.00 root offset:2, count:2", - " └─TableReader_35 4.00 root data:Limit_36", - " └─Limit_36 4.00 cop[tikv] offset:0, count:4", - " └─Selection_33 4.00 cop[tikv] gt(test.t.b, 2)", - " └─TableFullScan_34 4.00 cop[tikv] table:t, keep order:true, stats:pseudo" + "Projection_22 2.00 root test.t.a", + "└─Limit_24 2.00 root offset:2, count:2", + " └─TableReader_32 4.00 root data:Limit_33", + " └─Limit_33 4.00 cop[tikv] offset:0, count:4", + " └─Selection_30 4.00 cop[tikv] gt(test.t.b, 2)", + " └─TableFullScan_31 4.00 cop[tikv] table:t, keep order:true, stats:pseudo" ], "Result": [ "3", @@ -804,10 +821,10 @@ { "SQL": "select * from (select * from t order by a limit 3) as t1 order by a limit 5", "Plan": [ - "Limit_17 3.00 root offset:0, count:3", - "└─TableReader_23 3.00 root data:Limit_24", - " └─Limit_24 3.00 cop[tikv] offset:0, count:3", - " └─TableFullScan_22 3.00 cop[tikv] table:t, keep order:true, stats:pseudo" + "Limit_15 3.00 root offset:0, count:3", + "└─TableReader_21 3.00 root data:Limit_22", + " └─Limit_22 3.00 cop[tikv] offset:0, count:3", + " └─TableFullScan_20 3.00 cop[tikv] table:t, keep order:true, stats:pseudo" ], "Result": [ "1 11", @@ -818,39 +835,39 @@ { "SQL": "select b from (select b from t order by b limit 10 offset 10) as t1 order by b limit 10 offset 5", "Plan": [ - "TopN_16 5.00 root test.t.b:asc, offset:15, count:5", - "└─TableReader_18 20.00 root data:TopN_19", - " └─TopN_19 20.00 cop[tikv] test.t.b:asc, offset:0, count:20", - " └─TableFullScan_21 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "TopN_14 5.00 root test.t.b:asc, offset:15, count:5", + "└─TableReader_16 20.00 root data:TopN_17", + " └─TopN_17 20.00 cop[tikv] test.t.b:asc, offset:0, count:20", + " └─TableFullScan_19 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": null }, { "SQL": "select b from (select b from t order by b limit 10 offset 2) as t1 order by b limit 3 offset 5", "Plan": [ - "TopN_16 3.00 root test.t.b:asc, offset:7, count:3", - "└─TableReader_18 10.00 root data:TopN_19", - " └─TopN_19 10.00 cop[tikv] test.t.b:asc, offset:0, count:10", - " └─TableFullScan_21 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "TopN_14 3.00 root test.t.b:asc, offset:7, count:3", + "└─TableReader_16 10.00 root data:TopN_17", + " └─TopN_17 10.00 cop[tikv] test.t.b:asc, offset:0, count:10", + " └─TableFullScan_19 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": null }, { "SQL": "select a from (select a from t order by a limit 3 offset 5) as t1 order by a limit 3 offset 5", "Plan": [ - "TableDual_14 0.00 root rows:0" + "TableDual_11 0.00 root rows:0" ], "Result": null }, { "SQL": "select a from (select a from t where b > 2 order by a, b limit 3 offset 1) as t1 order by a limit 2 offset 1", "Plan": [ - "Projection_25 2.00 root test.t.a", - "└─TopN_26 2.00 root test.t.a:asc, test.t.b:asc, offset:2, count:2", - " └─TableReader_28 4.00 root data:TopN_29", - " └─TopN_29 4.00 cop[tikv] test.t.a:asc, test.t.b:asc, offset:0, count:4", - " └─Selection_31 8000.00 cop[tikv] gt(test.t.b, 2)", - " └─TableFullScan_32 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" + "Projection_22 2.00 root test.t.a", + "└─TopN_23 2.00 root test.t.a:asc, test.t.b:asc, offset:2, count:2", + " └─TableReader_25 4.00 root data:TopN_26", + " └─TopN_26 4.00 cop[tikv] test.t.a:asc, test.t.b:asc, offset:0, count:4", + " └─Selection_28 8000.00 cop[tikv] gt(test.t.b, 2)", + " └─TableFullScan_29 10000.00 cop[tikv] table:t, keep order:false, stats:pseudo" ], "Result": [ "3", diff --git a/planner/cascades/testdata/transformation_rules_suite_in.json b/planner/cascades/testdata/transformation_rules_suite_in.json index c602010e68059..32dd1bbeeabe2 100644 --- a/planner/cascades/testdata/transformation_rules_suite_in.json +++ b/planner/cascades/testdata/transformation_rules_suite_in.json @@ -120,6 +120,14 @@ "select a, b from ((select a, b from t) union all(select c as a, d as b from t limit 0 offset 5)) as t1 where a > 1" ] }, + { + "name": "TestPostTransformationRules", + "cases": [ + "select b from (select b+10 as b from t) as t1 order by b + 10 limit 10", + "select * from (select a+1 as c, a+b as d from t) as t1 order by c+d limit 10", + "select a from (select a, b from t order by b limit 10) as t1" + ] + }, { "name": "TestPushLimitDownTiKVSingleGather", "cases": [ @@ -172,4 +180,4 @@ "select count(case when a > 10 and d < 5 then null else b end) from t" ] } -] \ No newline at end of file +] diff --git a/planner/cascades/testdata/transformation_rules_suite_out.json b/planner/cascades/testdata/transformation_rules_suite_out.json index 6e75e82aad11a..76217934b66bf 100644 --- a/planner/cascades/testdata/transformation_rules_suite_out.json +++ b/planner/cascades/testdata/transformation_rules_suite_out.json @@ -12,11 +12,11 @@ "Group#2 Schema:[test.t.a,test.t.b]", " Projection_2 input:[Group#3], test.t.a, test.t.b", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#4], table:t1", + " TiKVSingleGather_8 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b]", " Selection_9 input:[Group#5], gt(test.t.b, 10)", "Group#5 Schema:[test.t.a,test.t.b]", - " TableScan_6 table:t1, pk col:test.t.a" + " TableScan_7 table:t1, pk col:test.t.a" ] }, { @@ -29,7 +29,7 @@ "Group#2 Schema:[test.t.a,test.t.b]", " Projection_2 input:[Group#3], test.t.a, test.t.b", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#4], table:t1", + " TiKVSingleGather_8 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b]", " TableScan_10 table:t1, pk col:test.t.a, cond:[gt(test.t.a, 10)]" ] @@ -42,11 +42,11 @@ "Group#1 Schema:[test.t.a,test.t.b,Column#13]", " Projection_2 input:[Group#2], test.t.a, test.t.b, plus(test.t.a, test.t.b)->Column#13", "Group#2 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_6 input:[Group#3], table:t1", + " TiKVSingleGather_7 input:[Group#3], table:t1", "Group#3 Schema:[test.t.a,test.t.b]", " Selection_8 input:[Group#4], eq(test.t.b, 1), gt(plus(test.t.a, test.t.b), 10)", "Group#4 Schema:[test.t.a,test.t.b]", - " TableScan_5 table:t1, pk col:test.t.a" + " TableScan_6 table:t1, pk col:test.t.a" ] }, { @@ -70,11 +70,11 @@ "Group#0 Schema:[test.t.b,Column#14]", " Projection_4 input:[Group#1], test.t.b, setvar(i, cast(plus(cast(getvar(i), double BINARY), 1), var_string(5)))->Column#14", "Group#1 Schema:[test.t.a,test.t.b,Column#13]", - " Selection_8 input:[Group#2], lt(cast(getvar(\"i\")), 10)", + " Selection_6 input:[Group#2], lt(cast(getvar(\"i\")), 10)", "Group#2 Schema:[test.t.a,test.t.b,Column#13]", " Projection_2 input:[Group#3], test.t.a, test.t.b, setvar(i, 0)->Column#13", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_6 input:[Group#4], table:t1", + " TiKVSingleGather_8 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b]", " TableScan_10 table:t1, pk col:test.t.a, cond:[gt(test.t.a, 10)]" ] @@ -87,7 +87,7 @@ "Group#1 Schema:[Column#13,test.t.a]", " Aggregation_2 input:[Group#2], group by:test.t.a, funcs:max(test.t.b), firstrow(test.t.a)", "Group#2 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_6 input:[Group#3], table:t", + " TiKVSingleGather_8 input:[Group#3], table:t", "Group#3 Schema:[test.t.a,test.t.b]", " TableScan_10 table:t, pk col:test.t.a, cond:[gt(test.t.a, 1)]" ] @@ -100,11 +100,11 @@ "Group#1 Schema:[test.t.a,Column#13,Column#14]", " Projection_3 input:[Group#2], test.t.a, Column#13, Column#14", "Group#2 Schema:[Column#13,Column#14,test.t.a]", - " Selection_10 input:[Group#3], gt(Column#14, 10)", + " Selection_8 input:[Group#3], gt(Column#14, 10)", "Group#3 Schema:[Column#13,Column#14,test.t.a]", " Aggregation_2 input:[Group#4], group by:test.t.a, funcs:avg(test.t.b), max(test.t.b), firstrow(test.t.a)", "Group#4 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#5], table:t", + " TiKVSingleGather_10 input:[Group#5], table:t", "Group#5 Schema:[test.t.a,test.t.b]", " TableScan_12 table:t, pk col:test.t.a, cond:[gt(test.t.a, 1)]" ] @@ -117,13 +117,13 @@ "Group#1 Schema:[test.t.a,test.t.b,test.t.a,test.t.b]", " Join_3 input:[Group#2,Group#3], inner join, equal:[eq(test.t.a, test.t.a) eq(test.t.b, test.t.b)], other cond:gt(test.t.a, test.t.b)", "Group#2 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#4], table:t1", + " TiKVSingleGather_9 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b]", - " Selection_14 input:[Group#5], gt(test.t.a, test.t.b), gt(test.t.b, 10)", + " Selection_12 input:[Group#5], gt(test.t.a, test.t.b), gt(test.t.b, 10)", "Group#5 Schema:[test.t.a,test.t.b]", - " TableScan_13 table:t1, pk col:test.t.a, cond:[gt(test.t.a, 10)]", + " TableScan_11 table:t1, pk col:test.t.a, cond:[gt(test.t.a, 10)]", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_9 input:[Group#6], table:t2", + " TiKVSingleGather_14 input:[Group#6], table:t2", "Group#6 Schema:[test.t.a,test.t.b]", " Selection_17 input:[Group#7], gt(test.t.a, test.t.b), gt(test.t.b, 10)", "Group#7 Schema:[test.t.a,test.t.b]", @@ -136,7 +136,7 @@ "Group#0 Schema:[test.t.a,test.t.b]", " Projection_5 input:[Group#1], test.t.a, test.t.b", "Group#1 Schema:[test.t.a,test.t.b,test.t.a]", - " TableDual_22 rowcount:0" + " TableDual_6 rowcount:0" ] }, { @@ -166,14 +166,14 @@ "Group#1 Schema:[test.t.a,test.t.f,test.t.g]", " Projection_3 input:[Group#2], test.t.a, test.t.f, test.t.g", "Group#2 Schema:[test.t.a,test.t.f,test.t.g]", - " TiKVSingleGather_7 input:[Group#3], table:t", - " TiKVSingleGather_9 input:[Group#4], table:t, index:f_g", + " TiKVSingleGather_9 input:[Group#3], table:t", + " TiKVSingleGather_11 input:[Group#4], table:t, index:f_g", "Group#3 Schema:[test.t.a,test.t.f,test.t.g]", - " Selection_16 input:[Group#5], eq(test.t.f, 1), gt(test.t.g, 1)", + " Selection_12 input:[Group#5], eq(test.t.f, 1), gt(test.t.g, 1)", "Group#5 Schema:[test.t.a,test.t.f,test.t.g]", - " TableScan_6 table:t, pk col:test.t.a", + " TableScan_8 table:t, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.f,test.t.g]", - " IndexScan_17 table:t, index:f, g, cond:[eq(test.t.f, 1) gt(test.t.g, 1)]" + " IndexScan_14 table:t, index:f, g, cond:[eq(test.t.f, 1) gt(test.t.g, 1)]" ] }, { @@ -200,7 +200,7 @@ "Group#0 Schema:[test.t.a,test.t.b]", " Projection_5 input:[Group#1], test.t.a, test.t.b", "Group#1 Schema:[test.t.a,test.t.b,test.t.a]", - " TableDual_22 rowcount:0" + " TableDual_6 rowcount:0" ] }, { @@ -215,20 +215,20 @@ "Group#4 Schema:[test.t.a,test.t.b]", " Projection_4 input:[Group#5], test.t.a, test.t.b", "Group#5 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_11 input:[Group#6], table:t", + " TiKVSingleGather_15 input:[Group#6], table:t", "Group#6 Schema:[test.t.a,test.t.b]", - " TableScan_19 table:t, pk col:test.t.a, cond:[gt(test.t.a, 1)]", + " TableScan_17 table:t, pk col:test.t.a, cond:[gt(test.t.a, 1)]", "Group#3 Schema:[Column#25,Column#26]", " Projection_7 input:[Group#7], test.t.c, test.t.d", "Group#7 Schema:[test.t.c,test.t.d]", " Projection_2 input:[Group#8], test.t.c, test.t.d", "Group#8 Schema:[test.t.c,test.t.d]", - " TiKVSingleGather_13 input:[Group#9], table:t", - " TiKVSingleGather_15 input:[Group#10], table:t, index:c_d_e", + " TiKVSingleGather_19 input:[Group#9], table:t", + " TiKVSingleGather_21 input:[Group#10], table:t, index:c_d_e", "Group#9 Schema:[test.t.c,test.t.d]", " Selection_22 input:[Group#11], gt(test.t.c, 1)", "Group#11 Schema:[test.t.c,test.t.d]", - " TableScan_12 table:t", + " TableScan_18 table:t", "Group#10 Schema:[test.t.c,test.t.d]", " IndexScan_24 table:t, index:c, d, e, cond:[gt(test.t.c, 1)]" ] @@ -241,7 +241,7 @@ "Group#1 Schema:[test.t.a,test.t.b,Column#14]", " Projection_5 input:[Group#2], test.t.a, test.t.b, Column#14", "Group#2 Schema:[test.t.a,test.t.b,Column#14]", - " Selection_12 input:[Group#3], eq(test.t.b, Column#14), lt(test.t.a, 10)", + " Selection_10 input:[Group#3], eq(test.t.b, Column#14), lt(test.t.a, 10)", "Group#3 Schema:[test.t.a,test.t.b,Column#14]", " Window_4 input:[Group#4]", "Group#4 Schema:[test.t.a,test.t.b]", @@ -249,11 +249,11 @@ "Group#5 Schema:[test.t.a,test.t.b]", " Projection_2 input:[Group#6], test.t.a, test.t.b", "Group#6 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_9 input:[Group#7], table:t", + " TiKVSingleGather_14 input:[Group#7], table:t", "Group#7 Schema:[test.t.a,test.t.b]", " Selection_15 input:[Group#8], gt(test.t.b, 10)", "Group#8 Schema:[test.t.a,test.t.b]", - " TableScan_8 table:t, pk col:test.t.a" + " TableScan_13 table:t, pk col:test.t.a" ] }, { @@ -264,11 +264,11 @@ "Group#1 Schema:[test.t.b,test.t.c]", " Projection_3 input:[Group#2], test.t.b, test.t.c", "Group#2 Schema:[test.t.b,test.t.c]", - " TiKVSingleGather_7 input:[Group#3], table:t", + " TiKVSingleGather_9 input:[Group#3], table:t", "Group#3 Schema:[test.t.b,test.t.c]", - " Selection_11 input:[Group#4], gt(test.t.b, 1), gt(test.t.b, 2), gt(test.t.c, 1), gt(test.t.c, 2)", + " Selection_10 input:[Group#4], gt(test.t.b, 1), gt(test.t.b, 2), gt(test.t.c, 1), gt(test.t.c, 2)", "Group#4 Schema:[test.t.b,test.t.c]", - " TableScan_6 table:t" + " TableScan_8 table:t" ] } ] @@ -338,13 +338,13 @@ "Group#1 Schema:[test.t.b,test.t.a]", " Projection_2 input:[Group#2], test.t.b, test.t.a", "Group#2 Schema:[test.t.a,test.t.b]", - " TopN_9 input:[Group#3], test.t.a:asc, offset:0, count:2", + " TopN_7 input:[Group#3], test.t.a:asc, offset:0, count:2", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#4], table:t", + " TiKVSingleGather_9 input:[Group#4], table:t", "Group#4 Schema:[test.t.a,test.t.b]", " TopN_10 input:[Group#5], test.t.a:asc, offset:0, count:2", "Group#5 Schema:[test.t.a,test.t.b]", - " TableScan_6 table:t, pk col:test.t.a" + " TableScan_8 table:t, pk col:test.t.a" ] }, { @@ -370,13 +370,13 @@ "Group#1 Schema:[Column#13,test.t.a]", " Projection_2 input:[Group#2], plus(test.t.a, test.t.b)->Column#13, test.t.a", "Group#2 Schema:[test.t.a,test.t.b]", - " TopN_9 input:[Group#3], test.t.a:asc, offset:2, count:1", + " TopN_7 input:[Group#3], test.t.a:asc, offset:2, count:1", "Group#3 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_7 input:[Group#4], table:t", + " TiKVSingleGather_9 input:[Group#4], table:t", "Group#4 Schema:[test.t.a,test.t.b]", " TopN_10 input:[Group#5], test.t.a:asc, offset:0, count:3", "Group#5 Schema:[test.t.a,test.t.b]", - " TableScan_6 table:t, pk col:test.t.a" + " TableScan_8 table:t, pk col:test.t.a" ] }, { @@ -387,20 +387,20 @@ "Group#1 Schema:[test.t.c,test.t.a]", " Projection_2 input:[Group#2], test.t.c, test.t.a", "Group#2 Schema:[test.t.a,test.t.c]", - " TopN_11 input:[Group#3], test.t.a:asc, offset:0, count:1", - " TopN_11 input:[Group#4], test.t.a:asc, offset:0, count:1", + " TopN_7 input:[Group#3], test.t.a:asc, offset:0, count:1", + " TopN_7 input:[Group#4], test.t.a:asc, offset:0, count:1", "Group#3 Schema:[test.t.a,test.t.c]", - " TiKVSingleGather_9 input:[Group#5], table:t, index:c_d_e", + " TiKVSingleGather_11 input:[Group#5], table:t, index:c_d_e", "Group#5 Schema:[test.t.a,test.t.c]", " TopN_13 input:[Group#6], test.t.a:asc, offset:0, count:1", "Group#6 Schema:[test.t.a,test.t.c]", - " IndexScan_8 table:t, index:c, d, e", + " IndexScan_10 table:t, index:c, d, e", "Group#4 Schema:[test.t.a,test.t.c]", - " TiKVSingleGather_7 input:[Group#7], table:t", + " TiKVSingleGather_9 input:[Group#7], table:t", "Group#7 Schema:[test.t.a,test.t.c]", " TopN_12 input:[Group#8], test.t.a:asc, offset:0, count:1", "Group#8 Schema:[test.t.a,test.t.c]", - " TableScan_6 table:t, pk col:test.t.a" + " TableScan_8 table:t, pk col:test.t.a" ] }, { @@ -411,13 +411,13 @@ "Group#1 Schema:[test.t.c,test.t.a,test.t.b]", " Projection_2 input:[Group#2], test.t.c, test.t.a, test.t.b", "Group#2 Schema:[test.t.a,test.t.b,test.t.c]", - " TopN_9 input:[Group#3], plus(test.t.a, test.t.b):asc, offset:0, count:1", + " TopN_7 input:[Group#3], plus(test.t.a, test.t.b):asc, offset:0, count:1", "Group#3 Schema:[test.t.a,test.t.b,test.t.c]", - " TiKVSingleGather_7 input:[Group#4], table:t", + " TiKVSingleGather_9 input:[Group#4], table:t", "Group#4 Schema:[test.t.a,test.t.b,test.t.c]", " TopN_10 input:[Group#5], plus(test.t.a, test.t.b):asc, offset:0, count:1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c]", - " TableScan_6 table:t, pk col:test.t.a" + " TableScan_8 table:t, pk col:test.t.a" ] }, { @@ -428,19 +428,19 @@ "Group#1 Schema:[test.t.a,test.t.b,test.t.c]", " Apply_8 input:[Group#2,Group#3], semi join, equal:[eq(test.t.a, test.t.a)]", "Group#2 Schema:[test.t.a,test.t.b,test.t.c]", - " TiKVSingleGather_11 input:[Group#4], table:t1", + " TiKVSingleGather_13 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b,test.t.c]", - " TableScan_10 table:t1, pk col:test.t.a", + " TableScan_12 table:t1, pk col:test.t.a", "Group#3 Schema:[test.t.a]", " Projection_5 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a,test.t.b]", - " TopN_15 input:[Group#6], , offset:0, count:1", + " TopN_11 input:[Group#6], , offset:0, count:1", "Group#6 Schema:[test.t.a,test.t.b]", " Selection_4 input:[Group#7], gt(test.t.b, test.t.b)", "Group#7 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_13 input:[Group#8], table:t2", + " TiKVSingleGather_15 input:[Group#8], table:t2", "Group#8 Schema:[test.t.a,test.t.b]", - " TableScan_12 table:t2, pk col:test.t.a" + " TableScan_14 table:t2, pk col:test.t.a" ] }, { @@ -451,9 +451,9 @@ "Group#1 Schema:[test.t.a,test.t.b,test.t.c]", " Apply_10 input:[Group#2,Group#3], semi join, equal:[eq(test.t.a, test.t.a)]", "Group#2 Schema:[test.t.a,test.t.b,test.t.c]", - " TiKVSingleGather_13 input:[Group#4], table:t1", + " TiKVSingleGather_16 input:[Group#4], table:t1", "Group#4 Schema:[test.t.a,test.t.b,test.t.c]", - " TableScan_12 table:t1, pk col:test.t.a", + " TableScan_15 table:t1, pk col:test.t.a", "Group#3 Schema:[test.t.a]", " Projection_9 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a,Column#25]", @@ -461,13 +461,13 @@ "Group#6 Schema:[test.t.a,Column#25]", " Projection_5 input:[Group#7], test.t.a, test.t.b", "Group#7 Schema:[test.t.a,test.t.b]", - " TopN_18 input:[Group#8], test.t.b:asc, offset:0, count:1", + " TopN_14 input:[Group#8], test.t.b:asc, offset:0, count:1", "Group#8 Schema:[test.t.a,test.t.b]", " Selection_4 input:[Group#9], gt(test.t.b, test.t.b)", "Group#9 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_15 input:[Group#10], table:t2", + " TiKVSingleGather_18 input:[Group#10], table:t2", "Group#10 Schema:[test.t.a,test.t.b]", - " TableScan_14 table:t2, pk col:test.t.a" + " TableScan_17 table:t2, pk col:test.t.a" ] }, { @@ -476,31 +476,31 @@ "Group#0 Schema:[Column#13,Column#14]", " Projection_3 input:[Group#1], Column#13, Column#14", "Group#1 Schema:[Column#13,Column#14]", - " TopN_21 input:[Group#2], Column#13:desc, offset:0, count:1", + " TopN_7 input:[Group#2], Column#13:desc, offset:0, count:1", "Group#2 Schema:[Column#13,Column#14]", " Projection_2 input:[Group#3], getvar(i)->Column#13, setvar(i, cast(plus(cast(getvar(i), double BINARY), 1), var_string(5)))->Column#14", "Group#3 Schema:[test.t.a]", - " TiKVSingleGather_7 input:[Group#4], table:t", - " TiKVSingleGather_19 input:[Group#5], table:t, index:e_d_c_str_prefix", - " TiKVSingleGather_17 input:[Group#6], table:t, index:c_d_e_str", - " TiKVSingleGather_15 input:[Group#7], table:t, index:f_g", - " TiKVSingleGather_13 input:[Group#8], table:t, index:g", - " TiKVSingleGather_11 input:[Group#9], table:t, index:f", - " TiKVSingleGather_9 input:[Group#10], table:t, index:c_d_e", + " TiKVSingleGather_9 input:[Group#4], table:t", + " TiKVSingleGather_21 input:[Group#5], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_19 input:[Group#6], table:t, index:c_d_e_str", + " TiKVSingleGather_17 input:[Group#7], table:t, index:f_g", + " TiKVSingleGather_15 input:[Group#8], table:t, index:g", + " TiKVSingleGather_13 input:[Group#9], table:t, index:f", + " TiKVSingleGather_11 input:[Group#10], table:t, index:c_d_e", "Group#4 Schema:[test.t.a]", - " TableScan_6 table:t, pk col:test.t.a", + " TableScan_8 table:t, pk col:test.t.a", "Group#5 Schema:[test.t.a]", - " IndexScan_18 table:t, index:e_str, d_str, c_str", + " IndexScan_20 table:t, index:e_str, d_str, c_str", "Group#6 Schema:[test.t.a]", - " IndexScan_16 table:t, index:c_str, d_str, e_str", + " IndexScan_18 table:t, index:c_str, d_str, e_str", "Group#7 Schema:[test.t.a]", - " IndexScan_14 table:t, index:f, g", + " IndexScan_16 table:t, index:f, g", "Group#8 Schema:[test.t.a]", - " IndexScan_12 table:t, index:g", + " IndexScan_14 table:t, index:g", "Group#9 Schema:[test.t.a]", - " IndexScan_10 table:t, index:f", + " IndexScan_12 table:t, index:f", "Group#10 Schema:[test.t.a]", - " IndexScan_8 table:t, index:c, d, e" + " IndexScan_10 table:t, index:c, d, e" ] }, { @@ -509,21 +509,21 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.b:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.b:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_13 input:[Group#5], test.t.b:asc, offset:0, count:1", + " TopN_9 input:[Group#5], test.t.b:asc, offset:0, count:1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#6], table:t1", + " TiKVSingleGather_11 input:[Group#6], table:t1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_14 input:[Group#7], test.t.b:asc, offset:0, count:1", + " TopN_12 input:[Group#7], test.t.b:asc, offset:0, count:1", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_10 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#8], table:t2", + " TiKVSingleGather_14 input:[Group#8], table:t2", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_13 table:t2, pk col:test.t.a" ] }, { @@ -532,21 +532,21 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_13 input:[Group#5], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_9 input:[Group#5], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#6], table:t1", + " TiKVSingleGather_11 input:[Group#6], table:t1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_14 input:[Group#7], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_12 input:[Group#7], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_10 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#8], table:t2", + " TiKVSingleGather_14 input:[Group#8], table:t2", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_13 table:t2, pk col:test.t.a" ] }, { @@ -555,17 +555,17 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#5], table:t1", + " TiKVSingleGather_10 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_9 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#6], table:t2", + " TiKVSingleGather_12 input:[Group#6], table:t2", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_11 table:t2, pk col:test.t.a" ] }, { @@ -574,17 +574,17 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#5], table:t1", + " TiKVSingleGather_10 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_9 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#6], table:t2", + " TiKVSingleGather_12 input:[Group#6], table:t2", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_11 table:t2, pk col:test.t.a" ] }, { @@ -593,17 +593,17 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#5], table:t1", + " TiKVSingleGather_10 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_9 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#6], table:t2", + " TiKVSingleGather_12 input:[Group#6], table:t2", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_11 table:t2, pk col:test.t.a" ] }, { @@ -612,21 +612,21 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#5], table:t1", + " TiKVSingleGather_11 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_10 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_13 input:[Group#6], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_9 input:[Group#6], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#7], table:t2", + " TiKVSingleGather_13 input:[Group#7], table:t2", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " TopN_14 input:[Group#8], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_12 table:t2, pk col:test.t.a" ] }, { @@ -635,17 +635,17 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", + " TopN_8 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_8 input:[Group#5], table:t1", + " TiKVSingleGather_10 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_7 table:t1, pk col:test.t.a", + " TableScan_9 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_10 input:[Group#6], table:t2", + " TiKVSingleGather_12 input:[Group#6], table:t2", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_9 table:t2, pk col:test.t.a" + " TableScan_11 table:t2, pk col:test.t.a" ] }, { @@ -658,17 +658,17 @@ "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_10 input:[Group#5], offset:0, count:1", + " Limit_6 input:[Group#5], offset:0, count:1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_7 input:[Group#6], table:t1", + " TiKVSingleGather_8 input:[Group#6], table:t1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_11 input:[Group#7], offset:0, count:1", + " Limit_9 input:[Group#7], offset:0, count:1", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_6 table:t1, pk col:test.t.a", + " TableScan_7 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_9 input:[Group#8], table:t2", + " TiKVSingleGather_11 input:[Group#8], table:t2", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_8 table:t2, pk col:test.t.a" + " TableScan_10 table:t2, pk col:test.t.a" ] }, { @@ -681,17 +681,17 @@ "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_10 input:[Group#5], offset:0, count:9", + " Limit_6 input:[Group#5], offset:0, count:9", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_7 input:[Group#6], table:t1", + " TiKVSingleGather_8 input:[Group#6], table:t1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_11 input:[Group#7], offset:0, count:9", + " Limit_9 input:[Group#7], offset:0, count:9", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_6 table:t1, pk col:test.t.a", + " TableScan_7 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_9 input:[Group#8], table:t2", + " TiKVSingleGather_11 input:[Group#8], table:t2", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_8 table:t2, pk col:test.t.a" + " TableScan_10 table:t2, pk col:test.t.a" ] }, { @@ -704,17 +704,17 @@ "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_7 input:[Group#5], table:t1", + " TiKVSingleGather_8 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_6 table:t1, pk col:test.t.a", + " TableScan_7 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_10 input:[Group#6], offset:0, count:1", + " Limit_6 input:[Group#6], offset:0, count:1", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_9 input:[Group#7], table:t2", + " TiKVSingleGather_10 input:[Group#7], table:t2", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Limit_11 input:[Group#8], offset:0, count:1", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_8 table:t2, pk col:test.t.a" + " TableScan_9 table:t2, pk col:test.t.a" ] }, { @@ -727,24 +727,24 @@ "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_7 input:[Group#5], table:t1", + " TiKVSingleGather_8 input:[Group#5], table:t1", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_6 table:t1, pk col:test.t.a", + " TableScan_7 table:t1, pk col:test.t.a", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Limit_10 input:[Group#6], offset:0, count:9", + " Limit_6 input:[Group#6], offset:0, count:9", "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TiKVSingleGather_9 input:[Group#7], table:t2", + " TiKVSingleGather_10 input:[Group#7], table:t2", "Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Limit_11 input:[Group#8], offset:0, count:9", "Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " TableScan_8 table:t2, pk col:test.t.a" + " TableScan_9 table:t2, pk col:test.t.a" ] }, { "SQL": "(select a from t) union all (select b from t) order by a limit 2;", "Result": [ "Group#0 Schema:[Column#25]", - " TopN_26 input:[Group#1], Column#25:asc, offset:0, count:2", + " TopN_10 input:[Group#1], Column#25:asc, offset:0, count:2", "Group#1 Schema:[Column#25]", " Union_5 input:[Group#2,Group#3]", "Group#2 Schema:[Column#25]", @@ -752,67 +752,67 @@ "Group#4 Schema:[test.t.a]", " Projection_4 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a]", - " TopN_29 input:[Group#6], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#7], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#8], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#9], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#10], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#11], test.t.a:asc, offset:0, count:2", - " TopN_29 input:[Group#12], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#6], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#7], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#8], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#9], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#10], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#11], test.t.a:asc, offset:0, count:2", + " TopN_13 input:[Group#12], test.t.a:asc, offset:0, count:2", "Group#6 Schema:[test.t.a]", - " TiKVSingleGather_13 input:[Group#13], table:t, index:c_d_e", + " TiKVSingleGather_19 input:[Group#13], table:t, index:c_d_e", "Group#13 Schema:[test.t.a]", " TopN_36 input:[Group#14], test.t.a:asc, offset:0, count:2", "Group#14 Schema:[test.t.a]", - " IndexScan_12 table:t, index:c, d, e", + " IndexScan_18 table:t, index:c, d, e", "Group#7 Schema:[test.t.a]", - " TiKVSingleGather_15 input:[Group#15], table:t, index:f", + " TiKVSingleGather_21 input:[Group#15], table:t, index:f", "Group#15 Schema:[test.t.a]", " TopN_35 input:[Group#16], test.t.a:asc, offset:0, count:2", "Group#16 Schema:[test.t.a]", - " IndexScan_14 table:t, index:f", + " IndexScan_20 table:t, index:f", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_17 input:[Group#17], table:t, index:g", + " TiKVSingleGather_23 input:[Group#17], table:t, index:g", "Group#17 Schema:[test.t.a]", " TopN_34 input:[Group#18], test.t.a:asc, offset:0, count:2", "Group#18 Schema:[test.t.a]", - " IndexScan_16 table:t, index:g", + " IndexScan_22 table:t, index:g", "Group#9 Schema:[test.t.a]", - " TiKVSingleGather_19 input:[Group#19], table:t, index:f_g", + " TiKVSingleGather_25 input:[Group#19], table:t, index:f_g", "Group#19 Schema:[test.t.a]", " TopN_33 input:[Group#20], test.t.a:asc, offset:0, count:2", "Group#20 Schema:[test.t.a]", - " IndexScan_18 table:t, index:f, g", + " IndexScan_24 table:t, index:f, g", "Group#10 Schema:[test.t.a]", - " TiKVSingleGather_21 input:[Group#21], table:t, index:c_d_e_str", + " TiKVSingleGather_27 input:[Group#21], table:t, index:c_d_e_str", "Group#21 Schema:[test.t.a]", " TopN_32 input:[Group#22], test.t.a:asc, offset:0, count:2", "Group#22 Schema:[test.t.a]", - " IndexScan_20 table:t, index:c_str, d_str, e_str", + " IndexScan_26 table:t, index:c_str, d_str, e_str", "Group#11 Schema:[test.t.a]", - " TiKVSingleGather_23 input:[Group#23], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_29 input:[Group#23], table:t, index:e_d_c_str_prefix", "Group#23 Schema:[test.t.a]", " TopN_31 input:[Group#24], test.t.a:asc, offset:0, count:2", "Group#24 Schema:[test.t.a]", - " IndexScan_22 table:t, index:e_str, d_str, c_str", + " IndexScan_28 table:t, index:e_str, d_str, c_str", "Group#12 Schema:[test.t.a]", - " TiKVSingleGather_11 input:[Group#25], table:t", + " TiKVSingleGather_17 input:[Group#25], table:t", "Group#25 Schema:[test.t.a]", " TopN_30 input:[Group#26], test.t.a:asc, offset:0, count:2", "Group#26 Schema:[test.t.a]", - " TableScan_10 table:t, pk col:test.t.a", + " TableScan_16 table:t, pk col:test.t.a", "Group#3 Schema:[Column#25]", " Projection_7 input:[Group#27], test.t.b", "Group#27 Schema:[test.t.b]", " Projection_2 input:[Group#28], test.t.b", "Group#28 Schema:[test.t.b]", - " TopN_38 input:[Group#29], test.t.b:asc, offset:0, count:2", + " TopN_15 input:[Group#29], test.t.b:asc, offset:0, count:2", "Group#29 Schema:[test.t.b]", - " TiKVSingleGather_25 input:[Group#30], table:t", + " TiKVSingleGather_38 input:[Group#30], table:t", "Group#30 Schema:[test.t.b]", " TopN_39 input:[Group#31], test.t.b:asc, offset:0, count:2", "Group#31 Schema:[test.t.b]", - " TableScan_24 table:t" + " TableScan_37 table:t" ] }, { @@ -827,67 +827,67 @@ "Group#4 Schema:[test.t.a]", " Projection_4 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a]", - " Limit_25 input:[Group#6], offset:0, count:2", - " Limit_25 input:[Group#7], offset:0, count:2", - " Limit_25 input:[Group#8], offset:0, count:2", - " Limit_25 input:[Group#9], offset:0, count:2", - " Limit_25 input:[Group#10], offset:0, count:2", - " Limit_25 input:[Group#11], offset:0, count:2", - " Limit_25 input:[Group#12], offset:0, count:2", + " Limit_9 input:[Group#6], offset:0, count:2", + " Limit_9 input:[Group#7], offset:0, count:2", + " Limit_9 input:[Group#8], offset:0, count:2", + " Limit_9 input:[Group#9], offset:0, count:2", + " Limit_9 input:[Group#10], offset:0, count:2", + " Limit_9 input:[Group#11], offset:0, count:2", + " Limit_9 input:[Group#12], offset:0, count:2", "Group#6 Schema:[test.t.a]", - " TiKVSingleGather_12 input:[Group#13], table:t, index:c_d_e", + " TiKVSingleGather_13 input:[Group#13], table:t, index:c_d_e", "Group#13 Schema:[test.t.a]", - " Limit_32 input:[Group#14], offset:0, count:2", + " Limit_30 input:[Group#14], offset:0, count:2", "Group#14 Schema:[test.t.a]", - " IndexScan_11 table:t, index:c, d, e", + " IndexScan_12 table:t, index:c, d, e", "Group#7 Schema:[test.t.a]", - " TiKVSingleGather_14 input:[Group#15], table:t, index:f", + " TiKVSingleGather_15 input:[Group#15], table:t, index:f", "Group#15 Schema:[test.t.a]", - " Limit_31 input:[Group#16], offset:0, count:2", + " Limit_29 input:[Group#16], offset:0, count:2", "Group#16 Schema:[test.t.a]", - " IndexScan_13 table:t, index:f", + " IndexScan_14 table:t, index:f", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_16 input:[Group#17], table:t, index:g", + " TiKVSingleGather_17 input:[Group#17], table:t, index:g", "Group#17 Schema:[test.t.a]", - " Limit_30 input:[Group#18], offset:0, count:2", + " Limit_28 input:[Group#18], offset:0, count:2", "Group#18 Schema:[test.t.a]", - " IndexScan_15 table:t, index:g", + " IndexScan_16 table:t, index:g", "Group#9 Schema:[test.t.a]", - " TiKVSingleGather_18 input:[Group#19], table:t, index:f_g", + " TiKVSingleGather_19 input:[Group#19], table:t, index:f_g", "Group#19 Schema:[test.t.a]", - " Limit_29 input:[Group#20], offset:0, count:2", + " Limit_27 input:[Group#20], offset:0, count:2", "Group#20 Schema:[test.t.a]", - " IndexScan_17 table:t, index:f, g", + " IndexScan_18 table:t, index:f, g", "Group#10 Schema:[test.t.a]", - " TiKVSingleGather_20 input:[Group#21], table:t, index:c_d_e_str", + " TiKVSingleGather_21 input:[Group#21], table:t, index:c_d_e_str", "Group#21 Schema:[test.t.a]", - " Limit_28 input:[Group#22], offset:0, count:2", + " Limit_26 input:[Group#22], offset:0, count:2", "Group#22 Schema:[test.t.a]", - " IndexScan_19 table:t, index:c_str, d_str, e_str", + " IndexScan_20 table:t, index:c_str, d_str, e_str", "Group#11 Schema:[test.t.a]", - " TiKVSingleGather_22 input:[Group#23], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_23 input:[Group#23], table:t, index:e_d_c_str_prefix", "Group#23 Schema:[test.t.a]", - " Limit_27 input:[Group#24], offset:0, count:2", + " Limit_25 input:[Group#24], offset:0, count:2", "Group#24 Schema:[test.t.a]", - " IndexScan_21 table:t, index:e_str, d_str, c_str", + " IndexScan_22 table:t, index:e_str, d_str, c_str", "Group#12 Schema:[test.t.a]", - " TiKVSingleGather_10 input:[Group#25], table:t", + " TiKVSingleGather_11 input:[Group#25], table:t", "Group#25 Schema:[test.t.a]", - " Limit_26 input:[Group#26], offset:0, count:2", + " Limit_24 input:[Group#26], offset:0, count:2", "Group#26 Schema:[test.t.a]", - " TableScan_9 table:t, pk col:test.t.a", + " TableScan_10 table:t, pk col:test.t.a", "Group#3 Schema:[Column#25]", " Projection_7 input:[Group#27], test.t.b", "Group#27 Schema:[test.t.b]", " Projection_2 input:[Group#28], test.t.b", "Group#28 Schema:[test.t.b]", - " Limit_25 input:[Group#29], offset:0, count:2", + " Limit_9 input:[Group#29], offset:0, count:2", "Group#29 Schema:[test.t.b]", - " TiKVSingleGather_24 input:[Group#30], table:t", + " TiKVSingleGather_32 input:[Group#30], table:t", "Group#30 Schema:[test.t.b]", " Limit_33 input:[Group#31], offset:0, count:2", "Group#31 Schema:[test.t.b]", - " TableScan_23 table:t" + " TableScan_31 table:t" ] }, { @@ -902,74 +902,74 @@ "Group#4 Schema:[test.t.a]", " Projection_4 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a]", - " Limit_25 input:[Group#6], offset:0, count:7", - " Limit_25 input:[Group#7], offset:0, count:7", - " Limit_25 input:[Group#8], offset:0, count:7", - " Limit_25 input:[Group#9], offset:0, count:7", - " Limit_25 input:[Group#10], offset:0, count:7", - " Limit_25 input:[Group#11], offset:0, count:7", - " Limit_25 input:[Group#12], offset:0, count:7", + " Limit_9 input:[Group#6], offset:0, count:7", + " Limit_9 input:[Group#7], offset:0, count:7", + " Limit_9 input:[Group#8], offset:0, count:7", + " Limit_9 input:[Group#9], offset:0, count:7", + " Limit_9 input:[Group#10], offset:0, count:7", + " Limit_9 input:[Group#11], offset:0, count:7", + " Limit_9 input:[Group#12], offset:0, count:7", "Group#6 Schema:[test.t.a]", - " TiKVSingleGather_12 input:[Group#13], table:t, index:c_d_e", + " TiKVSingleGather_13 input:[Group#13], table:t, index:c_d_e", "Group#13 Schema:[test.t.a]", - " Limit_32 input:[Group#14], offset:0, count:7", + " Limit_30 input:[Group#14], offset:0, count:7", "Group#14 Schema:[test.t.a]", - " IndexScan_11 table:t, index:c, d, e", + " IndexScan_12 table:t, index:c, d, e", "Group#7 Schema:[test.t.a]", - " TiKVSingleGather_14 input:[Group#15], table:t, index:f", + " TiKVSingleGather_15 input:[Group#15], table:t, index:f", "Group#15 Schema:[test.t.a]", - " Limit_31 input:[Group#16], offset:0, count:7", + " Limit_29 input:[Group#16], offset:0, count:7", "Group#16 Schema:[test.t.a]", - " IndexScan_13 table:t, index:f", + " IndexScan_14 table:t, index:f", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_16 input:[Group#17], table:t, index:g", + " TiKVSingleGather_17 input:[Group#17], table:t, index:g", "Group#17 Schema:[test.t.a]", - " Limit_30 input:[Group#18], offset:0, count:7", + " Limit_28 input:[Group#18], offset:0, count:7", "Group#18 Schema:[test.t.a]", - " IndexScan_15 table:t, index:g", + " IndexScan_16 table:t, index:g", "Group#9 Schema:[test.t.a]", - " TiKVSingleGather_18 input:[Group#19], table:t, index:f_g", + " TiKVSingleGather_19 input:[Group#19], table:t, index:f_g", "Group#19 Schema:[test.t.a]", - " Limit_29 input:[Group#20], offset:0, count:7", + " Limit_27 input:[Group#20], offset:0, count:7", "Group#20 Schema:[test.t.a]", - " IndexScan_17 table:t, index:f, g", + " IndexScan_18 table:t, index:f, g", "Group#10 Schema:[test.t.a]", - " TiKVSingleGather_20 input:[Group#21], table:t, index:c_d_e_str", + " TiKVSingleGather_21 input:[Group#21], table:t, index:c_d_e_str", "Group#21 Schema:[test.t.a]", - " Limit_28 input:[Group#22], offset:0, count:7", + " Limit_26 input:[Group#22], offset:0, count:7", "Group#22 Schema:[test.t.a]", - " IndexScan_19 table:t, index:c_str, d_str, e_str", + " IndexScan_20 table:t, index:c_str, d_str, e_str", "Group#11 Schema:[test.t.a]", - " TiKVSingleGather_22 input:[Group#23], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_23 input:[Group#23], table:t, index:e_d_c_str_prefix", "Group#23 Schema:[test.t.a]", - " Limit_27 input:[Group#24], offset:0, count:7", + " Limit_25 input:[Group#24], offset:0, count:7", "Group#24 Schema:[test.t.a]", - " IndexScan_21 table:t, index:e_str, d_str, c_str", + " IndexScan_22 table:t, index:e_str, d_str, c_str", "Group#12 Schema:[test.t.a]", - " TiKVSingleGather_10 input:[Group#25], table:t", + " TiKVSingleGather_11 input:[Group#25], table:t", "Group#25 Schema:[test.t.a]", - " Limit_26 input:[Group#26], offset:0, count:7", + " Limit_24 input:[Group#26], offset:0, count:7", "Group#26 Schema:[test.t.a]", - " TableScan_9 table:t, pk col:test.t.a", + " TableScan_10 table:t, pk col:test.t.a", "Group#3 Schema:[Column#25]", " Projection_7 input:[Group#27], test.t.b", "Group#27 Schema:[test.t.b]", " Projection_2 input:[Group#28], test.t.b", "Group#28 Schema:[test.t.b]", - " Limit_25 input:[Group#29], offset:0, count:7", + " Limit_9 input:[Group#29], offset:0, count:7", "Group#29 Schema:[test.t.b]", - " TiKVSingleGather_24 input:[Group#30], table:t", + " TiKVSingleGather_32 input:[Group#30], table:t", "Group#30 Schema:[test.t.b]", " Limit_33 input:[Group#31], offset:0, count:7", "Group#31 Schema:[test.t.b]", - " TableScan_23 table:t" + " TableScan_31 table:t" ] }, { "SQL": "(select a from t) union all (select sum(a) from t where a > 2 group by b) order by a limit 2;", "Result": [ "Group#0 Schema:[Column#26]", - " TopN_28 input:[Group#1], Column#26:asc, offset:0, count:2", + " TopN_12 input:[Group#1], Column#26:asc, offset:0, count:2", "Group#1 Schema:[Column#26]", " Union_7 input:[Group#2,Group#3]", "Group#2 Schema:[Column#26]", @@ -977,76 +977,76 @@ "Group#4 Schema:[test.t.a]", " Projection_6 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a]", - " TopN_31 input:[Group#6], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#7], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#8], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#9], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#10], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#11], cast(test.t.a):asc, offset:0, count:2", - " TopN_31 input:[Group#12], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#6], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#7], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#8], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#9], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#10], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#11], cast(test.t.a):asc, offset:0, count:2", + " TopN_15 input:[Group#12], cast(test.t.a):asc, offset:0, count:2", "Group#6 Schema:[test.t.a]", - " TiKVSingleGather_15 input:[Group#13], table:t, index:c_d_e", + " TiKVSingleGather_21 input:[Group#13], table:t, index:c_d_e", "Group#13 Schema:[test.t.a]", " TopN_38 input:[Group#14], cast(test.t.a):asc, offset:0, count:2", "Group#14 Schema:[test.t.a]", - " IndexScan_14 table:t, index:c, d, e", + " IndexScan_20 table:t, index:c, d, e", "Group#7 Schema:[test.t.a]", - " TiKVSingleGather_17 input:[Group#15], table:t, index:f", + " TiKVSingleGather_23 input:[Group#15], table:t, index:f", "Group#15 Schema:[test.t.a]", " TopN_37 input:[Group#16], cast(test.t.a):asc, offset:0, count:2", "Group#16 Schema:[test.t.a]", - " IndexScan_16 table:t, index:f", + " IndexScan_22 table:t, index:f", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_19 input:[Group#17], table:t, index:g", + " TiKVSingleGather_25 input:[Group#17], table:t, index:g", "Group#17 Schema:[test.t.a]", " TopN_36 input:[Group#18], cast(test.t.a):asc, offset:0, count:2", "Group#18 Schema:[test.t.a]", - " IndexScan_18 table:t, index:g", + " IndexScan_24 table:t, index:g", "Group#9 Schema:[test.t.a]", - " TiKVSingleGather_21 input:[Group#19], table:t, index:f_g", + " TiKVSingleGather_27 input:[Group#19], table:t, index:f_g", "Group#19 Schema:[test.t.a]", " TopN_35 input:[Group#20], cast(test.t.a):asc, offset:0, count:2", "Group#20 Schema:[test.t.a]", - " IndexScan_20 table:t, index:f, g", + " IndexScan_26 table:t, index:f, g", "Group#10 Schema:[test.t.a]", - " TiKVSingleGather_23 input:[Group#21], table:t, index:c_d_e_str", + " TiKVSingleGather_29 input:[Group#21], table:t, index:c_d_e_str", "Group#21 Schema:[test.t.a]", " TopN_34 input:[Group#22], cast(test.t.a):asc, offset:0, count:2", "Group#22 Schema:[test.t.a]", - " IndexScan_22 table:t, index:c_str, d_str, e_str", + " IndexScan_28 table:t, index:c_str, d_str, e_str", "Group#11 Schema:[test.t.a]", - " TiKVSingleGather_25 input:[Group#23], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_31 input:[Group#23], table:t, index:e_d_c_str_prefix", "Group#23 Schema:[test.t.a]", " TopN_33 input:[Group#24], cast(test.t.a):asc, offset:0, count:2", "Group#24 Schema:[test.t.a]", - " IndexScan_24 table:t, index:e_str, d_str, c_str", + " IndexScan_30 table:t, index:e_str, d_str, c_str", "Group#12 Schema:[test.t.a]", - " TiKVSingleGather_13 input:[Group#25], table:t", + " TiKVSingleGather_19 input:[Group#25], table:t", "Group#25 Schema:[test.t.a]", " TopN_32 input:[Group#26], cast(test.t.a):asc, offset:0, count:2", "Group#26 Schema:[test.t.a]", - " TableScan_12 table:t, pk col:test.t.a", + " TableScan_18 table:t, pk col:test.t.a", "Group#3 Schema:[Column#26]", " Projection_9 input:[Group#27], cast(Column#13, decimal(65,0) BINARY)->Column#26", "Group#27 Schema:[Column#13]", " Projection_4 input:[Group#28], Column#13", "Group#28 Schema:[Column#13]", - " TopN_40 input:[Group#29], cast(Column#13):asc, offset:0, count:2", + " TopN_17 input:[Group#29], cast(Column#13):asc, offset:0, count:2", "Group#29 Schema:[Column#13]", " Aggregation_3 input:[Group#30], group by:test.t.b, funcs:sum(test.t.a)", "Group#30 Schema:[test.t.a,test.t.b]", " Selection_2 input:[Group#31], gt(test.t.a, 2)", "Group#31 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_27 input:[Group#32], table:t", + " TiKVSingleGather_40 input:[Group#32], table:t", "Group#32 Schema:[test.t.a,test.t.b]", - " TableScan_26 table:t, pk col:test.t.a" + " TableScan_39 table:t, pk col:test.t.a" ] }, { "SQL": "(select a from t) union all (select sum(a) from t where a > 2 group by b) order by a limit 1, 2;", "Result": [ "Group#0 Schema:[Column#26]", - " TopN_28 input:[Group#1], Column#26:asc, offset:1, count:2", + " TopN_12 input:[Group#1], Column#26:asc, offset:1, count:2", "Group#1 Schema:[Column#26]", " Union_7 input:[Group#2,Group#3]", "Group#2 Schema:[Column#26]", @@ -1054,76 +1054,76 @@ "Group#4 Schema:[test.t.a]", " Projection_6 input:[Group#5], test.t.a", "Group#5 Schema:[test.t.a]", - " TopN_31 input:[Group#6], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#7], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#8], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#9], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#10], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#11], cast(test.t.a):asc, offset:0, count:3", - " TopN_31 input:[Group#12], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#6], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#7], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#8], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#9], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#10], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#11], cast(test.t.a):asc, offset:0, count:3", + " TopN_15 input:[Group#12], cast(test.t.a):asc, offset:0, count:3", "Group#6 Schema:[test.t.a]", - " TiKVSingleGather_15 input:[Group#13], table:t, index:c_d_e", + " TiKVSingleGather_21 input:[Group#13], table:t, index:c_d_e", "Group#13 Schema:[test.t.a]", " TopN_38 input:[Group#14], cast(test.t.a):asc, offset:0, count:3", "Group#14 Schema:[test.t.a]", - " IndexScan_14 table:t, index:c, d, e", + " IndexScan_20 table:t, index:c, d, e", "Group#7 Schema:[test.t.a]", - " TiKVSingleGather_17 input:[Group#15], table:t, index:f", + " TiKVSingleGather_23 input:[Group#15], table:t, index:f", "Group#15 Schema:[test.t.a]", " TopN_37 input:[Group#16], cast(test.t.a):asc, offset:0, count:3", "Group#16 Schema:[test.t.a]", - " IndexScan_16 table:t, index:f", + " IndexScan_22 table:t, index:f", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_19 input:[Group#17], table:t, index:g", + " TiKVSingleGather_25 input:[Group#17], table:t, index:g", "Group#17 Schema:[test.t.a]", " TopN_36 input:[Group#18], cast(test.t.a):asc, offset:0, count:3", "Group#18 Schema:[test.t.a]", - " IndexScan_18 table:t, index:g", + " IndexScan_24 table:t, index:g", "Group#9 Schema:[test.t.a]", - " TiKVSingleGather_21 input:[Group#19], table:t, index:f_g", + " TiKVSingleGather_27 input:[Group#19], table:t, index:f_g", "Group#19 Schema:[test.t.a]", " TopN_35 input:[Group#20], cast(test.t.a):asc, offset:0, count:3", "Group#20 Schema:[test.t.a]", - " IndexScan_20 table:t, index:f, g", + " IndexScan_26 table:t, index:f, g", "Group#10 Schema:[test.t.a]", - " TiKVSingleGather_23 input:[Group#21], table:t, index:c_d_e_str", + " TiKVSingleGather_29 input:[Group#21], table:t, index:c_d_e_str", "Group#21 Schema:[test.t.a]", " TopN_34 input:[Group#22], cast(test.t.a):asc, offset:0, count:3", "Group#22 Schema:[test.t.a]", - " IndexScan_22 table:t, index:c_str, d_str, e_str", + " IndexScan_28 table:t, index:c_str, d_str, e_str", "Group#11 Schema:[test.t.a]", - " TiKVSingleGather_25 input:[Group#23], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_31 input:[Group#23], table:t, index:e_d_c_str_prefix", "Group#23 Schema:[test.t.a]", " TopN_33 input:[Group#24], cast(test.t.a):asc, offset:0, count:3", "Group#24 Schema:[test.t.a]", - " IndexScan_24 table:t, index:e_str, d_str, c_str", + " IndexScan_30 table:t, index:e_str, d_str, c_str", "Group#12 Schema:[test.t.a]", - " TiKVSingleGather_13 input:[Group#25], table:t", + " TiKVSingleGather_19 input:[Group#25], table:t", "Group#25 Schema:[test.t.a]", " TopN_32 input:[Group#26], cast(test.t.a):asc, offset:0, count:3", "Group#26 Schema:[test.t.a]", - " TableScan_12 table:t, pk col:test.t.a", + " TableScan_18 table:t, pk col:test.t.a", "Group#3 Schema:[Column#26]", " Projection_9 input:[Group#27], cast(Column#13, decimal(65,0) BINARY)->Column#26", "Group#27 Schema:[Column#13]", " Projection_4 input:[Group#28], Column#13", "Group#28 Schema:[Column#13]", - " TopN_40 input:[Group#29], cast(Column#13):asc, offset:0, count:3", + " TopN_17 input:[Group#29], cast(Column#13):asc, offset:0, count:3", "Group#29 Schema:[Column#13]", " Aggregation_3 input:[Group#30], group by:test.t.b, funcs:sum(test.t.a)", "Group#30 Schema:[test.t.a,test.t.b]", " Selection_2 input:[Group#31], gt(test.t.a, 2)", "Group#31 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_27 input:[Group#32], table:t", + " TiKVSingleGather_40 input:[Group#32], table:t", "Group#32 Schema:[test.t.a,test.t.b]", - " TableScan_26 table:t, pk col:test.t.a" + " TableScan_39 table:t, pk col:test.t.a" ] }, { "SQL": "(select a from t where a = 1) union all (select b from t where a = 2) union all (select c from t where a = 3) order by a limit 2;", "Result": [ "Group#0 Schema:[Column#37]", - " TopN_36 input:[Group#1], Column#37:asc, offset:0, count:2", + " TopN_16 input:[Group#1], Column#37:asc, offset:0, count:2", "Group#1 Schema:[Column#37]", " Union_10 input:[Group#2,Group#3,Group#4]", "Group#2 Schema:[Column#37]", @@ -1131,58 +1131,58 @@ "Group#5 Schema:[test.t.a]", " Projection_9 input:[Group#6], test.t.a", "Group#6 Schema:[test.t.a]", - " TopN_39 input:[Group#7], test.t.a:asc, offset:0, count:2", + " TopN_19 input:[Group#7], test.t.a:asc, offset:0, count:2", "Group#7 Schema:[test.t.a]", " Selection_8 input:[Group#8], eq(test.t.a, 1)", "Group#8 Schema:[test.t.a]", - " TiKVSingleGather_17 input:[Group#9], table:t", - " TiKVSingleGather_29 input:[Group#10], table:t, index:e_d_c_str_prefix", - " TiKVSingleGather_27 input:[Group#11], table:t, index:c_d_e_str", - " TiKVSingleGather_25 input:[Group#12], table:t, index:f_g", - " TiKVSingleGather_23 input:[Group#13], table:t, index:g", - " TiKVSingleGather_21 input:[Group#14], table:t, index:f", - " TiKVSingleGather_19 input:[Group#15], table:t, index:c_d_e", + " TiKVSingleGather_25 input:[Group#9], table:t", + " TiKVSingleGather_37 input:[Group#10], table:t, index:e_d_c_str_prefix", + " TiKVSingleGather_35 input:[Group#11], table:t, index:c_d_e_str", + " TiKVSingleGather_33 input:[Group#12], table:t, index:f_g", + " TiKVSingleGather_31 input:[Group#13], table:t, index:g", + " TiKVSingleGather_29 input:[Group#14], table:t, index:f", + " TiKVSingleGather_27 input:[Group#15], table:t, index:c_d_e", "Group#9 Schema:[test.t.a]", - " TableScan_16 table:t, pk col:test.t.a", + " TableScan_24 table:t, pk col:test.t.a", "Group#10 Schema:[test.t.a]", - " IndexScan_28 table:t, index:e_str, d_str, c_str", + " IndexScan_36 table:t, index:e_str, d_str, c_str", "Group#11 Schema:[test.t.a]", - " IndexScan_26 table:t, index:c_str, d_str, e_str", + " IndexScan_34 table:t, index:c_str, d_str, e_str", "Group#12 Schema:[test.t.a]", - " IndexScan_24 table:t, index:f, g", + " IndexScan_32 table:t, index:f, g", "Group#13 Schema:[test.t.a]", - " IndexScan_22 table:t, index:g", + " IndexScan_30 table:t, index:g", "Group#14 Schema:[test.t.a]", - " IndexScan_20 table:t, index:f", + " IndexScan_28 table:t, index:f", "Group#15 Schema:[test.t.a]", - " IndexScan_18 table:t, index:c, d, e", + " IndexScan_26 table:t, index:c, d, e", "Group#3 Schema:[Column#37]", " Projection_12 input:[Group#16], test.t.b", "Group#16 Schema:[test.t.b]", " Projection_6 input:[Group#17], test.t.b", "Group#17 Schema:[test.t.a,test.t.b]", - " TopN_41 input:[Group#18], test.t.b:asc, offset:0, count:2", + " TopN_21 input:[Group#18], test.t.b:asc, offset:0, count:2", "Group#18 Schema:[test.t.a,test.t.b]", " Selection_5 input:[Group#19], eq(test.t.a, 2)", "Group#19 Schema:[test.t.a,test.t.b]", - " TiKVSingleGather_31 input:[Group#20], table:t", + " TiKVSingleGather_39 input:[Group#20], table:t", "Group#20 Schema:[test.t.a,test.t.b]", - " TableScan_30 table:t, pk col:test.t.a", + " TableScan_38 table:t, pk col:test.t.a", "Group#4 Schema:[Column#37]", " Projection_13 input:[Group#21], test.t.c", "Group#21 Schema:[test.t.c]", " Projection_3 input:[Group#22], test.t.c", "Group#22 Schema:[test.t.a,test.t.c]", - " TopN_43 input:[Group#23], test.t.c:asc, offset:0, count:2", + " TopN_23 input:[Group#23], test.t.c:asc, offset:0, count:2", "Group#23 Schema:[test.t.a,test.t.c]", " Selection_2 input:[Group#24], eq(test.t.a, 3)", "Group#24 Schema:[test.t.a,test.t.c]", - " TiKVSingleGather_33 input:[Group#25], table:t", - " TiKVSingleGather_35 input:[Group#26], table:t, index:c_d_e", + " TiKVSingleGather_41 input:[Group#25], table:t", + " TiKVSingleGather_43 input:[Group#26], table:t, index:c_d_e", "Group#25 Schema:[test.t.a,test.t.c]", - " TableScan_32 table:t, pk col:test.t.a", + " TableScan_40 table:t, pk col:test.t.a", "Group#26 Schema:[test.t.a,test.t.c]", - " IndexScan_34 table:t, index:c, d, e" + " IndexScan_42 table:t, index:c, d, e" ] } ] @@ -1595,6 +1595,48 @@ } ] }, + { + "Name": "TestPostTransformationRules", + "Cases": [ + { + "SQL": "select b from (select b+10 as b from t) as t1 order by b + 10 limit 10", + "Result": [ + "Group#0 Schema:[Column#13]", + " Projection_8 input:[Group#1], Column#13", + "Group#1 Schema:[Column#13,Column#14]", + " TopN_10 input:[Group#2], Column#14:asc, offset:0, count:10", + "Group#2 Schema:[Column#13,Column#14]", + " Projection_11 input:[Group#3], plus(test.t.b, 10)->Column#13, plus(plus(test.t.b, 10), 10)->Column#14", + "Group#3 Schema:[test.t.b]", + " DataSource_1 table:t" + ] + }, + { + "SQL": "select * from (select a+1 as c, a+b as d from t) as t1 order by c+d limit 10", + "Result": [ + "Group#0 Schema:[Column#13,Column#14]", + " Projection_8 input:[Group#1], Column#13, Column#14", + "Group#1 Schema:[Column#13,Column#14,Column#15]", + " TopN_10 input:[Group#2], Column#15:asc, offset:0, count:10", + "Group#2 Schema:[Column#13,Column#14,Column#15]", + " Projection_11 input:[Group#3], plus(test.t.a, 1)->Column#13, plus(test.t.a, test.t.b)->Column#14, plus(plus(test.t.a, 1), plus(test.t.a, test.t.b))->Column#15", + "Group#3 Schema:[test.t.a,test.t.b]", + " DataSource_1 table:t" + ] + }, + { + "SQL": "select a from (select a, b from t order by b limit 10) as t1", + "Result": [ + "Group#0 Schema:[test.t.a]", + " Projection_5 input:[Group#1], test.t.a", + "Group#1 Schema:[test.t.a,test.t.b]", + " TopN_6 input:[Group#2], test.t.b:asc, offset:0, count:10", + "Group#2 Schema:[test.t.a,test.t.b]", + " DataSource_1 table:t" + ] + } + ] + }, { "Name": "TestPushLimitDownTiKVSingleGather", "Cases": [ @@ -1604,51 +1646,62 @@ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Limit_3 input:[Group#1], offset:0, count:1", "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Projection_2 input:[Group#2], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", + " TiKVSingleGather_5 input:[Group#2], table:t", "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " DataSource_1 table:t" + " Limit_6 input:[Group#3], offset:0, count:1", + "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", + " TableScan_4 table:t, pk col:test.t.a" ] }, { "SQL": "select * from t as t1 left join (select * from t limit 2) as t2 on t1.a = t2.a;", "Result": [ "Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Projection_6 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", - "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Join_5 input:[Group#2,Group#3], left outer join, equal:[eq(test.t.a, test.t.a)]", - "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " DataSource_1 table:t1", + " Join_5 input:[Group#1,Group#2], left outer join, equal:[eq(test.t.a, test.t.a)]", + "Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", + " TiKVSingleGather_8 input:[Group#3], table:t1", "Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", + " TableScan_7 table:t1, pk col:test.t.a", + "Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", " Limit_4 input:[Group#4], offset:0, count:2", "Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " Projection_3 input:[Group#5], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date", + " TiKVSingleGather_10 input:[Group#5], table:t", "Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", - " DataSource_2 table:t" + " Limit_11 input:[Group#6], offset:0, count:2", + "Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]", + " TableScan_9 table:t, pk col:test.t.a" ] }, { "SQL": "select a, b from ((select a, b from t) union all(select c as a, d as b from t limit 3)) as t1 where a > 1", "Result": [ "Group#0 Schema:[Column#25,Column#26]", - " Projection_10 input:[Group#1], Column#25, Column#26", + " Selection_9 input:[Group#1], gt(Column#25, 1)", "Group#1 Schema:[Column#25,Column#26]", - " Selection_9 input:[Group#2], gt(Column#25, 1)", + " Union_6 input:[Group#2,Group#3]", "Group#2 Schema:[Column#25,Column#26]", - " Union_6 input:[Group#3,Group#4]", - "Group#3 Schema:[Column#25,Column#26]", - " Projection_7 input:[Group#5], test.t.a, test.t.b", + " Projection_7 input:[Group#4], test.t.a, test.t.b", + "Group#4 Schema:[test.t.a,test.t.b]", + " TiKVSingleGather_12 input:[Group#5], table:t", "Group#5 Schema:[test.t.a,test.t.b]", - " Projection_5 input:[Group#6], test.t.a, test.t.b", - "Group#6 Schema:[test.t.a,test.t.b]", - " DataSource_4 table:t", - "Group#4 Schema:[Column#25,Column#26]", - " Projection_8 input:[Group#7], test.t.c, test.t.d", - "Group#7 Schema:[test.t.c,test.t.d]", + " TableScan_11 table:t, pk col:test.t.a", + "Group#3 Schema:[Column#25,Column#26]", + " Projection_8 input:[Group#6], test.t.c, test.t.d", + "Group#6 Schema:[test.t.c,test.t.d]", + " Limit_3 input:[Group#7], offset:0, count:3", " Limit_3 input:[Group#8], offset:0, count:3", - "Group#8 Schema:[test.t.c,test.t.d]", - " Projection_2 input:[Group#9], test.t.c, test.t.d", + "Group#7 Schema:[test.t.c,test.t.d]", + " TiKVSingleGather_16 input:[Group#9], table:t, index:c_d_e", "Group#9 Schema:[test.t.c,test.t.d]", - " DataSource_1 table:t" + " Limit_18 input:[Group#10], offset:0, count:3", + "Group#10 Schema:[test.t.c,test.t.d]", + " IndexScan_15 table:t, index:c, d, e", + "Group#8 Schema:[test.t.c,test.t.d]", + " TiKVSingleGather_14 input:[Group#11], table:t", + "Group#11 Schema:[test.t.c,test.t.d]", + " Limit_17 input:[Group#12], offset:0, count:3", + "Group#12 Schema:[test.t.c,test.t.d]", + " TableScan_13 table:t" ] } ] diff --git a/planner/cascades/transformation_rules.go b/planner/cascades/transformation_rules.go index 21c28b2926446..f6bda6070112a 100644 --- a/planner/cascades/transformation_rules.go +++ b/planner/cascades/transformation_rules.go @@ -49,24 +49,29 @@ type Transformation interface { OnTransform(old *memo.ExprIter) (newExprs []*memo.GroupExpr, eraseOld bool, eraseAll bool, err error) } -var defaultTransformationMap = map[memo.Operand][]Transformation{ +// TransformationRuleBatch is a batch of transformation rules. +type TransformationRuleBatch map[memo.Operand][]Transformation + +// DefaultRuleBatches contain all the transformation rules. +// Each batch will be applied to the memo independently. +var DefaultRuleBatches = []TransformationRuleBatch{ + TiDBLayerOptimizationBatch, + TiKVLayerOptimizationBatch, + PostTransformationBatch, +} + +// TiDBLayerOptimizationBatch does the optimization in the TiDB layer. +var TiDBLayerOptimizationBatch = TransformationRuleBatch{ memo.OperandSelection: { - NewRulePushSelDownTableScan(), - NewRulePushSelDownTiKVSingleGather(), NewRulePushSelDownSort(), NewRulePushSelDownProjection(), NewRulePushSelDownAggregation(), NewRulePushSelDownJoin(), - NewRulePushSelDownIndexScan(), NewRulePushSelDownUnionAll(), NewRulePushSelDownWindow(), NewRuleMergeAdjacentSelection(), }, - memo.OperandDataSource: { - NewRuleEnumeratePaths(), - }, memo.OperandAggregation: { - NewRulePushAggDownGather(), NewRuleMergeAggregationProjection(), NewRuleEliminateSingleMaxMin(), NewRuleEliminateOuterJoinBelowAggregation(), @@ -79,7 +84,6 @@ var defaultTransformationMap = map[memo.Operand][]Transformation{ NewRulePushLimitDownOuterJoin(), NewRuleMergeAdjacentLimit(), NewRuleTransformLimitToTableDual(), - NewRulePushLimitDownTiKVSingleGather(), }, memo.OperandProjection: { NewRuleEliminateProjection(), @@ -89,11 +93,49 @@ var defaultTransformationMap = map[memo.Operand][]Transformation{ NewRulePushTopNDownProjection(), NewRulePushTopNDownOuterJoin(), NewRulePushTopNDownUnionAll(), - NewRulePushTopNDownTiKVSingleGather(), NewRuleMergeAdjacentTopN(), }, } +// TiKVLayerOptimizationBatch does the optimization related to TiKV layer. +// For example, rules about pushing down Operators like Selection, Limit, +// Aggregation into TiKV layer should be inside this batch. +var TiKVLayerOptimizationBatch = TransformationRuleBatch{ + memo.OperandDataSource: { + NewRuleEnumeratePaths(), + }, + memo.OperandSelection: { + NewRulePushSelDownTiKVSingleGather(), + NewRulePushSelDownTableScan(), + NewRulePushSelDownIndexScan(), + NewRuleMergeAdjacentSelection(), + }, + memo.OperandAggregation: { + NewRulePushAggDownGather(), + }, + memo.OperandLimit: { + NewRulePushLimitDownTiKVSingleGather(), + }, + memo.OperandTopN: { + NewRulePushTopNDownTiKVSingleGather(), + }, +} + +// PostTransformationBatch does the transformation which is related to +// the constraints of the execution engine of TiDB. +// For example, TopN/Sort only support `order by` columns in TiDB layer, +// as for scalar functions, we need to inject a Projection for them +// below the TopN/Sort. +var PostTransformationBatch = TransformationRuleBatch{ + memo.OperandProjection: { + NewRuleEliminateProjection(), + NewRuleMergeAdjacentProjection(), + }, + memo.OperandTopN: { + NewRuleInjectProjectionBelowTopN(), + }, +} + type baseRule struct { pattern *memo.Pattern } @@ -1952,3 +1994,100 @@ func (r *TransformAggregateCaseToSelection) isTwoOrThreeArgCase(expr expression. } return scalarFunc.FuncName.L == ast.Case && (len(scalarFunc.GetArgs()) == 2 || len(scalarFunc.GetArgs()) == 3) } + +// InjectProjectionBelowTopN injects two Projections below and upon TopN if TopN's ByItems +// contain ScalarFunctions. +type InjectProjectionBelowTopN struct { + baseRule +} + +// NewRuleInjectProjectionBelowTopN creates a new Transformation InjectProjectionBelowTopN. +// It will extract the ScalarFunctions of `ByItems` into a Projection and injects it below TopN. +// When a Projection is injected as the child of TopN, we need to add another Projection upon +// TopN to prune the extra Columns. +// The reason why we need this rule is that, TopNExecutor in TiDB does not support ScalarFunction +// as `ByItem`. So we have to use a Projection to calculate the ScalarFunctions in advance. +// The pattern of this rule is: a single TopN +func NewRuleInjectProjectionBelowTopN() Transformation { + rule := &InjectProjectionBelowTopN{} + rule.pattern = memo.BuildPattern( + memo.OperandTopN, + memo.EngineTiDBOnly, + ) + return rule +} + +// Match implements Transformation interface. +func (r *InjectProjectionBelowTopN) Match(expr *memo.ExprIter) bool { + topN := expr.GetExpr().ExprNode.(*plannercore.LogicalTopN) + for _, item := range topN.ByItems { + if _, ok := item.Expr.(*expression.ScalarFunction); ok { + return true + } + } + return false +} + +// OnTransform implements Transformation interface. +// It will convert `TopN -> X` to `Projection -> TopN -> Projection -> X`. +func (r *InjectProjectionBelowTopN) OnTransform(old *memo.ExprIter) (newExprs []*memo.GroupExpr, eraseOld bool, eraseAll bool, err error) { + topN := old.GetExpr().ExprNode.(*plannercore.LogicalTopN) + oldTopNSchema := old.GetExpr().Schema() + + // Construct top Projection. + topProjExprs := make([]expression.Expression, oldTopNSchema.Len()) + for i := range oldTopNSchema.Columns { + topProjExprs[i] = oldTopNSchema.Columns[i] + } + topProj := plannercore.LogicalProjection{ + Exprs: topProjExprs, + }.Init(topN.SCtx(), topN.SelectBlockOffset()) + topProj.SetSchema(oldTopNSchema) + + // Construct bottom Projection. + bottomProjExprs := make([]expression.Expression, 0, oldTopNSchema.Len()+len(topN.ByItems)) + bottomProjSchema := make([]*expression.Column, 0, oldTopNSchema.Len()+len(topN.ByItems)) + for _, col := range oldTopNSchema.Columns { + bottomProjExprs = append(bottomProjExprs, col) + bottomProjSchema = append(bottomProjSchema, col) + } + newByItems := make([]*plannercore.ByItems, 0, len(topN.ByItems)) + for _, item := range topN.ByItems { + itemExpr := item.Expr + if _, isScalarFunc := itemExpr.(*expression.ScalarFunction); !isScalarFunc { + newByItems = append(newByItems, item) + continue + } + bottomProjExprs = append(bottomProjExprs, itemExpr) + newCol := &expression.Column{ + UniqueID: topN.SCtx().GetSessionVars().AllocPlanColumnID(), + RetType: itemExpr.GetType(), + } + bottomProjSchema = append(bottomProjSchema, newCol) + newByItems = append(newByItems, &plannercore.ByItems{Expr: newCol, Desc: item.Desc}) + } + bottomProj := plannercore.LogicalProjection{ + Exprs: bottomProjExprs, + }.Init(topN.SCtx(), topN.SelectBlockOffset()) + newSchema := expression.NewSchema(bottomProjSchema...) + bottomProj.SetSchema(newSchema) + + newTopN := plannercore.LogicalTopN{ + ByItems: newByItems, + Offset: topN.Offset, + Count: topN.Count, + }.Init(topN.SCtx(), topN.SelectBlockOffset()) + + // Construct GroupExpr, Group (TopProj -> TopN -> BottomProj -> Child) + bottomProjGroupExpr := memo.NewGroupExpr(bottomProj) + bottomProjGroupExpr.SetChildren(old.GetExpr().Children[0]) + bottomProjGroup := memo.NewGroupWithSchema(bottomProjGroupExpr, newSchema) + + topNGroupExpr := memo.NewGroupExpr(newTopN) + topNGroupExpr.SetChildren(bottomProjGroup) + topNGroup := memo.NewGroupWithSchema(topNGroupExpr, newSchema) + + topProjGroupExpr := memo.NewGroupExpr(topProj) + topProjGroupExpr.SetChildren(topNGroup) + return []*memo.GroupExpr{topProjGroupExpr}, true, false, nil +} diff --git a/planner/cascades/transformation_rules_test.go b/planner/cascades/transformation_rules_test.go index 942795b10f1ce..077ffbaf64dfd 100644 --- a/planner/cascades/transformation_rules_test.go +++ b/planner/cascades/transformation_rules_test.go @@ -76,7 +76,7 @@ func testGroupToString(input []string, output []struct { } func (s *testTransformationRuleSuite) TestAggPushDownGather(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ memo.OperandAggregation: { NewRulePushAggDownGather(), }, @@ -85,7 +85,7 @@ func (s *testTransformationRuleSuite) TestAggPushDownGather(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -116,25 +116,31 @@ func (s *testTransformationRuleSuite) TestAggPushDownGather(c *C) { } func (s *testTransformationRuleSuite) TestPredicatePushDown(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandSelection: { - NewRulePushSelDownTableScan(), - NewRulePushSelDownTiKVSingleGather(), - NewRulePushSelDownSort(), - NewRulePushSelDownProjection(), - NewRulePushSelDownAggregation(), - NewRulePushSelDownJoin(), - NewRulePushSelDownIndexScan(), - NewRulePushSelDownUnionAll(), - NewRulePushSelDownWindow(), - NewRuleMergeAdjacentSelection(), + s.optimizer.ResetTransformationRules( + TransformationRuleBatch{ // TiDB layer + memo.OperandSelection: { + NewRulePushSelDownSort(), + NewRulePushSelDownProjection(), + NewRulePushSelDownAggregation(), + NewRulePushSelDownJoin(), + NewRulePushSelDownUnionAll(), + NewRulePushSelDownWindow(), + NewRuleMergeAdjacentSelection(), + }, }, - memo.OperandDataSource: { - NewRuleEnumeratePaths(), + TransformationRuleBatch{ // TiKV layer + memo.OperandSelection: { + NewRulePushSelDownTableScan(), + NewRulePushSelDownTiKVSingleGather(), + NewRulePushSelDownIndexScan(), + }, + memo.OperandDataSource: { + NewRuleEnumeratePaths(), + }, }, - }) + ) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -146,25 +152,33 @@ func (s *testTransformationRuleSuite) TestPredicatePushDown(c *C) { } func (s *testTransformationRuleSuite) TestTopNRules(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandLimit: { - NewRuleTransformLimitToTopN(), - NewRulePushLimitDownProjection(), - NewRulePushLimitDownUnionAll(), - NewRulePushLimitDownOuterJoin(), - NewRuleMergeAdjacentLimit(), - NewRulePushLimitDownTiKVSingleGather(), + s.optimizer.ResetTransformationRules( + TransformationRuleBatch{ // TiDB layer + memo.OperandLimit: { + NewRuleTransformLimitToTopN(), + NewRulePushLimitDownProjection(), + NewRulePushLimitDownUnionAll(), + NewRulePushLimitDownOuterJoin(), + NewRuleMergeAdjacentLimit(), + }, + memo.OperandTopN: { + NewRulePushTopNDownProjection(), + NewRulePushTopNDownOuterJoin(), + NewRulePushTopNDownUnionAll(), + }, }, - memo.OperandDataSource: { - NewRuleEnumeratePaths(), - }, - memo.OperandTopN: { - NewRulePushTopNDownProjection(), - NewRulePushTopNDownOuterJoin(), - NewRulePushTopNDownUnionAll(), - NewRulePushTopNDownTiKVSingleGather(), + TransformationRuleBatch{ // TiKV layer + memo.OperandLimit: { + NewRulePushLimitDownTiKVSingleGather(), + }, + memo.OperandTopN: { + NewRulePushTopNDownTiKVSingleGather(), + }, + memo.OperandDataSource: { + NewRuleEnumeratePaths(), + }, }, - }) + ) var input []string var output []struct { SQL string @@ -175,14 +189,14 @@ func (s *testTransformationRuleSuite) TestTopNRules(c *C) { } func (s *testTransformationRuleSuite) TestProjectionElimination(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ memo.OperandProjection: { NewRuleEliminateProjection(), NewRuleMergeAdjacentProjection(), }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -200,7 +214,7 @@ func (s *testTransformationRuleSuite) TestEliminateMaxMin(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -212,13 +226,13 @@ func (s *testTransformationRuleSuite) TestEliminateMaxMin(c *C) { } func (s *testTransformationRuleSuite) TestMergeAggregationProjection(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ memo.OperandAggregation: { NewRuleMergeAggregationProjection(), }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -243,7 +257,7 @@ func (s *testTransformationRuleSuite) TestMergeAdjacentTopN(c *C) { }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -255,14 +269,14 @@ func (s *testTransformationRuleSuite) TestMergeAdjacentTopN(c *C) { } func (s *testTransformationRuleSuite) TestMergeAdjacentLimit(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ memo.OperandLimit: { NewRulePushLimitDownProjection(), NewRuleMergeAdjacentLimit(), }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -274,13 +288,31 @@ func (s *testTransformationRuleSuite) TestMergeAdjacentLimit(c *C) { } func (s *testTransformationRuleSuite) TestTransformLimitToTableDual(c *C) { - s.optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ memo.OperandLimit: { NewRuleTransformLimitToTableDual(), }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) + }() + var input []string + var output []struct { + SQL string + Result []string + } + s.testData.GetTestCases(c, &input, &output) + testGroupToString(input, output, s, c) +} + +func (s *testTransformationRuleSuite) TestPostTransformationRules(c *C) { + s.optimizer.ResetTransformationRules(TransformationRuleBatch{ + memo.OperandLimit: { + NewRuleTransformLimitToTopN(), + }, + }, PostTransformationBatch) + defer func() { + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -296,9 +328,15 @@ func (s *testTransformationRuleSuite) TestPushLimitDownTiKVSingleGather(c *C) { memo.OperandLimit: { NewRulePushLimitDownTiKVSingleGather(), }, + memo.OperandProjection: { + NewRuleEliminateProjection(), + }, + memo.OperandDataSource: { + NewRuleEnumeratePaths(), + }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -316,7 +354,7 @@ func (s *testTransformationRuleSuite) TestEliminateOuterJoinBelowAggregation(c * }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { @@ -334,7 +372,7 @@ func (s *testTransformationRuleSuite) TestTransformAggregateCaseToSelection(c *C }, }) defer func() { - s.optimizer.ResetTransformationRules(defaultTransformationMap) + s.optimizer.ResetTransformationRules(DefaultRuleBatches...) }() var input []string var output []struct { diff --git a/planner/memo/group.go b/planner/memo/group.go index 00fd0ac7f634f..2d9148701f0b6 100644 --- a/planner/memo/group.go +++ b/planner/memo/group.go @@ -71,6 +71,25 @@ func (e EngineType) String() string { return "UnknownEngineType" } +// ExploreMark is uses to mark whether a Group or GroupExpr has +// been fully explored by a transformation rule batch. +type ExploreMark int + +// SetExplored sets the roundth bit. +func (m *ExploreMark) SetExplored(round int) { + *m |= 1 << round +} + +// SetUnexplored unsets the roundth bit. +func (m *ExploreMark) SetUnexplored(round int) { + *m &= ^(1 << round) +} + +// Explored returns whether the roundth bit has been set. +func (m *ExploreMark) Explored(round int) bool { + return *m&(1<