Skip to content

Commit

Permalink
*: support SHOW TABLE STATUS with case insensitivity (#35086)
Browse files Browse the repository at this point in the history
close #7518
  • Loading branch information
likzn authored Jun 1, 2022
1 parent 69b573c commit c133e74
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 208 deletions.
80 changes: 33 additions & 47 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,25 +404,19 @@ func (e *ShowExec) fetchShowDatabases() error {
sort.Strings(dbs)
var (
fieldPatternsLike collate.WildcardPattern
FieldFilterEnable bool
fieldFilter string
)

if e.Extractor != nil {
extractor := (e.Extractor).(*plannercore.ShowDatabaseExtractor)
if extractor.FieldPatterns != "" {
fieldPatternsLike = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
fieldPatternsLike.Compile(extractor.FieldPatterns, byte('\\'))
}
FieldFilterEnable = extractor.Field != ""
fieldFilter = extractor.Field
fieldFilter = e.Extractor.Field()
fieldPatternsLike = e.Extractor.FieldPatternLike()
}
// let information_schema be the first database
moveInfoSchemaToFront(dbs)
for _, d := range dbs {
if checker != nil && !checker.DBIsVisible(e.ctx.GetSessionVars().ActiveRoles, d) {
continue
} else if FieldFilterEnable && strings.ToLower(d) != fieldFilter {
} else if fieldFilter != "" && strings.ToLower(d) != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(strings.ToLower(d)) {
continue
Expand Down Expand Up @@ -484,24 +478,19 @@ func (e *ShowExec) fetchShowTables() error {
var (
tableTypes = make(map[string]string)
fieldPatternsLike collate.WildcardPattern
FieldFilterEnable bool
fieldFilter string
)

if e.Extractor != nil {
extractor := (e.Extractor).(*plannercore.ShowTablesTableExtractor)
if extractor.FieldPatterns != "" {
fieldPatternsLike = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
fieldPatternsLike.Compile(extractor.FieldPatterns, byte('\\'))
}
FieldFilterEnable = extractor.Field != ""
fieldFilter = extractor.Field
fieldFilter = e.Extractor.Field()
fieldPatternsLike = e.Extractor.FieldPatternLike()
}
for _, v := range schemaTables {
// Test with mysql.AllPrivMask means any privilege would be OK.
// TODO: Should consider column privileges, which also make a table visible.
if checker != nil && !checker.RequestVerification(activeRoles, e.DBName.O, v.Meta().Name.O, "", mysql.AllPrivMask) {
continue
} else if FieldFilterEnable && v.Meta().Name.L != fieldFilter {
} else if fieldFilter != "" && v.Meta().Name.L != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(v.Meta().Name.L) {
continue
Expand Down Expand Up @@ -563,10 +552,23 @@ func (e *ShowExec) fetchShowTableStatus(ctx context.Context) error {
if err != nil {
return errors.Trace(err)
}
var (
fieldPatternsLike collate.WildcardPattern
fieldFilter string
)

if e.Extractor != nil {
fieldFilter = e.Extractor.Field()
fieldPatternsLike = e.Extractor.FieldPatternLike()
}
activeRoles := e.ctx.GetSessionVars().ActiveRoles
for _, row := range rows {
if checker != nil && !checker.RequestVerification(activeRoles, e.DBName.O, row.GetString(0), "", mysql.AllPrivMask) {
tableName := row.GetString(0)
if checker != nil && !checker.RequestVerification(activeRoles, e.DBName.O, tableName, "", mysql.AllPrivMask) {
continue
} else if fieldFilter != "" && strings.ToLower(tableName) != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(strings.ToLower(tableName)) {
continue
}
e.result.AppendRow(row)
Expand All @@ -582,17 +584,12 @@ func (e *ShowExec) fetchShowColumns(ctx context.Context) error {
}
var (
fieldPatternsLike collate.WildcardPattern
FieldFilterEnable bool
fieldFilter string
)

if e.Extractor != nil {
extractor := (e.Extractor).(*plannercore.ShowColumnsTableExtractor)
if extractor.FieldPatterns != "" {
fieldPatternsLike = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
fieldPatternsLike.Compile(extractor.FieldPatterns, byte('\\'))
}
FieldFilterEnable = extractor.Field != ""
fieldFilter = extractor.Field
fieldFilter = e.Extractor.Field()
fieldPatternsLike = e.Extractor.FieldPatternLike()
}

checker := privilege.GetPrivilegeManager(e.ctx)
Expand All @@ -613,7 +610,7 @@ func (e *ShowExec) fetchShowColumns(ctx context.Context) error {
return err
}
for _, col := range cols {
if FieldFilterEnable && col.Name.L != fieldFilter {
if fieldFilter != "" && col.Name.L != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(col.Name.L) {
continue
Expand Down Expand Up @@ -806,17 +803,12 @@ func (e *ShowExec) fetchShowVariables() (err error) {
)
var (
fieldPatternsLike collate.WildcardPattern
FieldFilterEnable bool
fieldFilter string
)

if e.Extractor != nil {
extractor := (e.Extractor).(*plannercore.ShowVariablesExtractor)
if extractor.FieldPatterns != "" {
fieldPatternsLike = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
fieldPatternsLike.Compile(extractor.FieldPatterns, byte('\\'))
}
FieldFilterEnable = extractor.Field != ""
fieldFilter = extractor.Field
fieldFilter = e.Extractor.Field()
fieldPatternsLike = e.Extractor.FieldPatternLike()
}
if e.GlobalScope {
// Collect global scope variables,
Expand All @@ -825,7 +817,7 @@ func (e *ShowExec) fetchShowVariables() (err error) {
// otherwise, fetch the value from table `mysql.Global_Variables`.
for _, v := range variable.GetSysVars() {
if v.Scope != variable.ScopeSession {
if FieldFilterEnable && v.Name != fieldFilter {
if fieldFilter != "" && v.Name != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(v.Name) {
continue
Expand All @@ -847,7 +839,7 @@ func (e *ShowExec) fetchShowVariables() (err error) {
// If it is a session only variable, use the default value defined in code,
// otherwise, fetch the value from table `mysql.Global_Variables`.
for _, v := range variable.GetSysVars() {
if FieldFilterEnable && v.Name != fieldFilter {
if fieldFilter != "" && v.Name != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(v.Name) {
continue
Expand Down Expand Up @@ -1476,17 +1468,11 @@ func (e *ShowExec) fetchShowCreatePlacementPolicy() error {
func (e *ShowExec) fetchShowCollation() error {
var (
fieldPatternsLike collate.WildcardPattern
FieldFilterEnable bool
fieldFilter string
)
if e.Extractor != nil {
extractor := (e.Extractor).(*plannercore.ShowCollationExtractor)
if extractor.FieldPatterns != "" {
fieldPatternsLike = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
fieldPatternsLike.Compile(extractor.FieldPatterns, byte('\\'))
}
FieldFilterEnable = extractor.Field != ""
fieldFilter = extractor.Field
fieldPatternsLike = e.Extractor.FieldPatternLike()
fieldFilter = e.Extractor.Field()
}

collations := collate.GetSupportedCollations()
Expand All @@ -1495,7 +1481,7 @@ func (e *ShowExec) fetchShowCollation() error {
if v.IsDefault {
isDefault = "Yes"
}
if FieldFilterEnable && strings.ToLower(v.Name) != fieldFilter {
if fieldFilter != "" && strings.ToLower(v.Name) != fieldFilter {
continue
} else if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(v.Name) {
continue
Expand Down
23 changes: 23 additions & 0 deletions executor/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,29 @@ func TestShowDatabasesLike(t *testing.T) {
tk.MustQuery("SHOW DATABASES LIKE 'test_%'").Check(testkit.Rows("TEST_$1", "test_$2"))
}

func TestShowTableStatusLike(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("DROP table IF EXISTS `T1`")
tk.MustExec("CREATE table `T1` (a int);")
rows := tk.MustQuery("SHOW table status LIKE 't1'").Rows()
require.Equal(t, "T1", rows[0][0])

tk.MustExec("DROP table IF EXISTS `Li_1`")
tk.MustExec("DROP table IF EXISTS `li_2`")

tk.MustExec("CREATE table `Li_1` (a int);")
tk.MustExec("CREATE table `li_2` (a int);")

rows = tk.MustQuery("SHOW table status LIKE 'li%'").Rows()
require.Equal(t, "Li_1", rows[0][0])
require.Equal(t, "li_2", rows[1][0])

}

func TestShowCollationsLike(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
Expand Down
43 changes: 6 additions & 37 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2933,27 +2933,16 @@ func (b *PlanBuilder) buildShow(ctx context.Context, show *ast.ShowStmt) (Plan,
isSequence := false

switch show.Tp {
case ast.ShowColumns:
var extractor ShowColumnsTableExtractor
if extractor.Extract(show) {
p.Extractor = &extractor
// avoid to build Selection.
show.Pattern = nil
}
case ast.ShowTables:
if p.DBName == "" {
case ast.ShowDatabases, ast.ShowVariables, ast.ShowTables, ast.ShowColumns, ast.ShowTableStatus, ast.ShowCollation:
if (show.Tp == ast.ShowTables || show.Tp == ast.ShowTableStatus) && p.DBName == "" {
return nil, ErrNoDB
}
var extractor ShowTablesTableExtractor
if extractor.Extract(show) {
p.Extractor = &extractor
extractor := newShowBaseExtractor(*show)
if extractor.Extract() {
p.Extractor = extractor
// Avoid building Selection.
show.Pattern = nil
}
case ast.ShowTableStatus:
if p.DBName == "" {
return nil, ErrNoDB
}
case ast.ShowCreateTable, ast.ShowCreateSequence, ast.ShowPlacementForTable, ast.ShowPlacementForPartition:
var err error
if table, err := b.is.TableByName(show.Table.Schema, show.Table.Name); err == nil {
Expand Down Expand Up @@ -3012,28 +3001,8 @@ func (b *PlanBuilder) buildShow(ctx context.Context, show *ast.ShowStmt) (Plan,
if tableInfo.Meta().TempTableType != model.TempTableNone {
return nil, ErrOptOnTemporaryTable.GenWithStackByArgs("show table regions")
}
case ast.ShowDatabases:
var extractor ShowDatabaseExtractor
if extractor.Extract(show) {
p.Extractor = &extractor
// Avoid building Selection.
show.Pattern = nil
}
case ast.ShowCollation:
var extractor ShowCollationExtractor
if extractor.Extract(show) {
p.Extractor = &extractor
show.Pattern = nil
}
}
if show.Tp == ast.ShowVariables {
var extractor ShowVariablesExtractor
if extractor.Extract(show) {
p.Extractor = &extractor
// Avoid building Selection.
show.Pattern = nil
}
}

schema, names := buildShowSchema(show, isView, isSequence)
p.SetSchema(schema)
p.names = names
Expand Down
Loading

0 comments on commit c133e74

Please sign in to comment.