Skip to content

Commit

Permalink
plan: new plan support union scan. (#3098)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanfei1991 authored and XuHuaiyu committed Apr 26, 2017
1 parent 9e1022a commit 31bc108
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 95 deletions.
208 changes: 138 additions & 70 deletions plan/dag_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package plan
package plan_test

import (
. "github.com/pingcap/check"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/plan"
"github.com/pingcap/tidb/util/testleak"
)

var _ = Suite(&testPlanSuite{})

type testPlanSuite struct {
*parser.Parser
}

func (s *testPlanSuite) SetUpSuite(c *C) {
s.Parser = parser.New()
}

func (s *testPlanSuite) TestDAGPlanBuilderSimpleCase(c *C) {
UseDAGPlanBuilder = true
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
UseDAGPlanBuilder = false
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
Expand Down Expand Up @@ -140,27 +158,27 @@ func (s *testPlanSuite) TestDAGPlanBuilderSimpleCase(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
err = se.NewTxn()
c.Assert(err, IsNil)

builder := &planBuilder{
allocator: new(idAllocator),
ctx: mockContext(),
colMapper: make(map[*ast.ColumnNameExpr]int),
is: is,
}
p := builder.build(stmt)
c.Assert(builder.err, IsNil)
p, err = doOptimize(builder.optFlag, p.(LogicalPlan), builder.ctx, builder.allocator)
is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}

func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
UseDAGPlanBuilder = true
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
UseDAGPlanBuilder = false
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
Expand Down Expand Up @@ -197,27 +215,24 @@ func (s *testPlanSuite) TestDAGPlanBuilderJoin(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
allocator: new(idAllocator),
ctx: mockContext(),
colMapper: make(map[*ast.ColumnNameExpr]int),
is: is,
}
p := builder.build(stmt)
c.Assert(builder.err, IsNil)
p, err = doOptimize(builder.optFlag, p.(LogicalPlan), builder.ctx, builder.allocator)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}

func (s *testPlanSuite) TestDAGPlanBuilderBasePhysicalPlan(c *C) {
UseDAGPlanBuilder = true
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
UseDAGPlanBuilder = false
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
Expand Down Expand Up @@ -281,27 +296,24 @@ func (s *testPlanSuite) TestDAGPlanBuilderBasePhysicalPlan(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
allocator: new(idAllocator),
ctx: mockContext(),
colMapper: make(map[*ast.ColumnNameExpr]int),
is: is,
}
p := builder.build(stmt)
c.Assert(builder.err, IsNil)
p, err = doOptimize(builder.optFlag, p.(LogicalPlan), builder.ctx, builder.allocator)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}

func (s *testPlanSuite) TestDAGPlanBuilderUnion(c *C) {
UseDAGPlanBuilder = true
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
UseDAGPlanBuilder = false
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
Expand Down Expand Up @@ -334,27 +346,92 @@ func (s *testPlanSuite) TestDAGPlanBuilderUnion(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}

builder := &planBuilder{
allocator: new(idAllocator),
ctx: mockContext(),
colMapper: make(map[*ast.ColumnNameExpr]int),
is: is,
}
p := builder.build(stmt)
c.Assert(builder.err, IsNil)
p, err = doOptimize(builder.optFlag, p.(LogicalPlan), builder.ctx, builder.allocator)
func (s *testPlanSuite) TestDAGPlanBuilderUnionScan(c *C) {
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
sql string
best string
}{
// Read table.
{
sql: "select * from t",
best: "TableReader(Table(t))->UnionScan([])",
},
{
sql: "select * from t where b = 1",
best: "TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->UnionScan([eq(test.t.b, 1)])",
},
{
sql: "select * from t where a = 1",
best: "TableReader(Table(t))->UnionScan([eq(test.t.a, 1)])",
},
{
sql: "select * from t where a = 1 order by a",
best: "TableReader(Table(t))->UnionScan([eq(test.t.a, 1)])",
},
{
sql: "select * from t where a = 1 order by b",
best: "TableReader(Table(t))->UnionScan([eq(test.t.a, 1)])->Sort",
},
{
sql: "select * from t where a = 1 limit 1",
best: "TableReader(Table(t))->UnionScan([eq(test.t.a, 1)])->Limit",
},
{
sql: "select * from t where c = 1",
best: "IndexLookUp(Index(t.c_d_e)[[1,1]], Table(t))->UnionScan([eq(test.t.c, 1)])",
},
{
sql: "select c from t where c = 1",
best: "IndexReader(Index(t.c_d_e)[[1,1]])->UnionScan([eq(test.t.c, 1)])",
},
}
for _, tt := range tests {
comment := Commentf("for %s", tt.sql)
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)

err = se.NewTxn()
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
// Make txn not read only.
se.Txn().Set(nil, nil)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}

func (s *testPlanSuite) TestDAGPlanBuilderAgg(c *C) {
UseDAGPlanBuilder = true
store, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
defer store.Close()
se, err := tidb.CreateSession(store)
c.Assert(err, IsNil)

plan.UseDAGPlanBuilder = true
defer func() {
UseDAGPlanBuilder = false
plan.UseDAGPlanBuilder = false
testleak.AfterTest(c)()
}()
tests := []struct {
Expand Down Expand Up @@ -392,19 +469,10 @@ func (s *testPlanSuite) TestDAGPlanBuilderAgg(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := plan.MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
allocator: new(idAllocator),
ctx: mockContext(),
colMapper: make(map[*ast.ColumnNameExpr]int),
is: is,
}
p := builder.build(stmt)
c.Assert(builder.err, IsNil)
p, err = doOptimize(builder.optFlag, p.(LogicalPlan), builder.ctx, builder.allocator)
p, err := plan.Optimize(se, stmt, is)
c.Assert(err, IsNil)
c.Assert(ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
c.Assert(plan.ToString(p), Equals, tt.best, Commentf("for %s", tt.sql))
}
}
24 changes: 12 additions & 12 deletions plan/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func newStringType() types.FieldType {
return *ft
}

func mockResolve(node ast.Node) (infoschema.InfoSchema, error) {
func MockResolve(node ast.Node) (infoschema.InfoSchema, error) {
indices := []*model.IndexInfo{
{
Name: model.NewCIStr("c_d_e"),
Expand Down Expand Up @@ -535,7 +535,7 @@ func (s *testPlanSuite) TestPredicatePushDown(c *C) {
stmt, err := s.ParseOneStmt(ca.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil, comment)

builder := &planBuilder{
Expand Down Expand Up @@ -657,7 +657,7 @@ func (s *testPlanSuite) TestPlanBuilder(c *C) {
stmt, err := s.ParseOneStmt(ca.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -711,7 +711,7 @@ func (s *testPlanSuite) TestJoinReOrder(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -817,7 +817,7 @@ func (s *testPlanSuite) TestAggPushDown(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -1034,7 +1034,7 @@ func (s *testPlanSuite) TestRefine(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -1172,7 +1172,7 @@ func (s *testPlanSuite) TestColumnPruning(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil, comment)

builder := &planBuilder{
Expand Down Expand Up @@ -1303,7 +1303,7 @@ func (s *testPlanSuite) TestValidate(c *C) {
comment := Commentf("for %s", sql)
stmt, err := s.ParseOneStmt(sql, "", "")
c.Assert(err, IsNil, comment)
is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)
builder := &planBuilder{
allocator: new(idAllocator),
Expand Down Expand Up @@ -1407,7 +1407,7 @@ func (s *testPlanSuite) TestUniqueKeyInfo(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -1456,7 +1456,7 @@ func (s *testPlanSuite) TestAggPrune(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -1620,7 +1620,7 @@ func (s *testPlanSuite) TestVisitInfo(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down Expand Up @@ -1793,7 +1793,7 @@ func (s *testPlanSuite) TestTopNPushDown(c *C) {
stmt, err := s.ParseOneStmt(tt.sql, "", "")
c.Assert(err, IsNil, comment)

is, err := mockResolve(stmt)
is, err := MockResolve(stmt)
c.Assert(err, IsNil)

builder := &planBuilder{
Expand Down
Loading

0 comments on commit 31bc108

Please sign in to comment.