From 0595143194720a9974ae2d0a2faa78976cd9d8a2 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Fri, 28 Apr 2017 22:35:46 +0800 Subject: [PATCH] *: add Process_priv column to mysql.user (#2994) --- bootstrap.go | 27 ++++++++++++++++++++++++--- bootstrap_test.go | 2 +- executor/aggregate_test.go | 2 +- mysql/const.go | 7 ++++++- parser/misc.go | 1 + parser/parser.y | 5 +++++ privilege/privileges/cache.go | 2 +- privilege/privileges/cache_test.go | 14 +++++++------- session.go | 2 +- 9 files changed, 47 insertions(+), 15 deletions(-) diff --git a/bootstrap.go b/bootstrap.go index bbe5dcb1e88b4..0da83b47cf473 100644 --- a/bootstrap.go +++ b/bootstrap.go @@ -29,6 +29,7 @@ import ( "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/mysql" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/terror" "github.com/pingcap/tidb/util/types" ) @@ -44,6 +45,7 @@ const ( Delete_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Create_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Drop_priv ENUM('N','Y') NOT NULL DEFAULT 'N', + Process_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Grant_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Alter_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Show_db_priv ENUM('N','Y') NOT NULL DEFAULT 'N', @@ -182,6 +184,7 @@ const ( version4 = 4 version5 = 5 version6 = 6 + version7 = 7 ) func checkBootstrapped(s Session) (bool, error) { @@ -315,9 +318,27 @@ func upgradeToVer5(s Session) { } func upgradeToVer6(s Session) { - s.Execute("ALTER TABLE mysql.user ADD COLUMN `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Show_db_priv`") + _, err := s.Execute("ALTER TABLE mysql.user ADD COLUMN `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Show_db_priv`") + if terror.ErrorEqual(err, infoschema.ErrColumnExists) { + return + } + if err != nil { + log.Fatal(err) + } + // For reasons of compatibility, set the non-exists privilege column value to 'Y', as TiDB doesn't check them in older versions. + mustExecute(s, "UPDATE mysql.user SET Super_priv='Y'") +} + +func upgradeToVer7(s Session) { + _, err := s.Execute("ALTER TABLE mysql.user ADD COLUMN `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Drop_priv`") + if terror.ErrorEqual(err, infoschema.ErrColumnExists) { + return + } + if err != nil { + log.Fatal(err) + } // For reasons of compatibility, set the non-exists privilege column value to 'Y', as TiDB doesn't check them in older versions. - s.Execute("UPDATE mysql.user SET Super_priv='Y'") + mustExecute(s, "UPDATE mysql.user SET Process_priv='Y'") } // Update boostrap version variable in mysql.TiDB table. @@ -373,7 +394,7 @@ func doDMLWorks(s Session) { // Insert a default user with empty password. mustExecute(s, `INSERT INTO mysql.user VALUES - ("%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + ("%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) // Init global system variables table. values := make([]string, 0, len(variable.SysVars)) diff --git a/bootstrap_test.go b/bootstrap_test.go index 4425884e4322d..42500cdd1dacf 100644 --- a/bootstrap_test.go +++ b/bootstrap_test.go @@ -48,7 +48,7 @@ func (s *testBootstrapSuite) TestBootstrap(c *C) { row, err := r.Next() c.Assert(err, IsNil) c.Assert(row, NotNil) - match(c, row.Data, []byte("%"), []byte("root"), []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y") + match(c, row.Data, []byte("%"), []byte("root"), []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y") c.Assert(se.Auth("root@anyhost", []byte(""), []byte("")), IsTrue) mustExecSQL(c, se, "USE test;") diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 3b40017ff75b6..5e4d654da510b 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -277,7 +277,7 @@ func (s *testSuite) TestAggregation(c *C) { result = tk.MustQuery("select count(*) from information_schema.columns") // When adding new memory table in information_schema, please update this variable. - columnCountOfAllInformationSchemaTables := "714" + columnCountOfAllInformationSchemaTables := "715" result.Check(testkit.Rows(columnCountOfAllInformationSchemaTables)) tk.MustExec("drop table if exists t1") diff --git a/mysql/const.go b/mysql/const.go index 2dafee9940344..7f43bd379a975 100644 --- a/mysql/const.go +++ b/mysql/const.go @@ -172,6 +172,8 @@ const ( CreateUserPriv // DropPriv is the privilege to drop schema/table. DropPriv + // ProcessPriv pertains to display of information about the threads executing within the server. + ProcessPriv // GrantPriv is the privilege to grant privilege to user. GrantPriv // AlterPriv is the privilege to run alter statement. @@ -198,6 +200,7 @@ var Priv2UserCol = map[PrivilegeType]string{ SuperPriv: "Super_priv", CreateUserPriv: "Create_user_priv", DropPriv: "Drop_priv", + ProcessPriv: "Process_priv", GrantPriv: "Grant_priv", AlterPriv: "Alter_priv", ExecutePriv: "Execute_priv", @@ -215,6 +218,7 @@ var Col2PrivType = map[string]PrivilegeType{ "Super_priv": SuperPriv, "Create_user_priv": CreateUserPriv, "Drop_priv": DropPriv, + "Process_priv": ProcessPriv, "Grant_priv": GrantPriv, "Alter_priv": AlterPriv, "Execute_priv": ExecutePriv, @@ -222,7 +226,7 @@ var Col2PrivType = map[string]PrivilegeType{ } // AllGlobalPrivs is all the privileges in global scope. -var AllGlobalPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, GrantPriv, AlterPriv, ShowDBPriv, SuperPriv, ExecutePriv, IndexPriv, CreateUserPriv} +var AllGlobalPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, ProcessPriv, GrantPriv, AlterPriv, ShowDBPriv, SuperPriv, ExecutePriv, IndexPriv, CreateUserPriv} // Priv2Str is the map for privilege to string. var Priv2Str = map[PrivilegeType]string{ @@ -235,6 +239,7 @@ var Priv2Str = map[PrivilegeType]string{ SuperPriv: "Super", CreateUserPriv: "Create User", DropPriv: "Drop", + ProcessPriv: "Process", GrantPriv: "Grant Option", AlterPriv: "Alter", ExecutePriv: "Execute", diff --git a/parser/misc.go b/parser/misc.go index dda93b7371a74..e4b5236bdf16d 100644 --- a/parser/misc.go +++ b/parser/misc.go @@ -378,6 +378,7 @@ var tokenMap = map[string]int{ "PRIVILEGES": privileges, "PROCEDURE": procedure, "PROCESSLIST": processlist, + "PROCESS": process, "QUARTER": quarter, "QUICK": quick, "RADIANS": radians, diff --git a/parser/parser.y b/parser/parser.y index 42ff8bf60ce4b..7a90f3dba9659 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -312,6 +312,7 @@ import ( pi "PI" pow "POW" power "POWER" + process "PROCESS" query "QUERY" rand "RAND" radians "RADIANS" @@ -6115,6 +6116,10 @@ PrivType: { $$ = mysql.DropPriv } +| "PROCESS" + { + $$ = mysql.ProcessPriv + } | "EXECUTE" { $$ = mysql.ExecutePriv diff --git a/privilege/privileges/cache.go b/privilege/privileges/cache.go index 2cdd70128daf9..ac528176eacf4 100644 --- a/privilege/privileges/cache.go +++ b/privilege/privileges/cache.go @@ -149,7 +149,7 @@ func noSuchTable(err error) bool { // LoadUserTable loads the mysql.user table from database. func (p *MySQLPrivilege) LoadUserTable(ctx context.Context) error { - return p.loadTable(ctx, "select Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,Alter_priv,Show_db_priv,Super_priv,Execute_priv,Index_priv,Create_user_priv from mysql.user order by host, user;", p.decodeUserTableRow) + return p.loadTable(ctx, "select Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Process_priv,Grant_priv,Alter_priv,Show_db_priv,Super_priv,Execute_priv,Index_priv,Create_user_priv from mysql.user order by host, user;", p.decodeUserTableRow) } // LoadDBTable loads the mysql.db table from database. diff --git a/privilege/privileges/cache_test.go b/privilege/privileges/cache_test.go index 9d84c56f48a4e..deb1bdfb2bbff 100644 --- a/privilege/privileges/cache_test.go +++ b/privilege/privileges/cache_test.go @@ -53,11 +53,11 @@ func (s *testCacheSuite) TestLoadUserTable(c *C) { c.Assert(err, IsNil) c.Assert(len(p.User), Equals, 0) - // Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | Alter_priv | Show_db_priv | Super_priv | Execute_priv | Index_priv | Create_user_priv - mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root", "", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) - mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root1", "admin", "N", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) - mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root11", "", "N", "N", "Y", "N", "N", "N", "N", "N", "Y", "N", "N", "N", "N")`) - mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root111", "", "N", "N", "N", "N", "N", "N", "N", "N", "Y", "Y", "Y", "Y", "Y")`) + // Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv| Process_priv | Grant_priv | Alter_priv | Show_db_priv | Super_priv | Execute_priv | Index_priv | Create_user_priv + mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root", "", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) + mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root1", "admin", "N", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) + mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root11", "", "N", "N", "Y", "N", "N", "N", "N", "N", "N", "Y", "N", "N", "N", "N")`) + mustExec(c, se, `INSERT INTO mysql.user VALUES ("%", "root111", "", "N", "N", "N", "N", "N", "N", "N", "N", "N", "Y", "Y", "Y", "Y", "Y")`) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) @@ -136,7 +136,7 @@ func (s *testCacheSuite) TestPatternMatch(c *C) { defer se.Close() mustExec(c, se, "USE MYSQL;") mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user VALUES ("10.0.%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + mustExec(c, se, `INSERT INTO mysql.user VALUES ("10.0.%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) var p privileges.MySQLPrivilege err = p.LoadUserTable(se) c.Assert(err, IsNil) @@ -147,7 +147,7 @@ func (s *testCacheSuite) TestPatternMatch(c *C) { c.Assert(p.RequestVerification("root", "114.114.114.114", "test", "", "", mysql.SelectPriv), IsFalse) mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user VALUES ("", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + mustExec(c, se, `INSERT INTO mysql.user VALUES ("", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) c.Assert(err, IsNil) diff --git a/session.go b/session.go index 39d371b1b2065..50dc68e8b8df5 100644 --- a/session.go +++ b/session.go @@ -926,7 +926,7 @@ func createSession(store kv.Storage) (*session, error) { const ( notBootstrapped = 0 - currentBootstrapVersion = 6 + currentBootstrapVersion = 7 ) func getStoreBootstrapVersion(store kv.Storage) int64 {