From c41cac7918eff8125982c7ef100eeea78461fda2 Mon Sep 17 00:00:00 2001 From: crazycs Date: Sat, 20 Apr 2019 23:00:15 +0800 Subject: [PATCH 1/6] infoschema: fix compatibility of auto_increment column value of INFORMATION_SCHEMA.TABLES --- executor/show_test.go | 4 ++-- infoschema/tables.go | 41 ++++++++++++++++++++------------------- infoschema/tables_test.go | 6 ++++++ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/executor/show_test.go b/executor/show_test.go index 675a2ccf1901e..c7306f63cd44d 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -267,7 +267,7 @@ func (s *testSuite2) TestShow2(c *C) { tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "192.168.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890")) r := tk.MustQuery("show table status from test like 't'") - r.Check(testkit.Rows(fmt.Sprintf("t InnoDB 10 Compact 0 0 0 0 0 0 0 %s utf8mb4_bin 注释", createTime))) + r.Check(testkit.Rows(fmt.Sprintf("t InnoDB 10 Compact 0 0 0 0 0 0 %s utf8mb4_bin 注释", createTime))) tk.MustQuery("show databases like 'test'").Check(testkit.Rows("test")) @@ -346,7 +346,7 @@ func (s *testSuite2) TestUnprivilegedShow(c *C) { c.Assert(err, IsNil) createTime := model.TSConvert2Time(tblInfo.Meta().UpdateTS).Format("2006-01-02 15:04:05") - tk.MustQuery("show table status from testshow").Check(testkit.Rows(fmt.Sprintf("t1 InnoDB 10 Compact 0 0 0 0 0 0 0 %s utf8mb4_bin ", createTime))) + tk.MustQuery("show table status from testshow").Check(testkit.Rows(fmt.Sprintf("t1 InnoDB 10 Compact 0 0 0 0 0 0 %s utf8mb4_bin ", createTime))) } diff --git a/infoschema/tables.go b/infoschema/tables.go index a2ac042066c63..cb3e14ff6a09c 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1072,24 +1072,14 @@ func (c *statsCache) get(ctx sessionctx.Context) (map[int64]uint64, map[tableHis } func getAutoIncrementID(ctx sessionctx.Context, schema *model.DBInfo, tblInfo *model.TableInfo) (int64, error) { - hasAutoIncID := false - for _, col := range tblInfo.Cols() { - if mysql.HasAutoIncrementFlag(col.Flag) { - hasAutoIncID = true - break - } + is := ctx.GetSessionVars().TxnCtx.InfoSchema.(InfoSchema) + tbl, err := is.TableByName(schema.Name, tblInfo.Name) + if err != nil { + return 0, err } - autoIncID := tblInfo.AutoIncID - if hasAutoIncID { - is := ctx.GetSessionVars().TxnCtx.InfoSchema.(InfoSchema) - tbl, err := is.TableByName(schema.Name, tblInfo.Name) - if err != nil { - return 0, err - } - autoIncID, err = tbl.Allocator(ctx).NextGlobalAutoID(tblInfo.ID) - if err != nil { - return 0, err - } + autoIncID, err := tbl.Allocator(ctx).NextGlobalAutoID(tblInfo.ID) + if err != nil { + return 0, err } return autoIncID, nil } @@ -1162,10 +1152,21 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D if table.GetPartitionInfo() != nil { createOptions = "partitioned" } - autoIncID, err := getAutoIncrementID(ctx, schema, table) - if err != nil { - return nil, err + var autoIncID interface{} + hasAutoIncID := false + for _, col := range table.Cols() { + if mysql.HasAutoIncrementFlag(col.Flag) { + hasAutoIncID = true + break + } } + if hasAutoIncID { + autoIncID, err = getAutoIncrementID(ctx, schema, table) + if err != nil { + return nil, err + } + } + rowCount := tableRowsMap[table.ID] dataLength, indexLength := getDataAndIndexLength(table, rowCount, colLengthMap) avgRowLength := uint64(0) diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index ce102e67bc1a0..7159567ee4da6 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -86,6 +86,12 @@ func (s *testTableSuite) TestInfoschemaFieldValue(c *C) { tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( testkit.Rows("30002")) + // Test auto_increment for table without auto_increment column + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (d int)") + tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( + testkit.Rows("")) + tk.MustExec("create user xxx") tk.MustExec("flush privileges") From 141ba1a7f165a4fd4b62f179020bddcbd3f927cd Mon Sep 17 00:00:00 2001 From: crazycs Date: Wed, 24 Apr 2019 21:48:52 +0800 Subject: [PATCH 2/6] use memory base for auto_increment column value in INFORMATION_SCHEMA.TABLES --- infoschema/tables.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/infoschema/tables.go b/infoschema/tables.go index cb3e14ff6a09c..e4b462992541c 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1077,11 +1077,7 @@ func getAutoIncrementID(ctx sessionctx.Context, schema *model.DBInfo, tblInfo *m if err != nil { return 0, err } - autoIncID, err := tbl.Allocator(ctx).NextGlobalAutoID(tblInfo.ID) - if err != nil { - return 0, err - } - return autoIncID, nil + return tbl.Allocator(ctx).Base(), nil } func dataForViews(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.Datum, error) { From 0ebb3b1d528d300855a03443242ab96361059ac6 Mon Sep 17 00:00:00 2001 From: crazycs Date: Wed, 24 Apr 2019 22:00:22 +0800 Subject: [PATCH 3/6] fix test --- infoschema/tables_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 7159567ee4da6..61c5821896d74 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -81,10 +81,18 @@ func (s *testTableSuite) TestInfoschemaFieldValue(c *C) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (c int auto_increment primary key, d int)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( - testkit.Rows("1")) + testkit.Rows("0")) tk.MustExec("insert into t(c, d) values(1, 1)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( - testkit.Rows("30002")) + testkit.Rows("1")) + + tk.MustQuery("show create table t").Check( + testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `c` int(11) NOT NULL AUTO_INCREMENT,\n" + + " `d` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`c`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=30002")) // Test auto_increment for table without auto_increment column tk.MustExec("drop table if exists t") From e6fcbbb763ebadb2510cf95809f112650d0b92c5 Mon Sep 17 00:00:00 2001 From: crazycs520 Date: Fri, 19 Jul 2019 16:21:10 +0800 Subject: [PATCH 4/6] fix compatibility --- infoschema/tables.go | 2 +- infoschema/tables_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/infoschema/tables.go b/infoschema/tables.go index e4b462992541c..175cbd4bd8d39 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1077,7 +1077,7 @@ func getAutoIncrementID(ctx sessionctx.Context, schema *model.DBInfo, tblInfo *m if err != nil { return 0, err } - return tbl.Allocator(ctx).Base(), nil + return tbl.Allocator(ctx).Base() + 1, nil } func dataForViews(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.Datum, error) { diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 61c5821896d74..c8d4e20c43984 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -81,10 +81,10 @@ func (s *testTableSuite) TestInfoschemaFieldValue(c *C) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (c int auto_increment primary key, d int)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( - testkit.Rows("0")) + testkit.Rows("1")) tk.MustExec("insert into t(c, d) values(1, 1)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( - testkit.Rows("1")) + testkit.Rows("2")) tk.MustQuery("show create table t").Check( testkit.Rows("" + From ef2b5afdf8b8506474ba8f4426f2fe9f2cd66983 Mon Sep 17 00:00:00 2001 From: crazycs520 Date: Fri, 19 Jul 2019 16:36:25 +0800 Subject: [PATCH 5/6] address comment --- ddl/ddl_api.go | 9 --------- ddl/generated_column.go | 3 ++- infoschema/infoschema.go | 9 +++++++++ infoschema/tables.go | 8 +------- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 890d1a721a29c..a19b17b992e7f 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1702,15 +1702,6 @@ func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) err return nil } -func hasAutoIncrementColumn(tbInfo *model.TableInfo) (bool, string) { - for _, col := range tbInfo.Columns { - if mysql.HasAutoIncrementFlag(col.Flag) { - return true, col.Name.L - } - } - return false, "" -} - // isIgnorableSpec checks if the spec type is ignorable. // Some specs are parsed by ignored. This is for compatibility. func isIgnorableSpec(tp ast.AlterTableType) bool { diff --git a/ddl/generated_column.go b/ddl/generated_column.go index e9ee788ff033b..c0550a292efc3 100644 --- a/ddl/generated_column.go +++ b/ddl/generated_column.go @@ -18,6 +18,7 @@ import ( "github.com/pingcap/parser/ast" "github.com/pingcap/parser/model" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/table" ) @@ -238,7 +239,7 @@ func checkIndexOrStored(tbl table.Table, oldCol, newCol *table.Column) error { // checkAutoIncrementRef checks if an generated column depends on an auto-increment column and raises an error if so. // See https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html for details. func checkAutoIncrementRef(name string, dependencies map[string]struct{}, tbInfo *model.TableInfo) error { - exists, autoIncrementColumn := hasAutoIncrementColumn(tbInfo) + exists, autoIncrementColumn := infoschema.HasAutoIncrementColumn(tbInfo) if exists { if _, found := dependencies[autoIncrementColumn]; found { return ErrGeneratedColumnRefAutoInc.GenWithStackByArgs(name) diff --git a/infoschema/infoschema.go b/infoschema/infoschema.go index 7b0b5f612cae0..306e63158c724 100644 --- a/infoschema/infoschema.go +++ b/infoschema/infoschema.go @@ -388,3 +388,12 @@ func IsMemoryDB(dbName string) bool { } return false } + +func HasAutoIncrementColumn(tbInfo *model.TableInfo) (bool, string) { + for _, col := range tbInfo.Columns { + if mysql.HasAutoIncrementFlag(col.Flag) { + return true, col.Name.L + } + } + return false, "" +} diff --git a/infoschema/tables.go b/infoschema/tables.go index 175cbd4bd8d39..20386786579ca 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1149,13 +1149,7 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D createOptions = "partitioned" } var autoIncID interface{} - hasAutoIncID := false - for _, col := range table.Cols() { - if mysql.HasAutoIncrementFlag(col.Flag) { - hasAutoIncID = true - break - } - } + hasAutoIncID, _ := HasAutoIncrementColumn(table) if hasAutoIncID { autoIncID, err = getAutoIncrementID(ctx, schema, table) if err != nil { From 1dd4fa6d56d4b564df8ab40255a5a56f1eb4cb3e Mon Sep 17 00:00:00 2001 From: crazycs520 Date: Fri, 19 Jul 2019 16:41:28 +0800 Subject: [PATCH 6/6] add comment --- infoschema/infoschema.go | 1 + 1 file changed, 1 insertion(+) diff --git a/infoschema/infoschema.go b/infoschema/infoschema.go index 306e63158c724..9da6e2ee72dd0 100644 --- a/infoschema/infoschema.go +++ b/infoschema/infoschema.go @@ -389,6 +389,7 @@ func IsMemoryDB(dbName string) bool { return false } +// HasAutoIncrementColumn checks whether the table has auto_increment columns, if so, return true and the column name. func HasAutoIncrementColumn(tbInfo *model.TableInfo) (bool, string) { for _, col := range tbInfo.Columns { if mysql.HasAutoIncrementFlag(col.Flag) {