diff --git a/infoschema/tables.go b/infoschema/tables.go index 6c783272d8700..3da3a218420c8 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "net/http" "sort" + "strconv" "strings" "sync" "time" @@ -177,6 +178,7 @@ var tablesCols = []columnInfo{ {"CREATE_OPTIONS", mysql.TypeVarchar, 255, 0, nil, nil}, {"TABLE_COMMENT", mysql.TypeVarchar, 2048, 0, nil, nil}, {"TIDB_TABLE_ID", mysql.TypeLonglong, 21, 0, nil, nil}, + {"TIDB_ROW_ID_SHARDING_INFO", mysql.TypeVarchar, 255, 0, nil, nil}, } // See: http://dev.mysql.com/doc/refman/5.7/en/columns-table.html @@ -1303,6 +1305,8 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D if rowCount != 0 { avgRowLength = dataLength / rowCount } + + shardingInfo := GetShardingInfo(schema, table) record := types.MakeDatums( catalogVal, // TABLE_CATALOG schema.Name.O, // TABLE_SCHEMA @@ -1326,6 +1330,7 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D createOptions, // CREATE_OPTIONS table.Comment, // TABLE_COMMENT table.ID, // TIDB_TABLE_ID + shardingInfo, // TIDB_ROW_ID_SHARDING_INFO ) rows = append(rows, record) } else { @@ -1352,6 +1357,7 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D nil, // CREATE_OPTIONS "VIEW", // TABLE_COMMENT table.ID, // TIDB_TABLE_ID + nil, // TIDB_ROW_ID_SHARDING_INFO ) rows = append(rows, record) } @@ -1360,6 +1366,28 @@ func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.D return rows, nil } +// GetShardingInfo returns a nil or description string for the sharding information of given TableInfo. +// The returned description string may be: +// - "NOT_SHARDED": for tables that SHARD_ROW_ID_BITS is not specified. +// - "NOT_SHARDED(PK_IS_HANDLE)": for tables that is primary key is row id. +// - "SHARD_BITS={bit_number}": for tables that with SHARD_ROW_ID_BITS. +// The returned nil indicates that sharding information is not suitable for the table(for example, when the table is a View). +// This function is exported for unit test. +func GetShardingInfo(dbInfo *model.DBInfo, tableInfo *model.TableInfo) interface{} { + if dbInfo == nil || tableInfo == nil || tableInfo.IsView() || util.IsMemOrSysDB(dbInfo.Name.L) { + return nil + } + shardingInfo := "NOT_SHARDED" + if tableInfo.PKIsHandle { + shardingInfo = "NOT_SHARDED(PK_IS_HANDLE)" + } else { + if tableInfo.ShardRowIDBits > 0 { + shardingInfo = "SHARD_BITS=" + strconv.Itoa(int(tableInfo.ShardRowIDBits)) + } + } + return shardingInfo +} + func dataForIndexes(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.Datum, error) { checker := privilege.GetPrivilegeManager(ctx) var rows [][]types.Datum diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index c342bf86ca924..5fb68e429a3e5 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -463,6 +463,48 @@ func (s *testTableSuite) TestTableIDAndIndexID(c *C) { tk.MustQuery("select * from information_schema.tidb_indexes where table_schema = 'test' and table_name = 't'").Check(testkit.Rows("test t 0 PRIMARY 1 a 0", "test t 1 k1 1 b 1")) } +func (s *testTableSuite) TestTableRowIDShardingInfo(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("DROP DATABASE IF EXISTS `sharding_info_test_db`") + tk.MustExec("CREATE DATABASE `sharding_info_test_db`") + + assertShardingInfo := func(tableName string, expectInfo interface{}) { + querySQL := fmt.Sprintf("select tidb_row_id_sharding_info from information_schema.tables where table_schema = 'sharding_info_test_db' and table_name = '%s'", tableName) + info := tk.MustQuery(querySQL).Rows()[0][0] + if expectInfo == nil { + c.Assert(info, Equals, "") + } else { + c.Assert(info, Equals, expectInfo) + } + } + tk.MustExec("CREATE TABLE `sharding_info_test_db`.`t1` (a int)") + assertShardingInfo("t1", "NOT_SHARDED") + + tk.MustExec("CREATE TABLE `sharding_info_test_db`.`t2` (a int key)") + assertShardingInfo("t2", "NOT_SHARDED(PK_IS_HANDLE)") + + tk.MustExec("CREATE TABLE `sharding_info_test_db`.`t3` (a int) SHARD_ROW_ID_BITS=4") + assertShardingInfo("t3", "SHARD_BITS=4") + + tk.MustExec("CREATE VIEW `sharding_info_test_db`.`tv` AS select 1") + assertShardingInfo("tv", nil) + + testFunc := func(dbName string, expectInfo interface{}) { + dbInfo := model.DBInfo{Name: model.NewCIStr(dbName)} + tableInfo := model.TableInfo{} + + info := infoschema.GetShardingInfo(&dbInfo, &tableInfo) + c.Assert(info, Equals, expectInfo) + } + + testFunc("information_schema", nil) + testFunc("mysql", nil) + testFunc("performance_schema", nil) + testFunc("uucc", "NOT_SHARDED") + + tk.MustExec("DROP DATABASE `sharding_info_test_db`") +} + func (s *testTableSuite) TestSlowQuery(c *C) { tk := testkit.NewTestKit(c, s.store) // Prepare slow log file.