func (t *testUnionSuit) TestUnion(c *C) { tblPlan := &testTablePlan{t.data, []string{"id", "name"}, 0} tblPlan2 := &testTablePlan{t.data2, []string{"id", "name"}, 0} cols := []*column.Col{ { ColumnInfo: model.ColumnInfo{ ID: 0, Name: model.NewCIStr("id"), Offset: 0, DefaultValue: 0, FieldType: *types.NewFieldType(mysql.TypeLonglong), }, }, { ColumnInfo: model.ColumnInfo{ ID: 1, Name: model.NewCIStr("name"), Offset: 1, DefaultValue: nil, FieldType: *types.NewFieldType(mysql.TypeVarchar), }, }, } // Set Flen explicitly here, because following ColToResultField will change Flen to zero. // TODO: remove this if ColToResultField update. cols[1].FieldType.Flen = 100 pln := &plans.UnionPlan{ Srcs: []plan.Plan{ tblPlan, tblPlan2, }, Distincts: []bool{true}, RFields: []*field.ResultField{ field.ColToResultField(cols[0], "t"), field.ColToResultField(cols[1], "t"), }, } rset := rsets.Recordset{ Plan: pln, Ctx: mock.NewContext()} cnt := 0 rset.Do(func(data []interface{}) (bool, error) { cnt++ return true, nil }) c.Assert(cnt, Equals, 6) }
func (t *testUnionSuit) TestUnion(c *C) { tblPlan := &testTablePlan{t.data, []string{"id", "name"}} tblPlan2 := &testTablePlan{t.data2, []string{"id", "name"}} cols := []*column.Col{ &column.Col{ ColumnInfo: model.ColumnInfo{ ID: 0, Name: model.NewCIStr("id"), Offset: 0, DefaultValue: 0, FieldType: *types.NewFieldType(mysql.TypeLonglong), }, }, &column.Col{ ColumnInfo: model.ColumnInfo{ ID: 1, Name: model.NewCIStr("name"), Offset: 1, DefaultValue: nil, FieldType: *types.NewFieldType(mysql.TypeVarchar), }, }, } pln := &UnionPlan{ Srcs: []plan.Plan{ tblPlan, tblPlan2, }, Distincts: []bool{true}, RFields: []*field.ResultField{ field.ColToResultField(cols[0], "t"), field.ColToResultField(cols[1], "t"), }, } cnt := 0 pln.Do(nil, func(id interface{}, data []interface{}) (bool, error) { cnt++ return true, nil }) c.Assert(cnt, Equals, 6) }
// Plan gets InfoSchemaPlan/TableDefaultPlan. func (r *TableRset) Plan(ctx context.Context) (plan.Plan, error) { if strings.EqualFold(r.Schema, infoschema.Name) { return plans.NewInfoSchemaPlan(r.Name) } is := sessionctx.GetDomain(ctx).InfoSchema() t, err := is.TableByName(model.NewCIStr(r.Schema), model.NewCIStr(r.Name)) if err != nil { return nil, errors.Trace(err) } tdp := &plans.TableDefaultPlan{T: t} tdp.Fields = make([]*field.ResultField, 0, len(t.Cols())) for _, col := range t.Cols() { f := field.ColToResultField(col, t.TableName().O) f.DBName = r.Schema tdp.Fields = append(tdp.Fields, f) } return tdp, nil }
func (p *testFromSuit) TestTableDefaultPlan(c *C) { pln := &plans.TableDefaultPlan{ T: p.tbl, Fields: []*field.ResultField{ field.ColToResultField(p.cols[0], "t"), field.ColToResultField(p.cols[1], "t"), }, } ret := map[int64]string{} pln.Do(p, func(id interface{}, data []interface{}) (bool, error) { ret[data[0].(int64)] = data[1].(string) return true, nil }) excepted := map[int64]string{} for i := 0; i < 10; i++ { excepted[int64(i*10)] = "hello" } c.Assert(reflect.DeepEqual(ret, excepted), Equals, true) // expr: id > 0 expr := &expressions.BinaryOperation{ Op: opcode.GE, L: &expressions.Ident{ CIStr: model.NewCIStr("id"), }, R: &expressions.Value{ Val: 5, }, } _, filtered, err := pln.FilterForUpdateAndDelete(p, expr) c.Assert(err, IsNil) c.Assert(filtered, IsFalse) // with no index idxCol := &column.IndexedCol{ IndexInfo: model.IndexInfo{ Name: model.NewCIStr("id"), Table: model.NewCIStr("t"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("id"), Offset: 0, Length: 0, }, }, Unique: false, Primary: false, }, X: kv.NewKVIndex("i", "id", false), } p.tbl.AddIndex(idxCol) expr4 := &expressions.Ident{ CIStr: model.NewCIStr("id"), } _, filtered, err = pln.FilterForUpdateAndDelete(p, expr4) c.Assert(err, IsNil) // with no index c.Assert(filtered, IsTrue) expr5 := &expressions.IsNull{ Expr: &expressions.Ident{ CIStr: model.NewCIStr("id"), }, Not: true, } _, filtered, err = pln.FilterForUpdateAndDelete(p, expr5) c.Assert(err, IsNil) // with no index c.Assert(filtered, IsTrue) }
func (p *testIndexSuit) TestIndexPlan(c *C) { pln := &plans.TableDefaultPlan{ T: p.tbl, Fields: []*field.ResultField{ field.ColToResultField(p.tbl.Cols()[0], "t"), field.ColToResultField(p.tbl.Cols()[1], "t"), }, } // expr: id > 0 expr := &expression.BinaryOperation{ Op: opcode.GE, L: &expression.Ident{ CIStr: model.NewCIStr("id"), }, R: expression.Value{ Val: 50, }, } expr2 := &expression.BinaryOperation{ Op: opcode.LT, L: &expression.Ident{ CIStr: model.NewCIStr("id"), }, R: expression.Value{ Val: 100, }, } expr3 := &expression.BinaryOperation{ Op: opcode.LE, L: &expression.Ident{ CIStr: model.NewCIStr("id"), }, R: expression.Value{ Val: 100, }, } expr4 := &expression.BinaryOperation{ Op: opcode.GE, L: &expression.Ident{ CIStr: model.NewCIStr("id"), }, R: expression.Value{ Val: 60, }, } expr5 := &expression.Ident{ CIStr: model.NewCIStr("id"), } np, _, err := pln.Filter(p.ctx, expr) c.Assert(err, IsNil) c.Assert(np, NotNil) np, _, err = np.Filter(p.ctx, expr2) c.Assert(err, IsNil) c.Assert(np, NotNil) np, _, err = np.Filter(p.ctx, expr3) c.Assert(err, IsNil) c.Assert(np, NotNil) np, _, err = np.Filter(p.ctx, expr4) c.Assert(err, IsNil) c.Assert(np, NotNil) np, _, err = np.Filter(p.ctx, expr5) c.Assert(err, IsNil) c.Assert(np, NotNil) ret := map[int64][]byte{} rset := rsets.Recordset{ Plan: np, Ctx: p.ctx, } rset.Do(func(data []interface{}) (bool, error) { ret[data[0].(int64)] = data[1].([]byte) return true, nil }) excepted := map[int64][]byte{} for i := 6; i < 10; i++ { excepted[int64(i*10)] = []byte("hello") } expr6 := &expression.UnaryOperation{ Op: '!', V: &expression.Ident{ CIStr: model.NewCIStr("id"), }, } np, _, err = np.Filter(p.ctx, expr6) c.Assert(err, IsNil) c.Assert(np, NotNil) c.Assert(ret, DeepEquals, excepted) }
func (t *testFinalPlan) TestFinalPlan(c *C) { col1 := &column.Col{ ColumnInfo: model.ColumnInfo{ ID: 0, Name: model.NewCIStr("id"), Offset: 0, DefaultValue: 0, }, } col2 := &column.Col{ ColumnInfo: model.ColumnInfo{ ID: 1, Name: model.NewCIStr("name"), Offset: 1, DefaultValue: nil, }, } col3 := &column.Col{ ColumnInfo: model.ColumnInfo{ ID: 2, Name: model.NewCIStr("ok"), Offset: 2, DefaultValue: false, }, } tblPlan := &testTablePlan{finalTestData, []string{"id", "name", "ok"}, 0} p := &plans.SelectFinalPlan{ SelectList: &plans.SelectList{ HiddenFieldOffset: len(tblPlan.GetFields()), ResultFields: []*field.ResultField{ field.ColToResultField(col1, "t"), field.ColToResultField(col2, "t"), field.ColToResultField(col3, "t"), }, }, Src: tblPlan, } for _, rf := range p.ResultFields { c.Assert(rf.Col.Flag, Equals, uint(0)) c.Assert(rf.Col.Tp, Equals, byte(0)) c.Assert(rf.Col.Charset, Equals, "") } p.Do(nil, func(id interface{}, in []interface{}) (bool, error) { return true, nil }) for _, rf := range p.ResultFields { if rf.Name == "id" { c.Assert(rf.Col.Tp, Equals, mysql.TypeLonglong) c.Assert(rf.Col.Charset, Equals, charset.CharsetBin) } if rf.Name == "name" { c.Assert(rf.Col.Tp, Equals, mysql.TypeVarchar) } // TODO add more type tests } }
func (p *testFromSuit) TestTableDefaultPlan(c *C) { pln := &plans.TableDefaultPlan{ T: p.tbl, Fields: []*field.ResultField{ field.ColToResultField(p.tbl.Cols()[0], "t"), field.ColToResultField(p.tbl.Cols()[1], "t"), }, } ret := map[int64][]byte{} rset := rsets.Recordset{Ctx: p, Plan: pln} rset.Do(func(data []interface{}) (bool, error) { ret[data[0].(int64)] = data[1].([]byte) return true, nil }) excepted := map[int64][]byte{} for i := 0; i < 10; i++ { excepted[int64(i*10)] = []byte("hello") } //c.Assert(reflect.DeepEqual(ret, excepted), Equals, true) c.Assert(ret, DeepEquals, excepted) // expr: id > 0 expr := &expression.BinaryOperation{ Op: opcode.GE, L: &expression.Ident{ CIStr: model.NewCIStr("id"), }, R: &expression.Value{ Val: 5, }, } _, filtered, err := pln.FilterForUpdateAndDelete(p, expr) c.Assert(err, IsNil) c.Assert(filtered, IsFalse) // with no index idxCol := &column.IndexedCol{ IndexInfo: model.IndexInfo{ Name: model.NewCIStr("id"), Table: model.NewCIStr("t"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("id"), Offset: 0, Length: 0, }, }, Unique: false, Primary: false, State: model.StatePublic, }, } idxCol.X = kv.NewKVIndex([]byte("i"), "id", 0, false) p.tbl.AddIndex(idxCol) expr4 := &expression.Ident{ CIStr: model.NewCIStr("id"), } _, filtered, err = pln.FilterForUpdateAndDelete(p, expr4) c.Assert(err, IsNil) // with no index c.Assert(filtered, IsTrue) expr5 := &expression.IsNull{ Expr: &expression.Ident{ CIStr: model.NewCIStr("id"), }, Not: true, } _, filtered, err = pln.FilterForUpdateAndDelete(p, expr5) c.Assert(err, IsNil) // with no index c.Assert(filtered, IsTrue) }