github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/optimizer/new_plan_test.go (about) 1 // Copyright 2016 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package optimizer 15 16 import ( 17 "testing" 18 19 . "github.com/insionng/yougam/libraries/pingcap/check" 20 "github.com/insionng/yougam/libraries/pingcap/tidb/ast" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/infoschema" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 24 "github.com/insionng/yougam/libraries/pingcap/tidb/optimizer/plan" 25 "github.com/insionng/yougam/libraries/pingcap/tidb/parser" 26 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 27 ) 28 29 var _ = Suite(&testPlanSuite{}) 30 31 func TestT(t *testing.T) { 32 TestingT(t) 33 } 34 35 type testPlanSuite struct{} 36 37 func newMockResolve(node ast.Node) error { 38 indices := []*model.IndexInfo{ 39 { 40 Name: model.NewCIStr("b"), 41 Columns: []*model.IndexColumn{ 42 { 43 Name: model.NewCIStr("b"), 44 }, 45 }, 46 }, 47 { 48 Name: model.NewCIStr("c_d_e"), 49 Columns: []*model.IndexColumn{ 50 { 51 Name: model.NewCIStr("c"), 52 }, 53 { 54 Name: model.NewCIStr("d"), 55 }, 56 { 57 Name: model.NewCIStr("e"), 58 }, 59 }, 60 }, 61 } 62 pkColumn := &model.ColumnInfo{ 63 State: model.StatePublic, 64 Name: model.NewCIStr("a"), 65 } 66 col1 := &model.ColumnInfo{ 67 State: model.StatePublic, 68 Name: model.NewCIStr("d"), 69 } 70 pkColumn.Flag = mysql.PriKeyFlag 71 table := &model.TableInfo{ 72 Columns: []*model.ColumnInfo{pkColumn, col1}, 73 Indices: indices, 74 Name: model.NewCIStr("t"), 75 PKIsHandle: true, 76 } 77 is := infoschema.MockInfoSchema([]*model.TableInfo{table}) 78 return MockResolveName(node, is, "test") 79 } 80 81 func (s *testPlanSuite) TestPredicatePushDown(c *C) { 82 plan.UseNewPlanner = true 83 defer testleak.AfterTest(c)() 84 cases := []struct { 85 sql string 86 first string 87 best string 88 }{ 89 { 90 sql: "select a from (select a from t where d = 0) k where k.a = 5", 91 first: "Table(t)->Filter->Fields->Filter->Fields", 92 best: "Range(t)->Fields->Fields", 93 }, 94 { 95 sql: "select a from (select 1+2 as a from t where d = 0) k where k.a = 5", 96 first: "Table(t)->Filter->Fields->Filter->Fields", 97 best: "Table(t)->Fields->Filter->Fields", 98 }, 99 { 100 sql: "select a from (select d as a from t where d = 0) k where k.a = 5", 101 first: "Table(t)->Filter->Fields->Filter->Fields", 102 best: "Table(t)->Fields->Fields", 103 }, 104 { 105 sql: "select * from t ta join t tb on ta.d = tb.d and ta.d > 1 where tb.a = 0", 106 first: "Join{Table(t)->Table(t)}->Filter->Fields", 107 best: "Join{Table(t)->Range(t)}->Fields", 108 }, 109 { 110 sql: "select * from t ta left outer join t tb on ta.d = tb.d and ta.d > 1 where tb.a = 0", 111 first: "Join{Table(t)->Table(t)}->Filter->Fields", 112 best: "Join{Table(t)->Table(t)}->Filter->Fields", 113 }, 114 { 115 sql: "select * from t ta right outer join t tb on ta.d = tb.d and ta.a > 1 where tb.a = 0", 116 first: "Join{Table(t)->Table(t)}->Filter->Fields", 117 best: "Join{Range(t)->Range(t)}->Fields", 118 }, 119 } 120 for _, ca := range cases { 121 comment := Commentf("for %s", ca.sql) 122 stmt, err := parser.ParseOneStmt(ca.sql, "", "") 123 c.Assert(err, IsNil, comment) 124 ast.SetFlag(stmt) 125 126 err = newMockResolve(stmt) 127 c.Assert(err, IsNil) 128 129 p, err := plan.BuildPlan(stmt, nil) 130 c.Assert(err, IsNil) 131 c.Assert(plan.ToString(p), Equals, ca.first, Commentf("for %s", ca.sql)) 132 133 _, err = plan.PredicatePushDown(p, []ast.ExprNode{}) 134 c.Assert(err, IsNil) 135 err = plan.Refine(p) 136 c.Assert(err, IsNil) 137 c.Assert(plan.ToString(p), Equals, ca.best, Commentf("for %s", ca.sql)) 138 } 139 plan.UseNewPlanner = false 140 }