Skip to content

Commit

Permalink
session: change some privilege columns to case-insensitive (#43443) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored Jun 6, 2023
1 parent 6a1d55f commit 3368fbf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
21 changes: 21 additions & 0 deletions executor/revoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/parser/terror"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/testkit"
)

Expand Down Expand Up @@ -230,3 +231,23 @@ func (s *testSuite1) TestIssue41773(c *C) {
tk.MustExec("REVOKE USAGE ON test.* FROM 't1234'@'%';")
tk.MustExec("REVOKE USAGE ON test.xx FROM 't1234'@'%';")
}

// Check https://github.com/pingcap/tidb/issues/41048
func (s *testSuite1) TestCaseInsensitiveSchemaNames(c *C) {
defer collate.SetNewCollationEnabledForTest(false)
collate.SetNewCollationEnabledForTest(true)
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec(`CREATE TABLE test.TABLE_PRIV(id int, name varchar(20));`)
// Verify the case-insensitive updates for mysql.tables_priv table.
tk.MustExec(`GRANT SELECT ON test.table_priv TO 'root'@'%';`)
tk.MustExec(`revoke SELECT ON test.TABLE_PRIV from 'root'@'%';;`)

// Verify the case-insensitive updates for mysql.db table.
tk.MustExec(`GRANT SELECT ON test.* TO 'root'@'%';`)
tk.MustExec(`revoke SELECT ON tESt.* from 'root'@'%';;`)

// Verify the case-insensitive updates for mysql.columns_priv table.
tk.MustExec(`GRANT SELECT (id), INSERT (ID, name) ON tEst.TABLE_PRIV TO 'root'@'%';`)
tk.MustExec(`REVOKE SELECT (ID) ON test.taBle_priv from 'root'@'%';;`)
}
25 changes: 19 additions & 6 deletions session/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,23 @@ const (
"Priv LONGTEXT NOT NULL DEFAULT ''," +
"PRIMARY KEY (Host, User)" +
")"

// For `mysql.db`, `mysql.tables_priv` and `mysql.columns_priv` table, we have a slight different
// schema definition with MySQL: columns `DB`/`Table_name`/`Column_name` are defined with case-insensitive
// collation(in MySQL, they are case-sensitive).

// The reason behind this is that when writing those records, MySQL always converts those names into lower case
// while TiDB does not do so in early implementations, which makes some 'GRANT'/'REVOKE' operations case-sensitive.

// In order to fix this, we decide to explicitly set case-insensitive collation for the related columns here, to
// make sure:
// * The 'GRANT'/'REVOKE' could be case-insensitive for new clusters(compatible with MySQL).
// * Keep all behaviors unchanged for upgraded cluster.

// CreateDBPrivTable is the SQL statement creates DB scope privilege table in system db.
CreateDBPrivTable = `CREATE TABLE IF NOT EXISTS mysql.db (
Host CHAR(255),
DB CHAR(64),
DB CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
User CHAR(32),
Select_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Insert_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Expand All @@ -127,9 +140,9 @@ const (
// CreateTablePrivTable is the SQL statement creates table scope privilege table in system db.
CreateTablePrivTable = `CREATE TABLE IF NOT EXISTS mysql.tables_priv (
Host CHAR(255),
DB CHAR(64),
DB CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
User CHAR(32),
Table_name CHAR(64),
Table_name CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
Grantor CHAR(77),
Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Table_priv SET('Select','Insert','Update','Delete','Create','Drop','Grant','Index','Alter','Create View','Show View','Trigger','References'),
Expand All @@ -138,10 +151,10 @@ const (
// CreateColumnPrivTable is the SQL statement creates column scope privilege table in system db.
CreateColumnPrivTable = `CREATE TABLE IF NOT EXISTS mysql.columns_priv(
Host CHAR(255),
DB CHAR(64),
DB CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
User CHAR(32),
Table_name CHAR(64),
Column_name CHAR(64),
Table_name CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
Column_name CHAR(64) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Column_priv SET('Select','Insert','Update','References'),
PRIMARY KEY (Host, DB, User, Table_name, Column_name));`
Expand Down

0 comments on commit 3368fbf

Please sign in to comment.