func (d *ddl) AlterTable(ctx context.Context, ident ast.Ident, specs []*ast.AlterTableSpec) (err error) { // now we only allow one schema changes at the same time. if len(specs) != 1 { return errors.New("can't run multi schema changes in one DDL") } for _, spec := range specs { switch spec.Tp { case ast.AlterTableAddColumn: err = d.AddColumn(ctx, ident, spec) case ast.AlterTableDropColumn: err = d.DropColumn(ctx, ident, spec.DropColumn.Name) case ast.AlterTableDropIndex: err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name)) case ast.AlterTableAddConstraint: constr := spec.Constraint switch spec.Constraint.Tp { case ast.ConstraintKey, ast.ConstraintIndex: err = d.CreateIndex(ctx, ident, false, model.NewCIStr(constr.Name), spec.Constraint.Keys) case ast.ConstraintUniq, ast.ConstraintUniqIndex, ast.ConstraintUniqKey: err = d.CreateIndex(ctx, ident, true, model.NewCIStr(constr.Name), spec.Constraint.Keys) default: // nothing to do now. } default: // nothing to do now. } if err != nil { return errors.Trace(err) } } return nil }
func (s *testPlanSuite) TestCoveringIndex(c *C) { cases := []struct { columnNames []string indexNames []string indexLens []int isCovering bool }{ {[]string{"a"}, []string{"a"}, []int{-1}, true}, {[]string{"a"}, []string{"a", "b"}, []int{-1, -1}, true}, {[]string{"a", "b"}, []string{"b", "a"}, []int{-1, -1}, true}, {[]string{"a", "b"}, []string{"b", "c"}, []int{-1, -1}, false}, {[]string{"a", "b"}, []string{"a", "b"}, []int{50, -1}, false}, {[]string{"a", "b"}, []string{"a", "c"}, []int{-1, -1}, false}, } for _, ca := range cases { var columns []*model.ColumnInfo for _, cn := range ca.columnNames { columns = append(columns, &model.ColumnInfo{Name: model.NewCIStr(cn)}) } var indexCols []*model.IndexColumn for i := range ca.indexNames { icn := ca.indexNames[i] icl := ca.indexLens[i] indexCols = append(indexCols, &model.IndexColumn{Name: model.NewCIStr(icn), Length: icl}) } covering := isCoveringIndex(columns, indexCols) c.Assert(covering, Equals, ca.isCovering) } }
func buildResultField(tableName, name string, tp byte, size int) *ast.ResultField { cs := charset.CharsetBin cl := charset.CharsetBin flag := mysql.UnsignedFlag if tp == mysql.TypeVarchar || tp == mysql.TypeBlob { cs = mysql.DefaultCharset cl = mysql.DefaultCollationName flag = 0 } fieldType := types.FieldType{ Charset: cs, Collate: cl, Tp: tp, Flen: size, Flag: uint(flag), } colInfo := &model.ColumnInfo{ Name: model.NewCIStr(name), FieldType: fieldType, } expr := &ast.ValueExpr{} expr.SetType(&fieldType) return &ast.ResultField{ Column: colInfo, ColumnAsName: colInfo.Name, TableAsName: model.NewCIStr(tableName), DBName: model.NewCIStr(infoschema.Name), Expr: expr, } }
func (ts *testSuite) TestConstraintNames(c *C) { handle := infoschema.NewHandle(ts.store) handle.Set(nil) dd := ddl.NewDDL(ts.store, handle) se, _ := tidb.CreateSession(ts.store) ctx := se.(context.Context) schemaName := model.NewCIStr("test") tblName := model.NewCIStr("t") tbIdent := table.Ident{ Schema: schemaName, Name: tblName, } err := dd.CreateSchema(ctx, tbIdent.Schema) c.Assert(err, IsNil) tbStmt := statement("create table t (a int, b int, index a (a, b), index a (a))").(*stmts.CreateTableStmt) err = dd.CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints) c.Assert(err, NotNil) tbStmt = statement("create table t (a int, b int, index A (a, b), index (a))").(*stmts.CreateTableStmt) err = dd.CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints) c.Assert(err, IsNil) tbl, err := handle.Get().TableByName(schemaName, tblName) indices := tbl.Indices() c.Assert(len(indices), Equals, 2) c.Assert(indices[0].Name.O, Equals, "A") c.Assert(indices[1].Name.O, Equals, "a_2") err = dd.DropSchema(ctx, tbIdent.Schema) c.Assert(err, IsNil) }
func (s *testDDLSuite) TestIndexError(c *C) { defer testleak.AfterTest(c)() store := testCreateStore(c, "test_index_error") defer store.Close() d := newDDL(store, nil, nil, testLease) defer d.close() ctx := testNewContext(c, d) doDDLJobErr(c, -1, 1, model.ActionAddIndex, nil, ctx, d) doDDLJobErr(c, -1, 1, model.ActionDropIndex, nil, ctx, d) dbInfo := testSchemaInfo(c, d, "test") tblInfo := testTableInfo(c, d, "t", 3) testCreateSchema(c, ctx, d, dbInfo) testCreateTable(c, ctx, d, dbInfo, tblInfo) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex, []interface{}{1}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex, []interface{}{false, model.NewCIStr("t"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex, []interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}}, ctx, d) testCreateIndex(c, ctx, d, dbInfo, tblInfo, false, "c1_index", "c1") doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex, []interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c1")}, Length: 256}}}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropIndex, []interface{}{1}, ctx, d) testDropIndex(c, ctx, d, dbInfo, tblInfo, "c1_index") doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropIndex, []interface{}{model.NewCIStr("c1_index")}, ctx, d) }
func (b *planBuilder) buildExplain(explain *ast.ExplainStmt) Plan { if show, ok := explain.Stmt.(*ast.ShowStmt); ok { return b.buildShow(show) } targetPlan, err := Optimize(b.ctx, explain.Stmt, b.is) if err != nil { b.err = errors.Trace(err) return nil } p := &Explain{StmtPlan: targetPlan} addChild(p, targetPlan) schema := make(expression.Schema, 0, 3) schema = append(schema, &expression.Column{ ColName: model.NewCIStr("ID"), RetType: types.NewFieldType(mysql.TypeString), }) schema = append(schema, &expression.Column{ ColName: model.NewCIStr("Json"), RetType: types.NewFieldType(mysql.TypeString), }) schema = append(schema, &expression.Column{ ColName: model.NewCIStr("ParentID"), RetType: types.NewFieldType(mysql.TypeString), }) p.SetSchema(schema) return p }
// create a test table with num int columns and with no index. func testTableInfo(c *C, d *ddl, name string, num int) *model.TableInfo { var err error tblInfo := &model.TableInfo{ Name: model.NewCIStr(name), } tblInfo.ID, err = d.genGlobalID() c.Assert(err, IsNil) cols := make([]*model.ColumnInfo, num) for i := range cols { col := &model.ColumnInfo{ Name: model.NewCIStr(fmt.Sprintf("c%d", i+1)), Offset: i, DefaultValue: i + 1, State: model.StatePublic, } col.FieldType = *types.NewFieldType(mysql.TypeLong) col.ID, err = d.genGlobalID() c.Assert(err, IsNil) cols[i] = col } tblInfo.Columns = cols return tblInfo }
func (t *testGroupBySuite) TestGroupBy(c *C) { tblPlan := &testTablePlan{groupByTestData, []string{"id", "name"}} // test multiple fields sl := &SelectList{ Fields: []*field.Field{ { Expr: &expressions.Ident{ CIStr: model.NewCIStr("id"), }, }, { Expr: &expressions.Ident{ CIStr: model.NewCIStr("name"), }, }, { Expr: &expressions.Call{ F: "sum", Args: []expression.Expression{ &expressions.Ident{ CIStr: model.NewCIStr("id"), }, }, }, }, }, AggFields: map[int]struct{}{2: {}}, } groupbyPlan := &GroupByDefaultPlan{ SelectList: sl, Src: tblPlan, By: []expression.Expression{ &expressions.Ident{ CIStr: model.NewCIStr("id"), }, }, } ret := map[int]string{} groupbyPlan.Do(nil, func(id interface{}, data []interface{}) (bool, error) { ret[data[0].(int)] = data[1].(string) return true, nil }) c.Assert(ret, HasLen, 3) excepted := map[int]string{ 10: "10", 40: "40", 60: "60", } c.Assert(ret, DeepEquals, excepted) // test empty tblPlan.rows = []*testRowData{} groupbyPlan.Src = tblPlan groupbyPlan.By = nil groupbyPlan.Do(nil, func(id interface{}, data []interface{}) (bool, error) { return true, nil }) }
func (ts *testMemoryTableSuite) SetUpSuite(c *C) { driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} store, err := driver.Open("memory") c.Check(err, IsNil) ts.store = store ts.se, err = tidb.CreateSession(ts.store) c.Assert(err, IsNil) // create table tp1 := types.NewFieldType(mysql.TypeLong) col1 := &model.ColumnInfo{ ID: 1, Name: model.NewCIStr("a"), Offset: 0, FieldType: *tp1, } tp2 := types.NewFieldType(mysql.TypeVarchar) tp2.Flen = 255 col2 := &model.ColumnInfo{ ID: 2, Name: model.NewCIStr("b"), Offset: 1, FieldType: *tp2, } tblInfo := &model.TableInfo{ ID: 100, Name: model.NewCIStr("t"), Columns: []*model.ColumnInfo{col1, col2}, } alloc := autoid.NewMemoryAllocator(int64(10)) ts.tbl, _ = tables.MemoryTableFromMeta(alloc, tblInfo) }
func (s *testForeighKeySuite) testCreateForeignKey(c *C, tblInfo *model.TableInfo, fkName string, keys []string, refTable string, refKeys []string, onDelete ast.ReferOptionType, onUpdate ast.ReferOptionType) *model.Job { FKName := model.NewCIStr(fkName) Keys := make([]model.CIStr, len(keys)) for i, key := range keys { Keys[i] = model.NewCIStr(key) } RefTable := model.NewCIStr(refTable) RefKeys := make([]model.CIStr, len(refKeys)) for i, key := range refKeys { RefKeys[i] = model.NewCIStr(key) } fkInfo := &model.FKInfo{ Name: FKName, RefTable: RefTable, RefCols: RefKeys, Cols: Keys, OnDelete: int(onDelete), OnUpdate: int(onUpdate), State: model.StateNone, } job := &model.Job{ SchemaID: s.dbInfo.ID, TableID: tblInfo.ID, Type: model.ActionAddForeignKey, Args: []interface{}{fkInfo}, } err := s.d.doDDLJob(s.ctx, job) c.Assert(err, IsNil) return job }
func (ts *testSuite) TestConstraintNames(c *C) { se, _ := tidb.CreateSession(ts.store) ctx := se.(context.Context) schemaName := model.NewCIStr("test_constraint") tblName := model.NewCIStr("t") tbIdent := table.Ident{ Schema: schemaName, Name: tblName, } err := sessionctx.GetDomain(ctx).DDL().CreateSchema(ctx, tbIdent.Schema, ts.charsetInfo) c.Assert(err, IsNil) tbStmt := statement(ctx, "create table t (a int, b int, index a (a, b), index a (a))").(*stmts.CreateTableStmt) err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints) c.Assert(err, NotNil) tbStmt = statement(ctx, "create table t (a int, b int, index A (a, b), index (a))").(*stmts.CreateTableStmt) err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints) c.Assert(err, IsNil) tbl, err := sessionctx.GetDomain(ctx).InfoSchema().TableByName(schemaName, tblName) indices := tbl.Indices() c.Assert(len(indices), Equals, 2) c.Assert(indices[0].Name.O, Equals, "A") c.Assert(indices[1].Name.O, Equals, "a_2") err = sessionctx.GetDomain(ctx).DDL().DropSchema(ctx, tbIdent.Schema) c.Assert(err, IsNil) }
// Make sure that all tables of infomation_schema could be found in infoschema handle. func (*testSuite) TestInfoTables(c *C) { defer testleak.AfterTest(c)() driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} store, err := driver.Open("memory") c.Assert(err, IsNil) defer store.Close() handle, err := infoschema.NewHandle(store) c.Assert(err, IsNil) builder, err := infoschema.NewBuilder(handle).InitWithDBInfos(nil, 0) c.Assert(err, IsNil) err = builder.Build() c.Assert(err, IsNil) is := handle.Get() c.Assert(is, NotNil) info_tables := []string{ "SCHEMATA", "TABLES", "COLUMNS", "STATISTICS", "CHARACTER_SETS", "COLLATIONS", "FILES", "PROFILING", "PARTITIONS", "KEY_COLUMN_USAGE", "REFERENTIAL_CONSTRAINTS", } for _, t := range info_tables { tb, err1 := is.TableByName(model.NewCIStr(infoschema.Name), model.NewCIStr(t)) c.Assert(err1, IsNil) c.Assert(tb, NotNil) } }
func (s *testExpressionSuite) TestExpression(c *C) { defer testleak.AfterTest(c)() var schema Schema for i := 0; i < 3; i++ { schema = append(schema, &Column{ColName: model.NewCIStr("t"), FromID: "mock", Position: i}) } tc1 := &Column{FromID: "t", ColName: model.NewCIStr("c1")} kc1 := &Column{FromID: "k", ColName: model.NewCIStr("c1")} tc2 := &Column{FromID: "t", ColName: model.NewCIStr("c2")} con := &Constant{Value: types.NewDatum(10)} col := &ast.ColumnName{Name: model.NewCIStr("t")} // t.c1 as t, t.c2 as t, 10 as t => error index, err := getColIndex([]Expression{tc1, tc2, con}, schema, col) c.Check(err, NotNil) // t.c1 as t, 10 as t, t.c2 as t => 10 index, err = getColIndex([]Expression{tc1, con, tc2}, schema, col) c.Assert(index, Equals, 1) // t.c1 as t, t.c1 as t, 10 as t => 10 index, err = getColIndex([]Expression{tc1, tc1, con}, schema, col) c.Assert(index, Equals, 2) // t.c1 as t, k.c1 as t, 10 as t => error index, err = getColIndex([]Expression{tc1, kc1, con}, schema, col) c.Check(err, NotNil) }
func (s *testTableRsetSuite) TestTableSourceString(c *C) { tableIdent := table.Ident{Schema: model.NewCIStr(s.dbName), Name: model.NewCIStr(s.tableName)} ts := &rsets.TableSource{Source: tableIdent, Name: s.tableName} str := ts.String() c.Assert(len(str), Greater, 0) store := newStore(c) se := newSession(c, store, s.dbName) ctx, ok := se.(context.Context) c.Assert(ok, IsTrue) stmtList, err := tidb.Compile(ctx, s.querySql) c.Assert(err, IsNil) c.Assert(len(stmtList), Greater, 0) ts = &rsets.TableSource{Source: stmtList[0], Name: s.tableName} str = ts.String() c.Assert(len(str), Greater, 0) ts = &rsets.TableSource{Source: stmtList[0]} str = ts.String() c.Assert(len(str), Greater, 0) // check panic defer func() { e := recover() c.Assert(e, NotNil) }() ts = &rsets.TableSource{} str = ts.String() }
func (ts *testSuite) TestUniqueIndexMultipleNullEntries(c *C) { _, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)") c.Assert(err, IsNil) ctx := ts.se.(context.Context) dom := sessionctx.GetDomain(ctx) tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) c.Assert(tb.Meta().ID, Greater, int64(0)) c.Assert(tb.Meta().Name.L, Equals, "t") c.Assert(tb.Meta(), NotNil) c.Assert(tb.Indices(), NotNil) c.Assert(string(tb.FirstKey()), Not(Equals), "") c.Assert(string(tb.IndexPrefix()), Not(Equals), "") c.Assert(string(tb.RecordPrefix()), Not(Equals), "") c.Assert(tables.FindIndexByColName(tb, "b"), NotNil) autoid, err := tb.AllocAutoID() c.Assert(err, IsNil) c.Assert(autoid, Greater, int64(0)) _, err = tb.AddRecord(ctx, types.MakeDatums(1, nil)) c.Assert(err, IsNil) _, err = tb.AddRecord(ctx, types.MakeDatums(2, nil)) c.Assert(err, IsNil) _, err = ts.se.Execute("drop table test.t") c.Assert(err, IsNil) }
func (p *testFromSuit) SetUpSuite(c *C) { store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory) c.Assert(err, IsNil) p.vars = map[string]interface{}{} p.txn, _ = store.Begin() p.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), }, }, } p.tbl = tables.NewTable(1, "t", "test", p.cols, &simpleAllocator{}) variable.BindSessionVars(p) var i int64 for i = 0; i < 10; i++ { p.tbl.AddRecord(p, []interface{}{i * 10, "hello"}) } }
func (d *ddl) AlterTable(ctx context.Context, ident table.Ident, specs []*AlterSpecification) (err error) { // now we only allow one schema changes at the same time. if len(specs) != 1 { return errors.New("can't run multi schema changes in one DDL") } for _, spec := range specs { switch spec.Action { case AlterAddColumn: err = d.AddColumn(ctx, ident, spec) case AlterDropColumn: err = d.DropColumn(ctx, ident, model.NewCIStr(spec.Name)) case AlterDropIndex: err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name)) case AlterAddConstr: constr := spec.Constraint switch spec.Constraint.Tp { case coldef.ConstrKey, coldef.ConstrIndex: err = d.CreateIndex(ctx, ident, false, model.NewCIStr(constr.ConstrName), spec.Constraint.Keys) case coldef.ConstrUniq, coldef.ConstrUniqIndex, coldef.ConstrUniqKey: err = d.CreateIndex(ctx, ident, true, model.NewCIStr(constr.ConstrName), spec.Constraint.Keys) default: // nothing to do now. } default: // nothing to do now. } if err != nil { return errors.Trace(err) } } return nil }
func (s *testDDLSuite) TestColumnError(c *C) { defer testleak.AfterTest(c)() store := testCreateStore(c, "test_column_error") defer store.Close() d := newDDL(store, nil, nil, testLease) defer d.close() ctx := testNewContext(c, d) dbInfo := testSchemaInfo(c, d, "test") tblInfo := testTableInfo(c, d, "t", 3) testCreateSchema(c, ctx, d, dbInfo) testCreateTable(c, ctx, d, dbInfo, tblInfo) col := &model.ColumnInfo{ Name: model.NewCIStr("c4"), Offset: len(tblInfo.Columns), DefaultValue: 0, } col.ID = allocateColumnID(tblInfo) col.FieldType = *types.NewFieldType(mysql.TypeLong) pos := &ast.ColumnPosition{Tp: ast.ColumnPositionAfter, RelativeColumn: &ast.ColumnName{Name: model.NewCIStr("c5")}} // for adding column doDDLJobErr(c, -1, tblInfo.ID, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d) doDDLJobErr(c, dbInfo.ID, -1, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddColumn, []interface{}{0}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d) // for dropping column doDDLJobErr(c, -1, tblInfo.ID, model.ActionDropColumn, []interface{}{col, pos, 0}, ctx, d) doDDLJobErr(c, dbInfo.ID, -1, model.ActionDropColumn, []interface{}{col, pos, 0}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropColumn, []interface{}{0}, ctx, d) doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropColumn, []interface{}{model.NewCIStr("c5")}, ctx, d) }
// buildProjection returns a Projection plan and non-aux columns length. func (b *planBuilder) buildProjection(p LogicalPlan, fields []*ast.SelectField, mapper map[*ast.AggregateFuncExpr]int) (LogicalPlan, int) { proj := &Projection{ Exprs: make([]expression.Expression, 0, len(fields)), baseLogicalPlan: newBaseLogicalPlan(Proj, b.allocator), } proj.initID() proj.correlated = p.IsCorrelated() schema := make(expression.Schema, 0, len(fields)) oldLen := 0 for _, field := range fields { newExpr, np, correlated, err := b.rewrite(field.Expr, p, mapper, true) if err != nil { b.err = errors.Trace(err) return nil, oldLen } p = np proj.correlated = proj.correlated || correlated proj.Exprs = append(proj.Exprs, newExpr) var tblName, colName model.CIStr if field.AsName.L != "" { colName = field.AsName } else if c, ok := newExpr.(*expression.Column); ok && !c.IsAggOrSubq { if astCol, ok := getInnerFromParentheses(field.Expr).(*ast.ColumnNameExpr); ok { colName = astCol.Name.Name tblName = astCol.Name.Table } else { colName = c.ColName tblName = c.TblName } } else { // When the query is select t.a from t group by a; The Column Name should be a but not t.a; if agg, ok := field.Expr.(*ast.AggregateFuncExpr); ok && agg.F == ast.AggFuncFirstRow { if col, ok := agg.Args[0].(*ast.ColumnNameExpr); ok { colName = col.Name.Name } } else { innerExpr := getInnerFromParentheses(field.Expr) if _, ok := innerExpr.(*ast.ValueExpr); ok && innerExpr.Text() != "" { colName = model.NewCIStr(innerExpr.Text()) } else { colName = model.NewCIStr(field.Text()) } } } schemaCol := &expression.Column{ FromID: proj.id, TblName: tblName, ColName: colName, RetType: newExpr.GetType(), } if !field.Auxiliary { oldLen++ } schema = append(schema, schemaCol) schemaCol.Position = len(schema) } proj.SetSchema(schema) addChild(proj, p) return proj, oldLen }
func (s *testTableRsetSuite) TestTableSourceString(c *C) { tableIdent := table.Ident{Schema: model.NewCIStr(s.dbName), Name: model.NewCIStr(s.tableName)} ts := &rsets.TableSource{Source: tableIdent, Name: s.tableName} str := ts.String() c.Assert(len(str), Greater, 0) stmtList, err := tidb.Compile(s.querySql) c.Assert(err, IsNil) c.Assert(len(stmtList), Greater, 0) ts = &rsets.TableSource{Source: stmtList[0], Name: s.tableName} str = ts.String() c.Assert(len(str), Greater, 0) ts = &rsets.TableSource{Source: stmtList[0]} str = ts.String() c.Assert(len(str), Greater, 0) // check panic defer func() { e := recover() c.Assert(e, NotNil) }() ts = &rsets.TableSource{} str = ts.String() }
func (ts *testSuite) TestTypes(c *C) { _, err := ts.se.Execute("CREATE TABLE test.t (c1 tinyint, c2 smallint, c3 int, c4 bigint, c5 text, c6 blob, c7 varchar(64), c8 time, c9 timestamp not null default CURRENT_TIMESTAMP, c10 decimal)") c.Assert(err, IsNil) ctx := ts.se.(context.Context) dom := sessionctx.GetDomain(ctx) _, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) _, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, '5', '6', '7', '10:10:10', null, 1.4)") c.Assert(err, IsNil) rs, err := ts.se.Execute("select * from test.t where c1 = 1") row, err := rs[0].FirstRow() c.Assert(err, IsNil) c.Assert(row, NotNil) _, err = ts.se.Execute("drop table test.t") c.Assert(err, IsNil) _, err = ts.se.Execute("CREATE TABLE test.t (c1 tinyint unsigned, c2 smallint unsigned, c3 int unsigned, c4 bigint unsigned, c5 double)") c.Assert(err, IsNil) _, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, 5)") c.Assert(err, IsNil) rs, err = ts.se.Execute("select * from test.t where c1 = 1") row, err = rs[0].FirstRow() c.Assert(err, IsNil) c.Assert(row, NotNil) _, err = ts.se.Execute("drop table test.t") c.Assert(err, IsNil) }
func (*testSuite) TestT(c *C) { driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} store, err := driver.Open("memory") c.Assert(err, IsNil) defer store.Close() m := meta.NewMeta(store) err = m.RunInNewTxn(false, func(m *meta.TMeta) error { err = m.CreateDatabase(&model.DBInfo{ID: 1, Name: model.NewCIStr("a")}) c.Assert(err, IsNil) err = m.CreateTable(1, &model.TableInfo{ID: 1, Name: model.NewCIStr("t")}) c.Assert(err, IsNil) return nil }) c.Assert(err, IsNil) alloc := autoid.NewAllocator(m, 1) c.Assert(alloc, NotNil) id, err := alloc.Alloc(1) c.Assert(err, IsNil) c.Assert(id, Equals, int64(1)) id, err = alloc.Alloc(1) c.Assert(err, IsNil) c.Assert(id, Equals, int64(2)) id, err = alloc.Alloc(0) c.Assert(err, NotNil) }
func (ts *testFunctionsSuite) TestAggregateFuncExtractor(c *C) { var expr Node extractor := &AggregateFuncExtractor{} expr = &AggregateFuncExpr{} expr.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 1) c.Assert(extractor.AggFuncs[0], Equals, expr) extractor = &AggregateFuncExtractor{} expr = &FuncCallExpr{ FnName: model.NewCIStr("DATE_ARITH"), } expr.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 0) extractor = &AggregateFuncExtractor{} r := &AggregateFuncExpr{} expr = &BinaryOperationExpr{ L: &FuncCallExpr{ FnName: model.NewCIStr("DATE_ARITH"), }, R: r, } expr.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 1) c.Assert(extractor.AggFuncs[0], Equals, r) // convert ColumnNameExpr to AggregateFuncExpr extractor = &AggregateFuncExtractor{} expr = &ColumnNameExpr{} f := &SelectField{Expr: expr.(ExprNode)} f.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 1) e := extractor.AggFuncs[0] c.Assert(e, NotNil) c.Assert(e.F, Equals, AggFuncFirstRow) // select exists(select count(c) from t) from t // subquery contains aggregate function expr1 := &AggregateFuncExpr{} field1 := &SelectField{Expr: expr1} fields1 := &FieldList{Fields: []*SelectField{field1}} subSel := &SelectStmt{Fields: fields1} subExpr := &ExistsSubqueryExpr{ Sel: &SubqueryExpr{Query: subSel}, } field := &SelectField{Expr: subExpr} fields := &FieldList{Fields: []*SelectField{field}} sel := &SelectStmt{Fields: fields} extractor = &AggregateFuncExtractor{} sel.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 0) extractor = &AggregateFuncExtractor{} subSel.Accept(extractor) c.Assert(extractor.AggFuncs, HasLen, 1) }
func (s *testDBSuite) TestUpdateMultipleTable(c *C) { defer testleak.AfterTest(c) store, err := tidb.NewStore("memory://update_multiple_table") c.Assert(err, IsNil) tk := testkit.NewTestKit(c, store) tk.MustExec("use test") tk.MustExec("create table t1 (c1 int, c2 int)") tk.MustExec("insert t1 values (1, 1), (2, 2)") tk.MustExec("create table t2 (c1 int, c2 int)") tk.MustExec("insert t2 values (1, 3), (2, 5)") ctx := tk.Se.(context.Context) domain := sessionctx.GetDomain(ctx) is := domain.InfoSchema() db, ok := is.SchemaByName(model.NewCIStr("test")) c.Assert(ok, IsTrue) t1Tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) c.Assert(err, IsNil) t1Info := t1Tbl.Meta() // Add a new column in write only state. newColumn := &model.ColumnInfo{ ID: 100, Name: model.NewCIStr("c3"), Offset: 2, DefaultValue: 9, FieldType: *types.NewFieldType(mysql.TypeLonglong), State: model.StateWriteOnly, } t1Info.Columns = append(t1Info.Columns, newColumn) kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { m := meta.NewMeta(txn) _, err = m.GenSchemaVersion() c.Assert(err, IsNil) c.Assert(m.UpdateTable(db.ID, t1Info), IsNil) return nil }) err = domain.Reload() c.Assert(err, IsNil) tk.MustExec("update t1, t2 set t1.c1 = 8, t2.c2 = 10 where t1.c2 = t2.c1") tk.MustQuery("select * from t1").Check(testkit.Rows("8 1", "8 2")) tk.MustQuery("select * from t2").Check(testkit.Rows("1 10", "2 10")) newColumn.State = model.StatePublic kv.RunInNewTxn(store, false, func(txn kv.Transaction) error { m := meta.NewMeta(txn) _, err = m.GenSchemaVersion() c.Assert(err, IsNil) c.Assert(m.UpdateTable(db.ID, t1Info), IsNil) return nil }) err = domain.Reload() c.Assert(err, IsNil) tk.MustQuery("select * from t1").Check(testkit.Rows("8 1 9", "8 2 9")) }
func (s *testOrderByRsetSuite) TestOrderByRsetCheckAndUpdateSelectList(c *C) { resultFields := s.r.Src.GetFields() fields := make([]*field.Field, len(resultFields)) for i, resultField := range resultFields { name := resultField.Name fields[i] = &field.Field{Expr: &expressions.Ident{CIStr: model.NewCIStr(name)}, Name: name} } selectList := &plans.SelectList{ HiddenFieldOffset: len(resultFields), ResultFields: resultFields, Fields: fields, } expr := &expressions.Ident{model.NewCIStr("id")} orderByItem := OrderByItem{Expr: expr, Asc: true} by := []OrderByItem{orderByItem} r := &OrderByRset{By: by, SelectList: selectList} // `select id, name from t order by id` err := r.CheckAndUpdateSelectList(selectList, resultFields) c.Assert(err, IsNil) // `select id, name as id from t order by id` selectList.Fields[1].Name = "id" selectList.ResultFields[1].Name = "id" err = r.CheckAndUpdateSelectList(selectList, resultFields) c.Assert(err, NotNil) // `select id, name from t order by count(1) > 1` aggExpr, err := expressions.NewCall("count", []expression.Expression{expressions.Value{1}}, false) c.Assert(err, IsNil) r.By[0].Expr = aggExpr err = r.CheckAndUpdateSelectList(selectList, resultFields) c.Assert(err, IsNil) // `select id, name from t order by count(xxx) > 1` aggExpr, err = expressions.NewCall("count", []expression.Expression{&expressions.Ident{model.NewCIStr("xxx")}}, false) c.Assert(err, IsNil) r.By[0].Expr = aggExpr err = r.CheckAndUpdateSelectList(selectList, resultFields) c.Assert(err, NotNil) // `select id, name from t order by xxx` r.By[0].Expr = &expressions.Ident{model.NewCIStr("xxx")} selectList.Fields[1].Name = "name" selectList.ResultFields[1].Name = "name" err = r.CheckAndUpdateSelectList(selectList, resultFields) c.Assert(err, NotNil) }
func (p *physicalTableSource) addAggregation(agg *PhysicalAggregation) expression.Schema { if p.client == nil { return nil } for _, f := range agg.AggFuncs { pb := aggFuncToPBExpr(p.client, f) if pb == nil { p.clear() return nil } p.AggFuncs = append(p.AggFuncs, pb) } for _, item := range agg.GroupByItems { pb := groupByItemToPB(p.client, item) if pb == nil { p.clear() return nil } p.GbyItems = append(p.GbyItems, pb) } p.Aggregated = true gk := types.NewFieldType(mysql.TypeBlob) gk.Charset = charset.CharsetBin gk.Collate = charset.CollationBin p.AggFields = append(p.AggFields, gk) var schema expression.Schema cursor := 0 schema = append(schema, &expression.Column{Index: cursor, ColName: model.NewCIStr(fmt.Sprint(agg.GroupByItems))}) agg.GroupByItems = []expression.Expression{schema[cursor]} newAggFuncs := make([]expression.AggregationFunction, len(agg.AggFuncs)) for i, aggFun := range agg.AggFuncs { fun := expression.NewAggFunction(aggFun.GetName(), nil, false) var args []expression.Expression colName := model.NewCIStr(fmt.Sprint(aggFun.GetArgs())) if needCount(fun) { cursor++ schema = append(schema, &expression.Column{Index: cursor, ColName: colName}) args = append(args, schema[cursor]) ft := types.NewFieldType(mysql.TypeLonglong) ft.Flen = 21 ft.Charset = charset.CharsetBin ft.Collate = charset.CollationBin p.AggFields = append(p.AggFields, ft) } if needValue(fun) { cursor++ schema = append(schema, &expression.Column{Index: cursor, ColName: colName}) args = append(args, schema[cursor]) p.AggFields = append(p.AggFields, agg.schema[i].GetType()) } fun.SetArgs(args) fun.SetMode(expression.FinalMode) newAggFuncs[i] = fun } agg.AggFuncs = newAggFuncs return schema }
func (s *testSuite) TestAdmin(c *C) { defer testleak.AfterTest(c)() tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))") tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)") r, err := tk.Exec("admin show ddl") c.Assert(err, IsNil) row, err := r.Next() c.Assert(err, IsNil) c.Assert(row.Data, HasLen, 6) txn, err := s.store.Begin() c.Assert(err, IsNil) ddlInfo, err := inspectkv.GetDDLInfo(txn) c.Assert(err, IsNil) c.Assert(row.Data[0].GetInt64(), Equals, ddlInfo.SchemaVer) rowOwnerInfos := strings.Split(row.Data[1].GetString(), ",") ownerInfos := strings.Split(ddlInfo.Owner.String(), ",") c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0]) c.Assert(row.Data[2].GetString(), Equals, "") bgInfo, err := inspectkv.GetBgDDLInfo(txn) c.Assert(err, IsNil) c.Assert(row.Data[3].GetInt64(), Equals, bgInfo.SchemaVer) rowOwnerInfos = strings.Split(row.Data[4].GetString(), ",") ownerInfos = strings.Split(bgInfo.Owner.String(), ",") c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0]) c.Assert(row.Data[5].GetString(), Equals, "") row, err = r.Next() c.Assert(err, IsNil) c.Assert(row, IsNil) // check table test tk.MustExec("create table admin_test1 (c1 int, c2 int default 1, index (c1))") tk.MustExec("insert admin_test1 (c1) values (21),(22)") r, err = tk.Exec("admin check table admin_test, admin_test1") c.Assert(err, IsNil) c.Assert(r, IsNil) // error table name r, err = tk.Exec("admin check table admin_test_error") c.Assert(err, NotNil) // different index values ctx := tk.Se.(context.Context) domain := sessionctx.GetDomain(ctx) is := domain.InfoSchema() c.Assert(is, NotNil) tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("admin_test")) c.Assert(err, IsNil) c.Assert(tb.Indices(), HasLen, 1) _, err = tb.Indices()[0].Create(txn, types.MakeDatums(int64(10)), 1) c.Assert(err, IsNil) err = txn.Commit() c.Assert(err, IsNil) r, err = tk.Exec("admin check table admin_test") c.Assert(err, NotNil) }
func (ts *testSuite) TestBasic(c *C) { _, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)") c.Assert(err, IsNil) ctx := ts.se.(context.Context) dom := sessionctx.GetDomain(ctx) tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) c.Assert(tb.TableID(), Greater, int64(0)) c.Assert(tb.TableName().L, Equals, "t") c.Assert(tb.Meta(), NotNil) c.Assert(tb.Indices(), NotNil) c.Assert(tb.FirstKey(), Not(Equals), "") c.Assert(tb.IndexPrefix(), Not(Equals), "") c.Assert(tb.KeyPrefix(), Not(Equals), "") c.Assert(tb.FindIndexByColName("b"), NotNil) autoid, err := tb.AllocAutoID() c.Assert(err, IsNil) c.Assert(autoid, Greater, int64(0)) rid, err := tb.AddRecord(ctx, []interface{}{1, "abc"}) c.Assert(err, IsNil) c.Assert(rid, Greater, int64(0)) row, err := tb.Row(ctx, rid) c.Assert(err, IsNil) c.Assert(len(row), Equals, 2) c.Assert(row[0].(int64), Equals, int64(1)) _, err = tb.AddRecord(ctx, []interface{}{1, "aba"}) c.Assert(err, NotNil) _, err = tb.AddRecord(ctx, []interface{}{2, "abc"}) c.Assert(err, NotNil) c.Assert(tb.UpdateRecord(ctx, rid, []interface{}{1, "abc"}, []interface{}{1, "cba"}, []bool{false, true}), IsNil) tb.IterRecords(ctx, tb.FirstKey(), tb.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) { return true, nil }) c.Assert(tb.RemoveRowAllIndex(ctx, rid, []interface{}{1, "cba"}), IsNil) c.Assert(tb.RemoveRow(ctx, rid), IsNil) // Make sure there is index data in the storage. prefix := tb.IndexPrefix() cnt, err := countEntriesWithPrefix(ctx, prefix) c.Assert(err, IsNil) //c.Assert(cnt, Greater, 0) // it is not a correct assert, because after fix issue 463, there is no index in the table anymore c.Assert(cnt, Equals, 0) c.Assert(tb.Truncate(ctx), IsNil) // Make sure index data is also removed after tb.Truncate(). cnt, err = countEntriesWithPrefix(ctx, prefix) c.Assert(err, IsNil) c.Assert(cnt, Equals, 0) _, err = ts.se.Execute("drop table test.t") c.Assert(err, IsNil) }
func (s *testDBSuite) testGetTable(c *C, name string) table.Table { ctx := s.s.(context.Context) domain := sessionctx.GetDomain(ctx) // Make sure the table schema is the new schema. err := domain.MustReload() c.Assert(err, IsNil) tbl, err := domain.InfoSchema().TableByName(model.NewCIStr(s.schemaName), model.NewCIStr(name)) c.Assert(err, IsNil) return tbl }
func composeUserTableRset() *rsets.JoinRset { return &rsets.JoinRset{ Left: &rsets.TableSource{ Source: table.Ident{ Name: model.NewCIStr(mysql.UserTable), Schema: model.NewCIStr(mysql.SystemDB), }, }, } }