From 7fd3437fcce4e2e2e83f5d43f6683e95f6da2312 Mon Sep 17 00:00:00 2001 From: Rustin-Liu Date: Mon, 9 Mar 2020 20:16:14 +0800 Subject: [PATCH 1/2] executor,infoschema: move `dataForTableConstraints` from `infoschema` to `executor` Signed-off-by: Rustin-Liu --- executor/builder.go | 3 +- executor/infoschema_reader.go | 91 ++++++++++++++++++++++++------ executor/infoschema_reader_test.go | 5 ++ infoschema/tables.go | 73 +++--------------------- infoschema/tables_test.go | 1 - 5 files changed, 89 insertions(+), 84 deletions(-) diff --git a/executor/builder.go b/executor/builder.go index e513c68bec230..e59665e600af7 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -1417,7 +1417,8 @@ func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) Executo strings.ToLower(infoschema.TableCharacterSets), strings.ToLower(infoschema.TableKeyColumn), strings.ToLower(infoschema.TableUserPrivileges), - strings.ToLower(infoschema.TableCollationCharacterSetApplicability): + strings.ToLower(infoschema.TableCollationCharacterSetApplicability), + strings.ToLower(infoschema.TableConstraints): return &MemTableReaderExec{ baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()), retriever: &memtableRetriever{ diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index 99a37bdd101fb..99d7b767fa358 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -32,6 +32,12 @@ import ( "github.com/pingcap/tidb/util/sqlexec" ) +const ( + primaryKeyType = "PRIMARY KEY" + primaryConstraint = "PRIMARY" + uniqueKeyType = "UNIQUE" +) + type memtableRetriever struct { dummyCloser table *model.TableInfo @@ -58,9 +64,9 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex case infoschema.TableSchemata: e.setDataFromSchemata(sctx, dbs) case infoschema.TableTables: - err = e.dataForTables(sctx, dbs) + err = e.setDataFromTables(sctx, dbs) case infoschema.TablePartitions: - err = e.dataForPartitions(sctx, dbs) + err = e.setDataFromPartitions(sctx, dbs) case infoschema.TableTiDBIndexes: e.setDataFromIndexes(sctx, dbs) case infoschema.TableViews: @@ -77,6 +83,8 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex e.dataForCollationCharacterSetApplicability() case infoschema.TableUserPrivileges: e.setDataFromUserPrivileges(sctx) + case infoschema.TableConstraints: + e.setDataFromTableConstraints(sctx, dbs) } if err != nil { return nil, err @@ -270,7 +278,7 @@ func (e *memtableRetriever) setDataFromSchemata(ctx sessionctx.Context, schemas e.rows = rows } -func (e *memtableRetriever) dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) error { +func (e *memtableRetriever) setDataFromTables(ctx sessionctx.Context, schemas []*model.DBInfo) error { tableRowsMap, colLengthMap, err := tableStatsCache.get(ctx) if err != nil { return err @@ -392,7 +400,7 @@ func (e *memtableRetriever) dataForTables(ctx sessionctx.Context, schemas []*mod return nil } -func (e *memtableRetriever) dataForPartitions(ctx sessionctx.Context, schemas []*model.DBInfo) error { +func (e *memtableRetriever) setDataFromPartitions(ctx sessionctx.Context, schemas []*model.DBInfo) error { tableRowsMap, colLengthMap, err := tableStatsCache.get(ctx) if err != nil { return err @@ -680,18 +688,18 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ for _, col := range table.Columns { if mysql.HasPriKeyFlag(col.Flag) { record := types.MakeDatums( - infoschema.CatalogVal, // CONSTRAINT_CATALOG - schema.Name.O, // CONSTRAINT_SCHEMA - infoschema.PrimaryConstraint, // CONSTRAINT_NAME - infoschema.CatalogVal, // TABLE_CATALOG - schema.Name.O, // TABLE_SCHEMA - table.Name.O, // TABLE_NAME - col.Name.O, // COLUMN_NAME - 1, // ORDINAL_POSITION - 1, // POSITION_IN_UNIQUE_CONSTRAINT - nil, // REFERENCED_TABLE_SCHEMA - nil, // REFERENCED_TABLE_NAME - nil, // REFERENCED_COLUMN_NAME + infoschema.CatalogVal, // CONSTRAINT_CATALOG + schema.Name.O, // CONSTRAINT_SCHEMA + primaryConstraint, // CONSTRAINT_NAME + infoschema.CatalogVal, // TABLE_CATALOG + schema.Name.O, // TABLE_SCHEMA + table.Name.O, // TABLE_NAME + col.Name.O, // COLUMN_NAME + 1, // ORDINAL_POSITION + 1, // POSITION_IN_UNIQUE_CONSTRAINT + nil, // REFERENCED_TABLE_SCHEMA + nil, // REFERENCED_TABLE_NAME + nil, // REFERENCED_COLUMN_NAME ) rows = append(rows, record) break @@ -705,7 +713,7 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ for _, index := range table.Indices { var idxName string if index.Primary { - idxName = infoschema.PrimaryConstraint + idxName = primaryConstraint } else if index.Unique { idxName = index.Name.O } else { @@ -757,3 +765,52 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ } return rows } + +// setDataFromTableConstraints constructs data for table information_schema.constraints.See https://dev.mysql.com/doc/refman/5.7/en/table-constraints-table.html +func (e *memtableRetriever) setDataFromTableConstraints(ctx sessionctx.Context, schemas []*model.DBInfo) { + checker := privilege.GetPrivilegeManager(ctx) + var rows [][]types.Datum + for _, schema := range schemas { + for _, tbl := range schema.Tables { + if checker != nil && !checker.RequestVerification(ctx.GetSessionVars().ActiveRoles, schema.Name.L, tbl.Name.L, "", mysql.AllPrivMask) { + continue + } + + if tbl.PKIsHandle { + record := types.MakeDatums( + infoschema.CatalogVal, // CONSTRAINT_CATALOG + schema.Name.O, // CONSTRAINT_SCHEMA + mysql.PrimaryKeyName, // CONSTRAINT_NAME + schema.Name.O, // TABLE_SCHEMA + tbl.Name.O, // TABLE_NAME + primaryKeyType, // CONSTRAINT_TYPE + ) + rows = append(rows, record) + } + + for _, idx := range tbl.Indices { + var cname, ctype string + if idx.Primary { + cname = mysql.PrimaryKeyName + ctype = primaryKeyType + } else if idx.Unique { + cname = idx.Name.O + ctype = uniqueKeyType + } else { + // The index has no constriant. + continue + } + record := types.MakeDatums( + infoschema.CatalogVal, // CONSTRAINT_CATALOG + schema.Name.O, // CONSTRAINT_SCHEMA + cname, // CONSTRAINT_NAME + schema.Name.O, // TABLE_SCHEMA + tbl.Name.O, // TABLE_NAME + ctype, // CONSTRAINT_TYPE + ) + rows = append(rows, record) + } + } + } + e.rows = rows +} diff --git a/executor/infoschema_reader_test.go b/executor/infoschema_reader_test.go index baa6cc5b14a5b..73ac78e59e43e 100644 --- a/executor/infoschema_reader_test.go +++ b/executor/infoschema_reader_test.go @@ -309,3 +309,8 @@ func (s *testInfoschemaTableSuite) TestPartitionsTable(c *C) { tk.MustExec("DROP TABLE `test_partitions`;") } + +func (s *testInfoschemaTableSuite) TestTableConstraintsTable(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Check(testkit.Rows("def mysql delete_range_index mysql gc_delete_range UNIQUE")) +} diff --git a/infoschema/tables.go b/infoschema/tables.go index cbd7281dd0760..046eff8cb633a 100755 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -67,11 +67,12 @@ const ( // TablePartitions is the string constant of infoschema table TablePartitions = "PARTITIONS" // TableKeyColumn is the string constant of KEY_COLUMN_USAGE - TableKeyColumn = "KEY_COLUMN_USAGE" - tableReferConst = "REFERENTIAL_CONSTRAINTS" - tableSessionVar = "SESSION_VARIABLES" - tablePlugins = "PLUGINS" - tableConstraints = "TABLE_CONSTRAINTS" + TableKeyColumn = "KEY_COLUMN_USAGE" + tableReferConst = "REFERENTIAL_CONSTRAINTS" + tableSessionVar = "SESSION_VARIABLES" + tablePlugins = "PLUGINS" + // TableConstraints is the string constant of TABLE_CONSTRAINTS. + TableConstraints = "TABLE_CONSTRAINTS" tableTriggers = "TRIGGERS" // TableUserPrivileges is the string constant of infoschema user privilege table. TableUserPrivileges = "USER_PRIVILEGES" @@ -146,7 +147,7 @@ var tableIDMap = map[string]int64{ tableReferConst: autoid.InformationSchemaDBID + 13, tableSessionVar: autoid.InformationSchemaDBID + 14, tablePlugins: autoid.InformationSchemaDBID + 15, - tableConstraints: autoid.InformationSchemaDBID + 16, + TableConstraints: autoid.InformationSchemaDBID + 16, tableTriggers: autoid.InformationSchemaDBID + 17, TableUserPrivileges: autoid.InformationSchemaDBID + 18, tableSchemaPrivileges: autoid.InformationSchemaDBID + 19, @@ -1407,62 +1408,6 @@ func dataForStatisticsInTable(schema *model.DBInfo, table *model.TableInfo) [][] return rows } -const ( - primaryKeyType = "PRIMARY KEY" - // PrimaryConstraint is the string constant of PRIMARY - PrimaryConstraint = "PRIMARY" - uniqueKeyType = "UNIQUE" -) - -// dataForTableConstraints constructs data for table information_schema.constraints.See https://dev.mysql.com/doc/refman/5.7/en/table-constraints-table.html -func dataForTableConstraints(ctx sessionctx.Context, schemas []*model.DBInfo) [][]types.Datum { - checker := privilege.GetPrivilegeManager(ctx) - var rows [][]types.Datum - for _, schema := range schemas { - for _, tbl := range schema.Tables { - if checker != nil && !checker.RequestVerification(ctx.GetSessionVars().ActiveRoles, schema.Name.L, tbl.Name.L, "", mysql.AllPrivMask) { - continue - } - - if tbl.PKIsHandle { - record := types.MakeDatums( - CatalogVal, // CONSTRAINT_CATALOG - schema.Name.O, // CONSTRAINT_SCHEMA - mysql.PrimaryKeyName, // CONSTRAINT_NAME - schema.Name.O, // TABLE_SCHEMA - tbl.Name.O, // TABLE_NAME - primaryKeyType, // CONSTRAINT_TYPE - ) - rows = append(rows, record) - } - - for _, idx := range tbl.Indices { - var cname, ctype string - if idx.Primary { - cname = mysql.PrimaryKeyName - ctype = primaryKeyType - } else if idx.Unique { - cname = idx.Name.O - ctype = uniqueKeyType - } else { - // The index has no constriant. - continue - } - record := types.MakeDatums( - CatalogVal, // CONSTRAINT_CATALOG - schema.Name.O, // CONSTRAINT_SCHEMA - cname, // CONSTRAINT_NAME - schema.Name.O, // TABLE_SCHEMA - tbl.Name.O, // TABLE_NAME - ctype, // CONSTRAINT_TYPE - ) - rows = append(rows, record) - } - } - } - return rows -} - // dataForPseudoProfiling returns pseudo data for table profiling when system variable `profiling` is set to `ON`. func dataForPseudoProfiling() [][]types.Datum { var rows [][]types.Datum @@ -1851,7 +1796,7 @@ var tableNameToColumns = map[string][]columnInfo{ tableReferConst: referConstCols, tableSessionVar: sessionVarCols, tablePlugins: pluginsCols, - tableConstraints: tableConstraintsCols, + TableConstraints: tableConstraintsCols, tableTriggers: tableTriggersCols, TableUserPrivileges: tableUserPrivilegesCols, tableSchemaPrivileges: tableSchemaPrivilegesCols, @@ -1936,8 +1881,6 @@ func (it *infoschemaTable) getRows(ctx sessionctx.Context, cols []*table.Column) fullRows = dataForStatistics(ctx, dbs) case tableSessionVar: fullRows, err = dataForSessionVar(ctx) - case tableConstraints: - fullRows = dataForTableConstraints(ctx, dbs) case tableFiles: case tableProfiling: if v, ok := ctx.GetSessionVars().GetSystemVar("profiling"); ok && variable.TiDBOptOn(v) { diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 1260ff446f265..631dcbb1ad3ae 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -424,7 +424,6 @@ func (s *testTableSuite) TestSomeTables(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustQuery("select * from information_schema.SESSION_VARIABLES where VARIABLE_NAME='tidb_retry_limit';").Check(testkit.Rows("tidb_retry_limit 10")) - tk.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Check(testkit.Rows("def mysql delete_range_index mysql gc_delete_range UNIQUE")) sm := &mockSessionManager{make(map[uint64]*util.ProcessInfo, 2)} sm.processInfoMap[1] = &util.ProcessInfo{ From c00c94679f483481dccefa3582b0d193131d9ff8 Mon Sep 17 00:00:00 2001 From: Rustin-Liu Date: Tue, 10 Mar 2020 09:07:33 +0800 Subject: [PATCH 2/2] executor,infoschema: move const into tables Signed-off-by: Rustin-Liu --- executor/infoschema_reader.go | 48 +++++++++++++++-------------------- infoschema/tables.go | 9 +++++++ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index 99d7b767fa358..a54b25956e839 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -32,12 +32,6 @@ import ( "github.com/pingcap/tidb/util/sqlexec" ) -const ( - primaryKeyType = "PRIMARY KEY" - primaryConstraint = "PRIMARY" - uniqueKeyType = "UNIQUE" -) - type memtableRetriever struct { dummyCloser table *model.TableInfo @@ -688,18 +682,18 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ for _, col := range table.Columns { if mysql.HasPriKeyFlag(col.Flag) { record := types.MakeDatums( - infoschema.CatalogVal, // CONSTRAINT_CATALOG - schema.Name.O, // CONSTRAINT_SCHEMA - primaryConstraint, // CONSTRAINT_NAME - infoschema.CatalogVal, // TABLE_CATALOG - schema.Name.O, // TABLE_SCHEMA - table.Name.O, // TABLE_NAME - col.Name.O, // COLUMN_NAME - 1, // ORDINAL_POSITION - 1, // POSITION_IN_UNIQUE_CONSTRAINT - nil, // REFERENCED_TABLE_SCHEMA - nil, // REFERENCED_TABLE_NAME - nil, // REFERENCED_COLUMN_NAME + infoschema.CatalogVal, // CONSTRAINT_CATALOG + schema.Name.O, // CONSTRAINT_SCHEMA + infoschema.PrimaryConstraint, // CONSTRAINT_NAME + infoschema.CatalogVal, // TABLE_CATALOG + schema.Name.O, // TABLE_SCHEMA + table.Name.O, // TABLE_NAME + col.Name.O, // COLUMN_NAME + 1, // ORDINAL_POSITION + 1, // POSITION_IN_UNIQUE_CONSTRAINT + nil, // REFERENCED_TABLE_SCHEMA + nil, // REFERENCED_TABLE_NAME + nil, // REFERENCED_COLUMN_NAME ) rows = append(rows, record) break @@ -713,7 +707,7 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ for _, index := range table.Indices { var idxName string if index.Primary { - idxName = primaryConstraint + idxName = infoschema.PrimaryConstraint } else if index.Unique { idxName = index.Name.O } else { @@ -778,12 +772,12 @@ func (e *memtableRetriever) setDataFromTableConstraints(ctx sessionctx.Context, if tbl.PKIsHandle { record := types.MakeDatums( - infoschema.CatalogVal, // CONSTRAINT_CATALOG - schema.Name.O, // CONSTRAINT_SCHEMA - mysql.PrimaryKeyName, // CONSTRAINT_NAME - schema.Name.O, // TABLE_SCHEMA - tbl.Name.O, // TABLE_NAME - primaryKeyType, // CONSTRAINT_TYPE + infoschema.CatalogVal, // CONSTRAINT_CATALOG + schema.Name.O, // CONSTRAINT_SCHEMA + mysql.PrimaryKeyName, // CONSTRAINT_NAME + schema.Name.O, // TABLE_SCHEMA + tbl.Name.O, // TABLE_NAME + infoschema.PrimaryKeyType, // CONSTRAINT_TYPE ) rows = append(rows, record) } @@ -792,10 +786,10 @@ func (e *memtableRetriever) setDataFromTableConstraints(ctx sessionctx.Context, var cname, ctype string if idx.Primary { cname = mysql.PrimaryKeyName - ctype = primaryKeyType + ctype = infoschema.PrimaryKeyType } else if idx.Unique { cname = idx.Name.O - ctype = uniqueKeyType + ctype = infoschema.UniqueKeyType } else { // The index has no constriant. continue diff --git a/infoschema/tables.go b/infoschema/tables.go index 046eff8cb633a..5067a7e325402 100755 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1408,6 +1408,15 @@ func dataForStatisticsInTable(schema *model.DBInfo, table *model.TableInfo) [][] return rows } +const ( + // PrimaryKeyType is the string constant of PRIMARY KEY. + PrimaryKeyType = "PRIMARY KEY" + // PrimaryConstraint is the string constant of PRIMARY. + PrimaryConstraint = "PRIMARY" + // UniqueKeyType is the string constant of UNIQUE. + UniqueKeyType = "UNIQUE" +) + // dataForPseudoProfiling returns pseudo data for table profiling when system variable `profiling` is set to `ON`. func dataForPseudoProfiling() [][]types.Datum { var rows [][]types.Datum