Skip to content

Commit

Permalink
parser: implement Restore for PrivElem, GrantStmt and RevokeStmt (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
exialin authored and tiancaiamao committed Feb 12, 2019
1 parent a71b434 commit 03c4011
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 26 deletions.
152 changes: 149 additions & 3 deletions ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,65 @@ type PrivElem struct {

// Restore implements Node interface.
func (n *PrivElem) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented")
switch n.Priv {
case 0:
// Do nothing for types that have no effect.
// Actually this should not happen since there is no way to determine its type.
return errors.New("Cannot determine privilege type")
case mysql.AllPriv:
ctx.WriteKeyWord("ALL")
case mysql.AlterPriv:
ctx.WriteKeyWord("ALTER")
case mysql.CreatePriv:
ctx.WriteKeyWord("CREATE")
case mysql.CreateUserPriv:
ctx.WriteKeyWord("CREATE USER")
case mysql.TriggerPriv:
ctx.WriteKeyWord("TRIGGER")
case mysql.DeletePriv:
ctx.WriteKeyWord("DELETE")
case mysql.DropPriv:
ctx.WriteKeyWord("DROP")
case mysql.ProcessPriv:
ctx.WriteKeyWord("PROCESS")
case mysql.ExecutePriv:
ctx.WriteKeyWord("EXECUTE")
case mysql.IndexPriv:
ctx.WriteKeyWord("INDEX")
case mysql.InsertPriv:
ctx.WriteKeyWord("INSERT")
case mysql.SelectPriv:
ctx.WriteKeyWord("SELECT")
case mysql.SuperPriv:
ctx.WriteKeyWord("SUPER")
case mysql.ShowDBPriv:
ctx.WriteKeyWord("SHOW DATABASES")
case mysql.UpdatePriv:
ctx.WriteKeyWord("UPDATE")
case mysql.GrantPriv:
ctx.WriteKeyWord("GRANT OPTION")
case mysql.ReferencesPriv:
ctx.WriteKeyWord("REFERENCES")
case mysql.CreateViewPriv:
ctx.WriteKeyWord("CREATE VIEW")
case mysql.ShowViewPriv:
ctx.WriteKeyWord("SHOW VIEW")
default:
return errors.New("Unsupported privilege type")
}
if n.Cols != nil {
ctx.WritePlain(" (")
for i, v := range n.Cols {
if i != 0 {
ctx.WritePlain(",")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore PrivElem.Cols[%d]", i)
}
}
ctx.WritePlain(")")
}
return nil
}

// Accept implements Node Accept interface.
Expand Down Expand Up @@ -1250,6 +1308,19 @@ const (
ObjectTypeTable
)

// Restore implements Node interface.
func (n ObjectTypeType) Restore(ctx *RestoreCtx) error {
switch n {
case ObjectTypeNone:
// do nothing
case ObjectTypeTable:
ctx.WriteKeyWord("TABLE ")
default:
return errors.New("Unsupported object type")
}
return nil
}

// GrantLevelType is the type for grant level.
type GrantLevelType int

Expand All @@ -1271,6 +1342,28 @@ type GrantLevel struct {
TableName string
}

// Restore implements Node interface.
func (n *GrantLevel) Restore(ctx *RestoreCtx) error {
switch n.Level {
case GrantLevelDB:
if n.DBName == "" {
ctx.WritePlain("*")
} else {
ctx.WriteName(n.DBName)
ctx.WritePlain(".*")
}
case GrantLevelGlobal:
ctx.WritePlain("*.*")
case GrantLevelTable:
if n.DBName != "" {
ctx.WriteName(n.DBName)
ctx.WritePlain(".")
}
ctx.WriteName(n.TableName)
}
return nil
}

// RevokeStmt is the struct for REVOKE statement.
type RevokeStmt struct {
stmtNode
Expand All @@ -1283,7 +1376,32 @@ type RevokeStmt struct {

// Restore implements Node interface.
func (n *RevokeStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented")
ctx.WriteKeyWord("REVOKE ")
for i, v := range n.Privs {
if i != 0 {
ctx.WritePlain(", ")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Privs[%d]", i)
}
}
ctx.WriteKeyWord(" ON ")
if err := n.ObjectType.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore RevokeStmt.ObjectType")
}
if err := n.Level.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore RevokeStmt.Level")
}
ctx.WriteKeyWord(" FROM ")
for i, v := range n.Users {
if i != 0 {
ctx.WritePlain(", ")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Users[%d]", i)
}
}
return nil
}

// Accept implements Node Accept interface.
Expand Down Expand Up @@ -1316,7 +1434,35 @@ type GrantStmt struct {

// Restore implements Node interface.
func (n *GrantStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented")
ctx.WriteKeyWord("GRANT ")
for i, v := range n.Privs {
if i != 0 {
ctx.WritePlain(", ")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore GrantStmt.Privs[%d]", i)
}
}
ctx.WriteKeyWord(" ON ")
if err := n.ObjectType.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore GrantStmt.ObjectType")
}
if err := n.Level.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore GrantStmt.Level")
}
ctx.WriteKeyWord(" TO ")
for i, v := range n.Users {
if i != 0 {
ctx.WritePlain(", ")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
}
}
if n.WithGrant {
ctx.WriteKeyWord(" WITH GRANT OPTION")
}
return nil
}

