diff --git a/planner/cascades/group_test.go b/planner/cascades/group_test.go index 02ccee32697ae..8a3e4c025b465 100644 --- a/planner/cascades/group_test.go +++ b/planner/cascades/group_test.go @@ -17,9 +17,11 @@ import ( "testing" . "github.com/pingcap/check" + "github.com/pingcap/parser" + "github.com/pingcap/parser/model" + "github.com/pingcap/tidb/infoschema" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/testleak" ) @@ -31,12 +33,16 @@ func TestT(t *testing.T) { var _ = Suite(&testCascadesSuite{}) type testCascadesSuite struct { + *parser.Parser + is infoschema.InfoSchema sctx sessionctx.Context } func (s *testCascadesSuite) SetUpSuite(c *C) { testleak.BeforeTest() - s.sctx = mock.NewContext() + s.is = infoschema.MockInfoSchema([]*model.TableInfo{plannercore.MockTable()}) + s.sctx = plannercore.MockContext() + s.Parser = parser.New() } func (s *testCascadesSuite) TearDownSuite(c *C) { diff --git a/planner/core/cache_test.go b/planner/core/cache_test.go index 2d3ab7ea76010..bb1a3a86a5880 100644 --- a/planner/core/cache_test.go +++ b/planner/core/cache_test.go @@ -28,7 +28,7 @@ type testCacheSuite struct { } func (s *testCacheSuite) SetUpSuite(c *C) { - ctx := mockContext() + ctx := MockContext() ctx.GetSessionVars().SnapshotTS = 0 ctx.GetSessionVars().SQLMode = mysql.ModeNone ctx.GetSessionVars().TimeZone = time.UTC diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index ce66549e8658f..10b5a25467798 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -24,12 +24,9 @@ import ( "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" - "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/testleak" ) @@ -49,248 +46,10 @@ type testPlanSuite struct { func (s *testPlanSuite) SetUpSuite(c *C) { s.is = infoschema.MockInfoSchema([]*model.TableInfo{MockTable()}) - s.ctx = mockContext() + s.ctx = MockContext() s.Parser = parser.New() } -func newLongType() types.FieldType { - return *(types.NewFieldType(mysql.TypeLong)) -} - -func newStringType() types.FieldType { - ft := types.NewFieldType(mysql.TypeVarchar) - ft.Charset, ft.Collate = types.DefaultCharsetForType(mysql.TypeVarchar) - return *ft -} - -func MockTable() *model.TableInfo { - // column: a, b, c, d, e, c_str, d_str, e_str, f, g - // PK: a - // indeices: c_d_e, e, f, g, f_g, c_d_e_str, c_d_e_str_prefix - indices := []*model.IndexInfo{ - { - Name: model.NewCIStr("c_d_e"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("c"), - Length: types.UnspecifiedLength, - Offset: 2, - }, - { - Name: model.NewCIStr("d"), - Length: types.UnspecifiedLength, - Offset: 3, - }, - { - Name: model.NewCIStr("e"), - Length: types.UnspecifiedLength, - Offset: 4, - }, - }, - State: model.StatePublic, - Unique: true, - }, - { - Name: model.NewCIStr("e"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("e"), - Length: types.UnspecifiedLength, - Offset: 4, - }, - }, - State: model.StateWriteOnly, - Unique: true, - }, - { - Name: model.NewCIStr("f"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("f"), - Length: types.UnspecifiedLength, - Offset: 8, - }, - }, - State: model.StatePublic, - Unique: true, - }, - { - Name: model.NewCIStr("g"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("g"), - Length: types.UnspecifiedLength, - Offset: 9, - }, - }, - State: model.StatePublic, - }, - { - Name: model.NewCIStr("f_g"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("f"), - Length: types.UnspecifiedLength, - Offset: 8, - }, - { - Name: model.NewCIStr("g"), - Length: types.UnspecifiedLength, - Offset: 9, - }, - }, - State: model.StatePublic, - Unique: true, - }, - { - Name: model.NewCIStr("c_d_e_str"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("c_str"), - Length: types.UnspecifiedLength, - Offset: 5, - }, - { - Name: model.NewCIStr("d_str"), - Length: types.UnspecifiedLength, - Offset: 6, - }, - { - Name: model.NewCIStr("e_str"), - Length: types.UnspecifiedLength, - Offset: 7, - }, - }, - State: model.StatePublic, - }, - { - Name: model.NewCIStr("e_d_c_str_prefix"), - Columns: []*model.IndexColumn{ - { - Name: model.NewCIStr("e_str"), - Length: types.UnspecifiedLength, - Offset: 7, - }, - { - Name: model.NewCIStr("d_str"), - Length: types.UnspecifiedLength, - Offset: 6, - }, - { - Name: model.NewCIStr("c_str"), - Length: 10, - Offset: 5, - }, - }, - State: model.StatePublic, - }, - } - pkColumn := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 0, - Name: model.NewCIStr("a"), - FieldType: newLongType(), - ID: 1, - } - col0 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 1, - Name: model.NewCIStr("b"), - FieldType: newLongType(), - ID: 2, - } - col1 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 2, - Name: model.NewCIStr("c"), - FieldType: newLongType(), - ID: 3, - } - col2 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 3, - Name: model.NewCIStr("d"), - FieldType: newLongType(), - ID: 4, - } - col3 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 4, - Name: model.NewCIStr("e"), - FieldType: newLongType(), - ID: 5, - } - colStr1 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 5, - Name: model.NewCIStr("c_str"), - FieldType: newStringType(), - ID: 6, - } - colStr2 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 6, - Name: model.NewCIStr("d_str"), - FieldType: newStringType(), - ID: 7, - } - colStr3 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 7, - Name: model.NewCIStr("e_str"), - FieldType: newStringType(), - ID: 8, - } - col4 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 8, - Name: model.NewCIStr("f"), - FieldType: newLongType(), - ID: 9, - } - col5 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 9, - Name: model.NewCIStr("g"), - FieldType: newLongType(), - ID: 10, - } - col6 := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 10, - Name: model.NewCIStr("h"), - FieldType: newLongType(), - ID: 10, - } - pkColumn.Flag = mysql.PriKeyFlag | mysql.NotNullFlag - // Column 'b', 'c', 'd', 'f', 'g' is not null. - col0.Flag = mysql.NotNullFlag - col1.Flag = mysql.NotNullFlag - col2.Flag = mysql.NotNullFlag - col4.Flag = mysql.NotNullFlag - col5.Flag = mysql.NotNullFlag - col6.Flag = mysql.NoDefaultValueFlag - table := &model.TableInfo{ - Columns: []*model.ColumnInfo{pkColumn, col0, col1, col2, col3, colStr1, colStr2, colStr3, col4, col5, col6}, - Indices: indices, - Name: model.NewCIStr("t"), - PKIsHandle: true, - } - return table -} - -func mockContext() sessionctx.Context { - ctx := mock.NewContext() - ctx.Store = &mock.Store{ - Client: &mock.Client{}, - } - ctx.GetSessionVars().CurrentDB = "test" - do := &domain.Domain{} - do.CreateStatsHandle(ctx) - domain.BindDomain(ctx, do) - return ctx -} - func (s *testPlanSuite) TestPredicatePushDown(c *C) { defer testleak.AfterTest(c)() tests := []struct { @@ -1254,7 +1013,7 @@ func (s *testPlanSuite) TestColumnPruning(c *C) { } func (s *testPlanSuite) TestAllocID(c *C) { - ctx := mockContext() + ctx := MockContext() pA := DataSource{}.Init(ctx) pB := DataSource{}.Init(ctx) c.Assert(pA.id+1, Equals, pB.id) @@ -1726,7 +1485,7 @@ func (s *testPlanSuite) TestVisitInfo(c *C) { Preprocess(s.ctx, stmt, s.is, false) builder := &PlanBuilder{ colMapper: make(map[*ast.ColumnNameExpr]int), - ctx: mockContext(), + ctx: MockContext(), is: s.is, } builder.ctx.GetSessionVars().HashJoinConcurrency = 1 @@ -1839,7 +1598,7 @@ func (s *testPlanSuite) TestUnion(c *C) { c.Assert(err, IsNil, comment) Preprocess(s.ctx, stmt, s.is, false) builder := &PlanBuilder{ - ctx: mockContext(), + ctx: MockContext(), is: s.is, colMapper: make(map[*ast.ColumnNameExpr]int), } @@ -1971,7 +1730,7 @@ func (s *testPlanSuite) TestTopNPushDown(c *C) { c.Assert(err, IsNil, comment) Preprocess(s.ctx, stmt, s.is, false) builder := &PlanBuilder{ - ctx: mockContext(), + ctx: MockContext(), is: s.is, colMapper: make(map[*ast.ColumnNameExpr]int), } @@ -2082,7 +1841,7 @@ func (s *testPlanSuite) TestOuterJoinEliminator(c *C) { c.Assert(err, IsNil, comment) Preprocess(s.ctx, stmt, s.is, false) builder := &PlanBuilder{ - ctx: mockContext(), + ctx: MockContext(), is: s.is, colMapper: make(map[*ast.ColumnNameExpr]int), } diff --git a/planner/core/logical_plans_test.go b/planner/core/logical_plans_test.go index 3b162e7026c7f..f36fcd73b6795 100644 --- a/planner/core/logical_plans_test.go +++ b/planner/core/logical_plans_test.go @@ -35,7 +35,7 @@ type testUnitTestSuit struct { } func (s *testUnitTestSuit) SetUpSuite(c *C) { - s.ctx = mockContext() + s.ctx = MockContext() } func (s *testUnitTestSuit) newTypeWithFlen(typeByte byte, flen int) *types.FieldType { diff --git a/planner/core/mock.go b/planner/core/mock.go new file mode 100644 index 0000000000000..316a4c389bb92 --- /dev/null +++ b/planner/core/mock.go @@ -0,0 +1,263 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "github.com/pingcap/parser/model" + "github.com/pingcap/parser/mysql" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/mock" +) + +func newLongType() types.FieldType { + return *(types.NewFieldType(mysql.TypeLong)) +} + +func newStringType() types.FieldType { + ft := types.NewFieldType(mysql.TypeVarchar) + ft.Charset, ft.Collate = types.DefaultCharsetForType(mysql.TypeVarchar) + return *ft +} + +// MockTable is only used for plan related tests. +func MockTable() *model.TableInfo { + // column: a, b, c, d, e, c_str, d_str, e_str, f, g + // PK: a + // indeices: c_d_e, e, f, g, f_g, c_d_e_str, c_d_e_str_prefix + indices := []*model.IndexInfo{ + { + Name: model.NewCIStr("c_d_e"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("c"), + Length: types.UnspecifiedLength, + Offset: 2, + }, + { + Name: model.NewCIStr("d"), + Length: types.UnspecifiedLength, + Offset: 3, + }, + { + Name: model.NewCIStr("e"), + Length: types.UnspecifiedLength, + Offset: 4, + }, + }, + State: model.StatePublic, + Unique: true, + }, + { + Name: model.NewCIStr("e"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("e"), + Length: types.UnspecifiedLength, + Offset: 4, + }, + }, + State: model.StateWriteOnly, + Unique: true, + }, + { + Name: model.NewCIStr("f"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("f"), + Length: types.UnspecifiedLength, + Offset: 8, + }, + }, + State: model.StatePublic, + Unique: true, + }, + { + Name: model.NewCIStr("g"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("g"), + Length: types.UnspecifiedLength, + Offset: 9, + }, + }, + State: model.StatePublic, + }, + { + Name: model.NewCIStr("f_g"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("f"), + Length: types.UnspecifiedLength, + Offset: 8, + }, + { + Name: model.NewCIStr("g"), + Length: types.UnspecifiedLength, + Offset: 9, + }, + }, + State: model.StatePublic, + Unique: true, + }, + { + Name: model.NewCIStr("c_d_e_str"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("c_str"), + Length: types.UnspecifiedLength, + Offset: 5, + }, + { + Name: model.NewCIStr("d_str"), + Length: types.UnspecifiedLength, + Offset: 6, + }, + { + Name: model.NewCIStr("e_str"), + Length: types.UnspecifiedLength, + Offset: 7, + }, + }, + State: model.StatePublic, + }, + { + Name: model.NewCIStr("e_d_c_str_prefix"), + Columns: []*model.IndexColumn{ + { + Name: model.NewCIStr("e_str"), + Length: types.UnspecifiedLength, + Offset: 7, + }, + { + Name: model.NewCIStr("d_str"), + Length: types.UnspecifiedLength, + Offset: 6, + }, + { + Name: model.NewCIStr("c_str"), + Length: 10, + Offset: 5, + }, + }, + State: model.StatePublic, + }, + } + pkColumn := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 0, + Name: model.NewCIStr("a"), + FieldType: newLongType(), + ID: 1, + } + col0 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 1, + Name: model.NewCIStr("b"), + FieldType: newLongType(), + ID: 2, + } + col1 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 2, + Name: model.NewCIStr("c"), + FieldType: newLongType(), + ID: 3, + } + col2 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 3, + Name: model.NewCIStr("d"), + FieldType: newLongType(), + ID: 4, + } + col3 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 4, + Name: model.NewCIStr("e"), + FieldType: newLongType(), + ID: 5, + } + colStr1 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 5, + Name: model.NewCIStr("c_str"), + FieldType: newStringType(), + ID: 6, + } + colStr2 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 6, + Name: model.NewCIStr("d_str"), + FieldType: newStringType(), + ID: 7, + } + colStr3 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 7, + Name: model.NewCIStr("e_str"), + FieldType: newStringType(), + ID: 8, + } + col4 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 8, + Name: model.NewCIStr("f"), + FieldType: newLongType(), + ID: 9, + } + col5 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 9, + Name: model.NewCIStr("g"), + FieldType: newLongType(), + ID: 10, + } + col6 := &model.ColumnInfo{ + State: model.StatePublic, + Offset: 10, + Name: model.NewCIStr("h"), + FieldType: newLongType(), + ID: 10, + } + pkColumn.Flag = mysql.PriKeyFlag | mysql.NotNullFlag + // Column 'b', 'c', 'd', 'f', 'g' is not null. + col0.Flag = mysql.NotNullFlag + col1.Flag = mysql.NotNullFlag + col2.Flag = mysql.NotNullFlag + col4.Flag = mysql.NotNullFlag + col5.Flag = mysql.NotNullFlag + col6.Flag = mysql.NoDefaultValueFlag + table := &model.TableInfo{ + Columns: []*model.ColumnInfo{pkColumn, col0, col1, col2, col3, colStr1, colStr2, colStr3, col4, col5, col6}, + Indices: indices, + Name: model.NewCIStr("t"), + PKIsHandle: true, + } + return table +} + +// MockContext is only used for plan related tests. +func MockContext() sessionctx.Context { + ctx := mock.NewContext() + ctx.Store = &mock.Store{ + Client: &mock.Client{}, + } + ctx.GetSessionVars().CurrentDB = "test" + do := &domain.Domain{} + do.CreateStatsHandle(ctx) + domain.BindDomain(ctx, do) + return ctx +} diff --git a/planner/core/rule_join_reorder_dp_test.go b/planner/core/rule_join_reorder_dp_test.go index dfaebc44a734d..12da2ddae6260 100644 --- a/planner/core/rule_join_reorder_dp_test.go +++ b/planner/core/rule_join_reorder_dp_test.go @@ -34,7 +34,7 @@ type testJoinReorderDPSuite struct { } func (s *testJoinReorderDPSuite) SetUpTest(c *C) { - s.ctx = mockContext() + s.ctx = MockContext() s.ctx.GetSessionVars().PlanID = -1 }