@@ -85,6 +85,8 @@ func (e *SimpleExec) Next(ctx context.Context, req *chunk.RecordBatch) (err erro
8585 err = e .executeDropStats (x )
8686 case * ast.SetRoleStmt :
8787 err = e .executeSetRole (x )
88+ case * ast.RevokeRoleStmt :
89+ err = e .executeRevokeRole (x )
8890 }
8991 e .done = true
9092 return err
@@ -165,6 +167,52 @@ func (e *SimpleExec) executeBegin(ctx context.Context, s *ast.BeginStmt) error {
165167 return nil
166168}
167169
170+ func (e * SimpleExec ) executeRevokeRole (s * ast.RevokeRoleStmt ) error {
171+ for _ , role := range s .Roles {
172+ exists , err := userExists (e .ctx , role .Username , role .Hostname )
173+ if err != nil {
174+ return errors .Trace (err )
175+ }
176+ if ! exists {
177+ return ErrCannotUser .GenWithStackByArgs ("REVOKE ROLE" , role .String ())
178+ }
179+ }
180+
181+ // begin a transaction to insert role graph edges.
182+ if _ , err := e .ctx .(sqlexec.SQLExecutor ).Execute (context .Background (), "begin" ); err != nil {
183+ return errors .Trace (err )
184+ }
185+ for _ , user := range s .Users {
186+ exists , err := userExists (e .ctx , user .Username , user .Hostname )
187+ if err != nil {
188+ return errors .Trace (err )
189+ }
190+ if ! exists {
191+ if _ , err := e .ctx .(sqlexec.SQLExecutor ).Execute (context .Background (), "rollback" ); err != nil {
192+ return errors .Trace (err )
193+ }
194+ return ErrCannotUser .GenWithStackByArgs ("REVOKE ROLE" , user .String ())
195+ }
196+ for _ , role := range s .Roles {
197+ if role .Hostname == "" {
198+ role .Hostname = "%"
199+ }
200+ sql := fmt .Sprintf (`DELETE IGNORE FROM %s.%s WHERE FROM_HOST='%s' and FROM_USER='%s' and TO_HOST='%s' and TO_USER='%s'` , mysql .SystemDB , mysql .RoleEdgeTable , role .Hostname , role .Username , user .Hostname , user .Username )
201+ if _ , err := e .ctx .(sqlexec.SQLExecutor ).Execute (context .Background (), sql ); err != nil {
202+ if _ , err := e .ctx .(sqlexec.SQLExecutor ).Execute (context .Background (), "rollback" ); err != nil {
203+ return errors .Trace (err )
204+ }
205+ return ErrCannotUser .GenWithStackByArgs ("REVOKE ROLE" , role .String ())
206+ }
207+ }
208+ }
209+ if _ , err := e .ctx .(sqlexec.SQLExecutor ).Execute (context .Background (), "commit" ); err != nil {
210+ return err
211+ }
212+ err := domain .GetDomain (e .ctx ).PrivilegeHandle ().Update (e .ctx .(sessionctx.Context ))
213+ return errors .Trace (err )
214+ }
215+
168216func (e * SimpleExec ) executeCommit (s * ast.CommitStmt ) {
169217 e .ctx .GetSessionVars ().SetStatusFlag (mysql .ServerStatusInTrans , false )
170218}
0 commit comments