// SecureText implements SensitiveStatement interface.
Expand Down
2 changes: 1 addition & 1 deletion parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -5804,7 +5804,7 @@ AdminStmt:
$$ = &ast.AdminStmt{
Tp: ast.AdminRestoreTable,
Tables: []*ast.TableName{$4.(*ast.TableName)},
JobNumber: $5.(int64),
JobNumber: $5.(int64),
}
}
| "ADMIN" "CLEANUP" "INDEX" TableName Identifier
Expand Down
44 changes: 22 additions & 22 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2102,32 +2102,32 @@ func (s *testParserSuite) TestPrivilege(c *C) {
{`DROP USER IF EXISTS 'root'@'localhost'`, true, "DROP USER IF EXISTS `root`@`localhost`"},

// for grant statement
{"GRANT ALL ON db1.* TO 'jeffrey'@'localhost';", true, ""},
{"GRANT ALL ON db1.* TO 'jeffrey'@'localhost' WITH GRANT OPTION;", true, ""},
{"GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';", true, ""},
{"GRANT ALL ON *.* TO 'someuser'@'somehost';", true, ""},
{"GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';", true, ""},
{"GRANT ALL ON mydb.* TO 'someuser'@'somehost';", true, ""},
{"GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';", true, ""},
{"GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost';", true, ""},
{"GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';", true, ""},
{"GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';", true, ""},
{"grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by 'password';", true, ""},
{"GRANT SELECT ON test.* to 'test'", true, ""}, // For issue 2654.
{"GRANT ALL ON db1.* TO 'jeffrey'@'localhost';", true, "GRANT ALL ON `db1`.* TO `jeffrey`@`localhost`"},
{"GRANT ALL ON db1.* TO 'jeffrey'@'localhost' WITH GRANT OPTION;", true, "GRANT ALL ON `db1`.* TO `jeffrey`@`localhost` WITH GRANT OPTION"},
{"GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';", true, "GRANT SELECT ON `db2`.`invoice` TO `jeffrey`@`localhost`"},
{"GRANT ALL ON *.* TO 'someuser'@'somehost';", true, "GRANT ALL ON *.* TO `someuser`@`somehost`"},
{"GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';", true, "GRANT SELECT, INSERT ON *.* TO `someuser`@`somehost`"},
{"GRANT ALL ON mydb.* TO 'someuser'@'somehost';", true, "GRANT ALL ON `mydb`.* TO `someuser`@`somehost`"},
{"GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';", true, "GRANT SELECT, INSERT ON `mydb`.* TO `someuser`@`somehost`"},
{"GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost';", true, "GRANT ALL ON `mydb`.`mytbl` TO `someuser`@`somehost`"},
{"GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';", true, "GRANT SELECT, INSERT ON `mydb`.`mytbl` TO `someuser`@`somehost`"},
{"GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';", true, "GRANT SELECT (`col1`), INSERT (`col1`,`col2`) ON `mydb`.`mytbl` TO `someuser`@`somehost`"},
{"grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by 'password';", true, "GRANT ALL ON `zabbix`.* TO `zabbix`@`localhost` IDENTIFIED BY 'password'"},
{"GRANT SELECT ON test.* to 'test'", true, "GRANT SELECT ON `test`.* TO `test`@`%`"}, // For issue 2654.
{"grant PROCESS,usage, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'xxxxxxxxxx'@'%' identified by password 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'", true, ""}, // For issue 4865
{"/* rds internal mark */ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, RELOAD, PROCESS, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER on *.* to 'root2'@'%' identified by password '*sdsadsdsadssadsadsadsadsada' with grant option", true, ""},

// for revoke statement
{"REVOKE ALL ON db1.* FROM 'jeffrey'@'localhost';", true, ""},
{"REVOKE SELECT ON db2.invoice FROM 'jeffrey'@'localhost';", true, ""},
{"REVOKE ALL ON *.* FROM 'someuser'@'somehost';", true, ""},
{"REVOKE SELECT, INSERT ON *.* FROM 'someuser'@'somehost';", true, ""},
{"REVOKE ALL ON mydb.* FROM 'someuser'@'somehost';", true, ""},
{"REVOKE SELECT, INSERT ON mydb.* FROM 'someuser'@'somehost';", true, ""},
{"REVOKE ALL ON mydb.mytbl FROM 'someuser'@'somehost';", true, ""},
{"REVOKE SELECT, INSERT ON mydb.mytbl FROM 'someuser'@'somehost';", true, ""},
{"REVOKE SELECT (col1), INSERT (col1,col2) ON mydb.mytbl FROM 'someuser'@'somehost';", true, ""},
{"REVOKE all privileges on zabbix.* FROM 'zabbix'@'localhost' identified by 'password';", true, ""},
{"REVOKE ALL ON db1.* FROM 'jeffrey'@'localhost';", true, "REVOKE ALL ON `db1`.* FROM `jeffrey`@`localhost`"},
{"REVOKE SELECT ON db2.invoice FROM 'jeffrey'@'localhost';", true, "REVOKE SELECT ON `db2`.`invoice` FROM `jeffrey`@`localhost`"},
{"REVOKE ALL ON *.* FROM 'someuser'@'somehost';", true, "REVOKE ALL ON *.* FROM `someuser`@`somehost`"},
{"REVOKE SELECT, INSERT ON *.* FROM 'someuser'@'somehost';", true, "REVOKE SELECT, INSERT ON *.* FROM `someuser`@`somehost`"},
{"REVOKE ALL ON mydb.* FROM 'someuser'@'somehost';", true, "REVOKE ALL ON `mydb`.* FROM `someuser`@`somehost`"},
{"REVOKE SELECT, INSERT ON mydb.* FROM 'someuser'@'somehost';", true, "REVOKE SELECT, INSERT ON `mydb`.* FROM `someuser`@`somehost`"},
{"REVOKE ALL ON mydb.mytbl FROM 'someuser'@'somehost';", true, "REVOKE ALL ON `mydb`.`mytbl` FROM `someuser`@`somehost`"},
{"REVOKE SELECT, INSERT ON mydb.mytbl FROM 'someuser'@'somehost';", true, "REVOKE SELECT, INSERT ON `mydb`.`mytbl` FROM `someuser`@`somehost`"},
{"REVOKE SELECT (col1), INSERT (col1,col2) ON mydb.mytbl FROM 'someuser'@'somehost';", true, "REVOKE SELECT (`col1`), INSERT (`col1`,`col2`) ON `mydb`.`mytbl` FROM `someuser`@`somehost`"},
{"REVOKE all privileges on zabbix.* FROM 'zabbix'@'localhost' identified by 'password';", true, "REVOKE ALL ON `zabbix`.* FROM `zabbix`@`localhost` IDENTIFIED BY 'password'"},
}
s.RunTest(c, table)
}
Expand Down

0 comments on commit 03c4011

Please sign in to comment.