Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: make pattern match case-insensitive for some infoschema tables #56378

Merged
merged 2 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/parser/mysql/charset.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ const (
BinaryDefaultCollationID = 63
UTF8MB4DefaultCollation = "utf8mb4_bin"
DefaultCollationName = UTF8MB4DefaultCollation
UTF8MB4GeneralCICollation = "utf8mb4_general_ci"

// MaxBytesOfCharacter, is the max bytes length of a character,
// refer to RFC3629, in UTF-8, characters from the U+0000..U+10FFFF range
Expand Down
34 changes: 33 additions & 1 deletion pkg/planner/core/memtable_infoschema_extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,15 @@ func (e *InfoSchemaBaseExtractor) Extract(
}
var likePatterns []string
remained, likePatterns = e.extractLikePatternCol(ctx, schema, names, remained, colName, true, false)
if len(likePatterns) == 0 {
continue
}
regexp := make([]collate.WildcardPattern, len(likePatterns))
for i, pattern := range likePatterns {
regexp[i] = collate.GetCollatorByID(collate.CollationName2ID(mysql.UTF8MB4DefaultCollation)).Pattern()
// Because @@lower_case_table_names is always 2 in TiDB,
// schema object names comparison should be case insensitive.
ciCollateID := collate.CollationName2ID(mysql.UTF8MB4GeneralCICollation)
regexp[i] = collate.GetCollatorByID(ciCollateID).Pattern()
regexp[i].Compile(pattern, byte('\\'))
}
e.LikePatterns[colName] = likePatterns
Expand Down Expand Up @@ -249,6 +255,11 @@ func (e *InfoSchemaBaseExtractor) filter(colName string, val string) bool {
if e.SkipRequest {
return true
}
for _, re := range e.colsRegexp[colName] {
if !re.DoMatch(val) {
return true
}
}
predVals, ok := e.ColPredicates[colName]
if ok && len(predVals) > 0 {
fn, ok := e.pushedDownFuncs[colName]
Expand Down Expand Up @@ -661,6 +672,15 @@ func findTableAndSchemaByName(
schemaSlice = append(schemaSlice, st.schema)
tableSlice = append(tableSlice, st.table)
}
sort.Slice(schemaSlice, func(i, j int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need to sort by schema name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iSchema, jSchema := schemaSlice[i].L, schemaSlice[j].L
less := iSchema < jSchema ||
(iSchema == jSchema && tableSlice[i].Name.L < tableSlice[j].Name.L)
if less {
tableSlice[i], tableSlice[j] = tableSlice[j], tableSlice[i]
}
return less
})
return schemaSlice, tableSlice, nil
}

Expand All @@ -687,6 +707,9 @@ func listTablesForEachSchema(
return schemaSlice, tableSlice, nil
}

// findSchemasForTables finds a schema for each tableInfo, and it
// returns a schema slice and a table slice that has the same length.
// Note that input arg "tableSlice" will be changed in place.
func findSchemasForTables(
ctx context.Context,
is infoschema.InfoSchema,
Expand Down Expand Up @@ -721,6 +744,15 @@ func findSchemasForTables(
remains = append(remains, tbl)
}
}
sort.Slice(schemaSlice, func(i, j int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create a new slice to store tables instead of directly modifing input slice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input slice is not used by anyone else. Let me add some comments for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iSchema, jSchema := schemaSlice[i].L, schemaSlice[j].L
less := iSchema < jSchema ||
(iSchema == jSchema && remains[i].Name.L < remains[j].Name.L)
if less {
remains[i], remains[j] = remains[j], remains[i]
}
return less
})
return schemaSlice, remains, nil
}

Expand Down
11 changes: 11 additions & 0 deletions tests/integrationtest/r/infoschema/infoschema.result
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ engine DATA_LENGTH
InnoDB 8
drop table infoschema__infoschema.t4;
drop table infoschema__infoschema.t5;
create table caseSensitive (a int);
create table unrelatedTable (a int);
select table_schema, table_name from information_schema.tables where table_schema = 'infoschema__infoschema' and table_name like '%aseSensitive';
table_schema table_name
infoschema__infoschema caseSensitive
select table_schema, table_name, tidb_pk_type from information_schema.tables where table_schema = 'infoschema__infoschema' and table_name like '%aseSensitive';
table_schema table_name tidb_pk_type
infoschema__infoschema caseSensitive NONCLUSTERED
drop table caseSensitive;
drop table unrelatedTable;
create table pt1(a int primary key, b int) partition by hash(a) partitions 4;
create table pt2(a int primary key, b int) partition by hash(a) partitions 4;
select TABLE_NAME, PARTITION_NAME from information_schema.partitions where table_schema = 'infoschema__infoschema';
Expand Down Expand Up @@ -477,5 +487,6 @@ Projection_4 10000.00 root Column#2, Column#3
└─MemTableScan_5 10000.00 root table:SEQUENCES sequence_schema_pattern:[%db1%]
select sequence_schema, sequence_name from information_schema.sequences where sequence_schema like '%db1%';
sequence_schema sequence_name
Db1 s1
drop database db1;
drop database db2;
6 changes: 6 additions & 0 deletions tests/integrationtest/t/infoschema/infoschema.test
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ explain select engine, DATA_LENGTH from information_schema.tables where table_na
select engine, DATA_LENGTH from information_schema.tables where table_name ='t4' and upper(table_name) ='T4' and table_schema = 'infoschema__infoschema';
drop table infoschema__infoschema.t4;
drop table infoschema__infoschema.t5;
create table caseSensitive (a int);
create table unrelatedTable (a int);
select table_schema, table_name from information_schema.tables where table_schema = 'infoschema__infoschema' and table_name like '%aseSensitive';
select table_schema, table_name, tidb_pk_type from information_schema.tables where table_schema = 'infoschema__infoschema' and table_name like '%aseSensitive';
drop table caseSensitive;
drop table unrelatedTable;

# TestPartitionsColumn
create table pt1(a int primary key, b int) partition by hash(a) partitions 4;
Expand Down