This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a97792086 [IOTDB-4030] Simplify Privilege Operations SQL (#6875)
8a97792086 is described below

commit 8a977920862056a02076bfc37caf7b05e18fc377
Author: Yifu Zhou <[email protected]>
AuthorDate: Sun Aug 7 19:03:54 2022 +0800

    [IOTDB-4030] Simplify Privilege Operations SQL (#6875)
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  31 +-----
 .../consensus/request/ConfigPhysicalPlanType.java  |   2 +
 .../iotdb/confignode/persistence/AuthorInfo.java   | 103 ++++++++----------
 .../persistence/executor/ConfigPlanExecutor.java   |   8 +-
 .../confignode/persistence/AuthorInfoTest.java     |  43 +++++---
 .../thrift/ConfigNodeRPCServiceProcessorTest.java  |   4 +-
 .../Administration-Management/Administration.md    | 119 +++++++++++----------
 .../Administration-Management/Administration.md    |  53 ++++-----
 .../iotdb/db/integration/IoTDBAuthorizationIT.java |  20 ++--
 .../iotdb/db/localconfignode/LocalConfigNode.java  |  90 +++++++---------
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       |  52 ++-------
 .../db/mpp/plan/statement/sys/AuthorStatement.java |   8 --
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |  18 ++--
 .../iotdb/db/qp/logical/sys/AuthorOperator.java    |  12 +--
 .../iotdb/db/qp/physical/sys/AuthorPlan.java       |   8 --
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  54 +++-------
 .../java/org/apache/iotdb/db/qp/PlannerTest.java   |   2 +-
 17 files changed, 259 insertions(+), 368 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index dfd3ece92a..ffa922239c 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -56,7 +56,6 @@ dclStatement
     : createUser | createRole | alterUser | grantUser | grantRole | 
grantRoleToUser
     | revokeUser |  revokeRole | revokeRoleFromUser | dropUser | dropRole
     | listUser | listRole | listPrivilegesUser | listPrivilegesRole
-    | listUserPrivileges | listRolePrivileges | listAllRoleOfUser | 
listAllUserOfRole
     ;
 
 utilityStatement
@@ -570,42 +569,22 @@ dropRole
 
 // List Users
 listUser
-    : LIST USER
+    : LIST USER (OF ROLE roleName=identifier)?
     ;
 
 // List Roles
 listRole
-    : LIST ROLE
+    : LIST ROLE (OF USER userName=usernameWithRoot)?
     ;
 
-// List Privileges
+// List Privileges of Users On Specific Path
 listPrivilegesUser
-    : LIST PRIVILEGES USER userName=usernameWithRoot ON prefixPath (COMMA 
prefixPath)*
+    : LIST PRIVILEGES USER userName=usernameWithRoot (ON prefixPath (COMMA 
prefixPath)*)?
     ;
 
 // List Privileges of Roles On Specific Path
 listPrivilegesRole
-    : LIST PRIVILEGES ROLE roleName=identifier ON prefixPath (COMMA 
prefixPath)*
-    ;
-
-// List Privileges of Users
-listUserPrivileges
-    : LIST USER PRIVILEGES userName=usernameWithRoot
-    ;
-
-// List Privileges of Roles
-listRolePrivileges
-    : LIST ROLE PRIVILEGES roleName=identifier
-    ;
-
-// List Roles of Users
-listAllRoleOfUser
-    : LIST ALL ROLE OF USER userName=usernameWithRoot
-    ;
-
-// List Users of Role
-listAllUserOfRole
-    : LIST ALL USER OF ROLE roleName=identifier
+    : LIST PRIVILEGES ROLE roleName=identifier (ON prefixPath (COMMA 
prefixPath)*)?
     ;
 
 privileges
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
index e64806224b..aa08063bd5 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
@@ -57,7 +57,9 @@ public enum ConfigPhysicalPlanType {
   ListRole,
   ListUserPrivilege,
   ListRolePrivilege,
+  @Deprecated
   ListUserRoles,
+  @Deprecated
   ListRoleUsers,
   ApplyConfigNode,
   RemoveDataNode,
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
index 0edaf346a2..0e24fb8b10 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
@@ -51,6 +51,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -207,78 +208,66 @@ public class AuthorInfo implements SnapshotProcessor {
     return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
   }
 
-  public PermissionInfoResp executeListRole() {
+  public PermissionInfoResp executeListUsers(AuthorPlan plan) throws 
AuthException {
     PermissionInfoResp result = new PermissionInfoResp();
-    List<String> roleList = authorizer.listAllRoles();
     Map<String, List<String>> permissionInfo = new HashMap<>();
-    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, roleList);
-    result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
-    result.setPermissionInfo(permissionInfo);
-    return result;
-  }
-
-  public PermissionInfoResp executeListUser() {
-    PermissionInfoResp result = new PermissionInfoResp();
     List<String> userList = authorizer.listAllUsers();
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    permissionInfo.put(IoTDBConstant.COLUMN_USER, userList);
-    result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
-    result.setPermissionInfo(permissionInfo);
-    return result;
-  }
-
-  public PermissionInfoResp executeListRoleUsers(AuthorPlan plan) throws 
AuthException {
-    PermissionInfoResp result = new PermissionInfoResp();
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    Role role;
-    try {
-      role = authorizer.getRole(plan.getRoleName());
-      if (role == null) {
-        result.setStatus(
-            RpcUtils.getStatus(
-                TSStatusCode.ROLE_NOT_EXIST_ERROR, "No such role : " + 
plan.getRoleName()));
-        result.setPermissionInfo(permissionInfo);
-        return result;
+    if (!plan.getRoleName().isEmpty()) {
+      Role role;
+      try {
+        role = authorizer.getRole(plan.getRoleName());
+        if (role == null) {
+          result.setStatus(
+              RpcUtils.getStatus(
+                  TSStatusCode.ROLE_NOT_EXIST_ERROR, "No such role : " + 
plan.getRoleName()));
+          result.setPermissionInfo(permissionInfo);
+          return result;
+        }
+      } catch (AuthException e) {
+        throw new AuthException(e);
       }
-    } catch (AuthException e) {
-      throw new AuthException(e);
-    }
-    List<String> roleUsersList = new ArrayList<>();
-    List<String> userList = authorizer.listAllUsers();
-    for (String userN : userList) {
-      User userObj = authorizer.getUser(userN);
-      if (userObj != null && userObj.hasRole(plan.getRoleName())) {
-        roleUsersList.add(userN);
+      Iterator<String> itr = userList.iterator();
+      while (itr.hasNext()) {
+        User userObj = authorizer.getUser(itr.next());
+        if (userObj == null || !userObj.hasRole(plan.getRoleName())) {
+          itr.remove();
+        }
       }
     }
-    permissionInfo.put(IoTDBConstant.COLUMN_USER, roleUsersList);
+
+    permissionInfo.put(IoTDBConstant.COLUMN_USER, userList);
     result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
     result.setPermissionInfo(permissionInfo);
     return result;
   }
 
-  public PermissionInfoResp executeListUserRoles(AuthorPlan plan) throws 
AuthException {
+  public PermissionInfoResp executeListRoles(AuthorPlan plan) throws 
AuthException {
     PermissionInfoResp result = new PermissionInfoResp();
     Map<String, List<String>> permissionInfo = new HashMap<>();
-    User user;
-    try {
-      user = authorizer.getUser(plan.getUserName());
-      if (user == null) {
-        result.setStatus(
-            RpcUtils.getStatus(
-                TSStatusCode.USER_NOT_EXIST_ERROR, "No such user : " + 
plan.getUserName()));
-        result.setPermissionInfo(permissionInfo);
-        return result;
+    List<String> roleList = new ArrayList<>();
+    ;
+    if (plan.getUserName().isEmpty()) {
+      roleList.addAll(authorizer.listAllRoles());
+    } else {
+      User user;
+      try {
+        user = authorizer.getUser(plan.getUserName());
+        if (user == null) {
+          result.setStatus(
+              RpcUtils.getStatus(
+                  TSStatusCode.USER_NOT_EXIST_ERROR, "No such user : " + 
plan.getUserName()));
+          result.setPermissionInfo(permissionInfo);
+          return result;
+        }
+      } catch (AuthException e) {
+        throw new AuthException(e);
+      }
+      for (String roleN : user.getRoleList()) {
+        roleList.add(roleN);
       }
-    } catch (AuthException e) {
-      throw new AuthException(e);
-    }
-    List<String> userRoleList = new ArrayList<>();
-    for (String roleN : user.getRoleList()) {
-      userRoleList.add(roleN);
     }
 
-    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, userRoleList);
+    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, roleList);
     result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
     result.setPermissionInfo(permissionInfo);
     return result;
@@ -369,7 +358,7 @@ public class AuthorInfo implements SnapshotProcessor {
         for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
           if (plan.getNodeNameList().isEmpty()
               && !rolePrivilegeSet.contains(pathPrivilege.toString())) {
-            rolePrivileges.add("");
+            rolePrivileges.add(roleN);
             rolePrivilegeSet.add(pathPrivilege.toString());
             continue;
           }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
index 2b8a7c58f9..b37baa8f66 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java
@@ -131,17 +131,13 @@ public class ConfigPlanExecutor {
       case GetOrCreateSchemaPartition:
         return partitionInfo.getSchemaPartition((GetSchemaPartitionPlan) req);
       case ListUser:
-        return authorInfo.executeListUser();
+        return authorInfo.executeListUsers((AuthorPlan) req);
       case ListRole:
-        return authorInfo.executeListRole();
+        return authorInfo.executeListRoles((AuthorPlan) req);
       case ListUserPrivilege:
         return authorInfo.executeListUserPrivileges((AuthorPlan) req);
       case ListRolePrivilege:
         return authorInfo.executeListRolePrivileges((AuthorPlan) req);
-      case ListUserRoles:
-        return authorInfo.executeListUserRoles((AuthorPlan) req);
-      case ListRoleUsers:
-        return authorInfo.executeListRoleUsers((AuthorPlan) req);
       case GetNodePathsPartition:
         return getSchemaNodeManagementPartition(req);
       case GetRegionInfoList:
diff --git 
a/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
 
b/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
index f17cbb3565..4c986b985a 100644
--- 
a/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
+++ 
b/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
@@ -141,7 +141,10 @@ public class AuthorInfoTest {
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
 
     // list user
-    PermissionInfoResp permissionInfoResp = authorInfo.executeListUser();
+    authorPlan =
+        new AuthorPlan(
+            ConfigPhysicalPlanType.ListUser, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
+    PermissionInfoResp permissionInfoResp = 
authorInfo.executeListUsers(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
     userList.remove("user1");
@@ -178,7 +181,10 @@ public class AuthorInfoTest {
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
 
     // list role
-    permissionInfoResp = authorInfo.executeListRole();
+    authorPlan =
+        new AuthorPlan(
+            ConfigPhysicalPlanType.ListRole, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
+    permissionInfoResp = authorInfo.executeListRoles(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
     roleList.remove("role1");
@@ -316,14 +322,14 @@ public class AuthorInfoTest {
     // list all role of user
     authorPlan =
         new AuthorPlan(
-            ConfigPhysicalPlanType.ListUserRoles,
+            ConfigPhysicalPlanType.ListRole,
             "user0",
             "",
             "",
             "",
             new HashSet<>(),
             new ArrayList<>());
-    permissionInfoResp = authorInfo.executeListUserRoles(authorPlan);
+    permissionInfoResp = authorInfo.executeListRoles(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
     roleList.remove("role1");
@@ -333,14 +339,14 @@ public class AuthorInfoTest {
     // list all user of role
     authorPlan =
         new AuthorPlan(
-            ConfigPhysicalPlanType.ListRoleUsers,
+            ConfigPhysicalPlanType.ListUser,
             "",
             "role0",
             "",
             "",
             new HashSet<>(),
             new ArrayList<>());
-    permissionInfoResp = authorInfo.executeListRoleUsers(authorPlan);
+    permissionInfoResp = authorInfo.executeListUsers(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
     userList.remove("user1");
@@ -388,7 +394,7 @@ public class AuthorInfoTest {
     AuthorPlan authorPlan =
         new AuthorPlan(
             ConfigPhysicalPlanType.ListUser, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
-    PermissionInfoResp permissionInfoResp = authorInfo.executeListUser();
+    PermissionInfoResp permissionInfoResp = 
authorInfo.executeListUsers(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
 
@@ -410,7 +416,10 @@ public class AuthorInfoTest {
     }
 
     // clean role
-    permissionInfoResp = authorInfo.executeListRole();
+    authorPlan =
+        new AuthorPlan(
+            ConfigPhysicalPlanType.ListRole, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
+    permissionInfoResp = authorInfo.executeListRoles(authorPlan);
     status = permissionInfoResp.getStatus();
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
 
@@ -444,13 +453,23 @@ public class AuthorInfoTest {
     status = authorInfo.authorNonQuery(createUserReq);
     Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
 
-    Assert.assertEquals(1, 
authorInfo.executeListRole().getPermissionInfo().get("role").size());
-    Assert.assertEquals(2, 
authorInfo.executeListUser().getPermissionInfo().get("user").size());
+    AuthorPlan listUserPlan =
+        new AuthorPlan(
+            ConfigPhysicalPlanType.ListUser, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
+    AuthorPlan listRolePlan =
+        new AuthorPlan(
+            ConfigPhysicalPlanType.ListRole, "", "", "", "", new HashSet<>(), 
new ArrayList<>());
+    Assert.assertEquals(
+        1, 
authorInfo.executeListRoles(listRolePlan).getPermissionInfo().get("role").size());
+    Assert.assertEquals(
+        2, 
authorInfo.executeListUsers(listUserPlan).getPermissionInfo().get("user").size());
     Assert.assertTrue(authorInfo.processTakeSnapshot(snapshotDir));
     authorInfo.clear();
     authorInfo.processLoadSnapshot(snapshotDir);
-    Assert.assertEquals(1, 
authorInfo.executeListRole().getPermissionInfo().get("role").size());
-    Assert.assertEquals(2, 
authorInfo.executeListUser().getPermissionInfo().get("user").size());
+    Assert.assertEquals(
+        1, 
authorInfo.executeListRoles(listRolePlan).getPermissionInfo().get("role").size());
+    Assert.assertEquals(
+        2, 
authorInfo.executeListUsers(listUserPlan).getPermissionInfo().get("user").size());
   }
 
   @Test
diff --git 
a/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
 
b/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
index 1506a6ea00..98053bfa08 100644
--- 
a/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
+++ 
b/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
@@ -912,7 +912,7 @@ public class ConfigNodeRPCServiceProcessorTest {
     // list all role of user
     authorizerReq =
         new TAuthorizerReq(
-            AuthorOperator.AuthorType.LIST_USER_ROLES.ordinal(),
+            AuthorOperator.AuthorType.LIST_ROLE.ordinal(),
             "tempuser0",
             "",
             "",
@@ -929,7 +929,7 @@ public class ConfigNodeRPCServiceProcessorTest {
     // list all user of role
     authorizerReq =
         new TAuthorizerReq(
-            AuthorOperator.AuthorType.LIST_ROLE_USERS.ordinal(),
+            AuthorOperator.AuthorType.LIST_USER.ordinal(),
             "",
             "temprole0",
             "",
diff --git a/docs/UserGuide/Administration-Management/Administration.md 
b/docs/UserGuide/Administration-Management/Administration.md
index 7eae10a4fe..368fe40b47 100644
--- a/docs/UserGuide/Administration-Management/Administration.md
+++ b/docs/UserGuide/Administration-Management/Administration.md
@@ -256,6 +256,13 @@ LIST USER
 Eg: IoTDB > LIST USER
 ```
 
+* List User of Specific Role
+
+```
+LIST USER OF ROLE <roleName>;
+Eg: IoTDB > LIST USER OF ROLE `roleuser`;
+```
+
 * List Roles
 
 ```
@@ -263,7 +270,21 @@ LIST ROLE
 Eg: IoTDB > LIST ROLE
 ```
 
-* List Related Privileges of Users(On Specific Path)
+* List Roles of Specific User
+
+```
+LIST ROLE OF USER <username> ;  
+Eg: IoTDB > LIST ROLE OF USER `tempuser`;
+```
+
+* List All Privileges of Users
+
+```
+LIST PRIVILEGES USER <username> ;   
+Eg: IoTDB > LIST PRIVILEGES USER `tempuser`;
+```
+
+* List Related Privileges of Users(On Specific Paths)
 
 ```
 LIST PRIVILEGES USER <username> ON <paths>;
@@ -287,14 +308,14 @@ Total line number = 2
 It costs 0.005s
 ```
 
-* List Privileges of Roles
+* List All Privileges of Roles
 
 ```
-LIST ROLE PRIVILEGES <roleName>
-Eg: IoTDB > LIST ROLE PRIVILEGES `actor`;
+LIST PRIVILEGES ROLE <roleName>
+Eg: IoTDB > LIST PRIVILEGES ROLE `actor`;
 ```
 
-* List Related Privileges of Roles(On Specific Path)
+* List Related Privileges of Roles(On Specific Paths)
 
 ```
 LIST PRIVILEGES ROLE <roleName> ON <paths>;    
@@ -316,27 +337,6 @@ Total line number = 1
 It costs 0.005s
 ```
 
-* List Privileges of Users
-
-```
-LIST USER PRIVILEGES <username> ;   
-Eg: IoTDB > LIST USER PRIVILEGES `tempuser`;
-```
-
-* List Roles of User
-
-```
-LIST ALL ROLE OF USER <username> ;  
-Eg: IoTDB > LIST ALL ROLE OF USER `tempuser`;
-```
-
-* List Users of Role
-
-```
-LIST ALL USER OF ROLE <roleName>;
-Eg: IoTDB > LIST ALL USER OF ROLE `roleuser`;
-```
-
 * Alter Password
 
 ```
@@ -361,39 +361,40 @@ At the same time, changes to roles are immediately 
reflected on all users who ow
 
 **List of privileges Included in the System**
 
-|privilege Name|Interpretation|Example|
-|:---|:---|----|
-|SET\_STORAGE\_GROUP|set storage groups; path dependent|Eg: `set storage group 
to root.ln;`|
-|DELETE\_STORAGE\_GROUP|delete storage groups; path dependent|Eg: `delete 
storage group root.ln;`|
-|CREATE\_TIMESERIES|create timeseries; path dependent|Eg1: create 
timeseries<br />`create timeseries root.ln.wf02.status with 
datatype=BOOLEAN,encoding=PLAIN;`<br />Eg2: create aligned timeseries<br 
/>`create aligned timeseries root.ln.device1(latitude FLOAT encoding=PLAIN 
compressor=SNAPPY, longitude FLOAT encoding=PLAIN compressor=SNAPPY);`|
-|INSERT\_TIMESERIES|insert data; path dependent|Eg1: `insert into 
root.ln.wf02(timestamp,status) values(1,true);`<br />Eg2: `insert into 
root.sg1.d1(time, s1, s2) aligned values(1, 1, 1)`|
-|READ\_TIMESERIES|query data; path dependent|Eg1: `show storage group;` <br 
/>Eg2: `show child paths root.ln, show child nodes root.ln;`<br />Eg3: `show 
devices;`<br />Eg4: `show timeseries root.**;`<br />Eg5: `show schema 
templates;`<br />Eg6: `show all ttl`<br />Eg7: 
[Query-Data](../Query-Data/Overview.md)(The query statements under this section 
all use this permission)<br />Eg8: CVS format data export<br 
/>`./export-csv.bat -h 127.0.0.1 -p 6667 -u tempuser -pw root -td ./`<br />Eg9: 
P [...]
-|DELETE\_TIMESERIES|delete data or timeseries; path dependent|Eg1: delete 
timeseries<br />`delete timeseries root.ln.wf01.wt01.status`<br />Eg2: delete 
data<br />`delete from root.ln.wf02.wt02.status where time < 10`|
-|CREATE\_USER|create users; path independent|Eg: `create user thulab 
'passwd';`|
-|DELETE\_USER|delete users; path independent|Eg: `drop user xiaoming;`|
-|MODIFY\_PASSWORD|modify passwords for all users; path independent; (Those who 
do not have this privilege can still change their own asswords. )|Eg: `alter 
user tempuser SET PASSWORD 'newpwd';`|
-|LIST\_USER|list all users; list a user's privileges; list a user's roles; 
list users of Role with four kinds of operation privileges; path 
independent|Eg1: `list user;`<br />Eg2: `list privileges user 'admin' on 
root.sgcc.**;`<br />Eg3: `list user privileges admin;`<br />Eg4: `list all user 
of role 'admin';`|
-|GRANT\_USER\_PRIVILEGE|grant user privileges; path independent|Eg:  `grant 
user tempuser privileges DELETE_TIMESERIES on root.ln.**;`|
-|REVOKE\_USER\_PRIVILEGE|revoke user privileges; path independent|Eg:  `revoke 
user tempuser privileges DELETE_TIMESERIES on root.ln.**;`|
-|GRANT\_USER\_ROLE|grant user roles; path independent|Eg:  `grant temprole to 
tempuser;`|
-|REVOKE\_USER\_ROLE|revoke user roles; path independent|Eg:  `revoke temprole 
from tempuser;`|
-|CREATE\_ROLE|create roles; path independent|Eg:  `create role admin;`|
-|DELETE\_ROLE|delete roles; path independent|Eg: `drop role admin;`|
-|LIST\_ROLE|list all roles; list the privileges of a role; list the three 
kinds of operation privileges of all users owning a role; path independent|Eg1: 
`list role`<br />Eg2: `list role privileges actor;`<br />Eg3: `list privileges 
role wirte_role ON root.sgcc;`<br />Eg4: `list all role of user admin;`|
-|GRANT\_ROLE\_PRIVILEGE|grant role privileges; path independent|Eg: `grant 
role temprole privileges DELETE_TIMESERIES ON root.ln.**;`|
-|REVOKE\_ROLE\_PRIVILEGE|revoke role privileges; path independent|Eg: `revoke 
role temprole privileges DELETE_TIMESERIES ON root.ln.**;`|
-|CREATE_FUNCTION|register UDFs; path independent|Eg: `create function example 
AS 'org.apache.iotdb.udf.UDTFExample';`|
-|DROP_FUNCTION|deregister UDFs; path independent|Eg: `drop function example`|
-|CREATE_TRIGGER|create triggers; path dependent|Eg1: `CREATE TRIGGER 
<TRIGGER-NAME> BEFORE INSERT ON <FULL-PATH> AS <CLASSNAME>`<br />Eg2: `CREATE 
TRIGGER <TRIGGER-NAME> AFTER INSERT ON <FULL-PATH> AS <CLASSNAME>`|
-|DROP_TRIGGER|drop triggers; path dependent|Eg: `drop trigger 
'alert-listener-sg1d1s1'`|
-|START_TRIGGER|start triggers; path dependent|Eg: `start trigger 
lert-listener-sg1d1s1'`|
-|STOP_TRIGGER|stop triggers; path dependent|Eg: `stop trigger 
'alert-listener-sg1d1s1'`|
-|CREATE_CONTINUOUS_QUERY|create continuous queries; path independent|Eg: 
`select s1, s1 into t1, t2 from root.sg.d1`|
-|DROP_CONTINUOUS_QUERY|drop continuous queries; path independent|Eg1: `DROP 
CONTINUOUS QUERY cq3`<br />Eg2: `DROP CQ cq3`|
-|UPDATE_TEMPLATE|create, drop, append and prune schema template; path 
independent|Eg1: `create schema template t1(s1 int32)`
-|READ_TEMPLATE|show schema templates and show nodes in schema template; path 
independent|Eg1: `show schema templates`<br/>Eg2: `show nodes in template t1` 
-|APPLY_TEMPLATE|set, unset and activate schema template; path dependent|Eg1: 
`set schema template t1 to root.sg.d`<br/>Eg2: `create timeseries of schema 
template on root.sg.d`
-|READ_TEMPLATE_APPLICATION|show paths set and using schema template; path 
independent|Eg1: `show paths set schema template t1`<br/>Eg2: `show paths using 
schema template t1`
+|privilege Name|Interpretation| Example                                        
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|:---|:---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [...]
+|SET\_STORAGE\_GROUP|set storage groups; path dependent| Eg: `set storage 
group to root.ln;`                                                              
                                                                                
                                                                                
                                                                                
                                                                                
                   [...]
+|DELETE\_STORAGE\_GROUP|delete storage groups; path dependent| Eg: `delete 
storage group root.ln;`                                                         
                                                                                
                                                                                
                                                                                
                                                                                
                  [...]
+|CREATE\_TIMESERIES|create timeseries; path dependent| Eg1: create 
timeseries<br />`create timeseries root.ln.wf02.status with 
datatype=BOOLEAN,encoding=PLAIN;`<br />Eg2: create aligned timeseries<br 
/>`create aligned timeseries root.ln.device1(latitude FLOAT encoding=PLAIN 
compressor=SNAPPY, longitude FLOAT encoding=PLAIN compressor=SNAPPY);`          
                                                                                
                                                          [...]
+|INSERT\_TIMESERIES|insert data; path dependent| Eg1: `insert into 
root.ln.wf02(timestamp,status) values(1,true);`<br />Eg2: `insert into 
root.sg1.d1(time, s1, s2) aligned values(1, 1, 1)`                              
                                                                                
                                                                                
                                                                                
                                   [...]
+|ALTER\_TIMESERIES|alter timeseries; path dependent| Eg1: `alter timeseries 
root.turbine.d1.s1 ADD TAGS tag3=v3, tag4=v4;`<br />Eg2: `ALTER timeseries 
root.turbine.d1.s1 UPSERT ALIAS=newAlias TAGS(tag2=newV2, tag3=v3) 
ATTRIBUTES(attr3=v3, attr4=v4);`                                                
                                                                                
                                                                                
                                   [...]
+|READ\_TIMESERIES|query data; path dependent| Eg1: `show storage group;` <br 
/>Eg2: `show child paths root.ln, show child nodes root.ln;`<br />Eg3: `show 
devices;`<br />Eg4: `show timeseries root.**;`<br />Eg5: `show schema 
templates;`<br />Eg6: `show all ttl`<br />Eg7: 
[Query-Data](../Query-Data/Overview.md)(The query statements under this section 
all use this permission)<br />Eg8: CVS format data export<br 
/>`./export-csv.bat -h 127.0.0.1 -p 6667 -u tempuser -pw root -td ./`<br />Eg9: 
 [...]
+|DELETE\_TIMESERIES|delete data or timeseries; path dependent| Eg1: delete 
timeseries<br />`delete timeseries root.ln.wf01.wt01.status`<br />Eg2: delete 
data<br />`delete from root.ln.wf02.wt02.status where time < 10`                
                                                                                
                                                                                
                                                                                
                    [...]
+|CREATE\_USER|create users; path independent| Eg: `create user thulab 
'passwd';`                                                                      
                                                                                
                                                                                
                                                                                
                                                                                
                       [...]
+|DELETE\_USER|delete users; path independent| Eg: `drop user xiaoming;`        
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|MODIFY\_PASSWORD|modify passwords for all users; path independent; (Those who 
do not have this privilege can still change their own asswords. )| Eg: `alter 
user tempuser SET PASSWORD 'newpwd';`                                           
                                                                                
                                                                                
                                                                                
                [...]
+|LIST\_USER|list all users; list a user's privileges; list a user's roles; 
list users of Role with four kinds of operation privileges; path independent| 
Eg1: `list user;`<br />Eg2: `list privileges user 'admin' on root.sgcc.**;`<br 
/>Eg3: `list user privileges admin;`<br />Eg4: `list all user of role 'admin';` 
                                                                                
                                                                                
                     [...]
+|GRANT\_USER\_PRIVILEGE|grant user privileges; path independent| Eg:  `grant 
user tempuser privileges DELETE_TIMESERIES on root.ln.**;`                      
                                                                                
                                                                                
                                                                                
                                                                                
                [...]
+|REVOKE\_USER\_PRIVILEGE|revoke user privileges; path independent| Eg:  
`revoke user tempuser privileges DELETE_TIMESERIES on root.ln.**;`              
                                                                                
                                                                                
                                                                                
                                                                                
                     [...]
+|GRANT\_USER\_ROLE|grant user roles; path independent| Eg:  `grant temprole to 
tempuser;`                                                                      
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|REVOKE\_USER\_ROLE|revoke user roles; path independent| Eg:  `revoke temprole 
from tempuser;`                                                                 
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|CREATE\_ROLE|create roles; path independent| Eg:  `create role admin;`        
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|DELETE\_ROLE|delete roles; path independent| Eg: `drop role admin;`           
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|LIST\_ROLE|list all roles; list the privileges of a role; list the three 
kinds of operation privileges of all users owning a role; path independent| 
Eg1: `list role`<br />Eg2: `list role privileges actor;`<br />Eg3: `list 
privileges role wirte_role ON root.sgcc;`<br />Eg4: `list all role of user 
admin;`                                                                         
                                                                                
                                   [...]
+|GRANT\_ROLE\_PRIVILEGE|grant role privileges; path independent| Eg: `grant 
role temprole privileges DELETE_TIMESERIES ON root.ln.**;`                      
                                                                                
                                                                                
                                                                                
                                                                                
                 [...]
+|REVOKE\_ROLE\_PRIVILEGE|revoke role privileges; path independent| Eg: `revoke 
role temprole privileges DELETE_TIMESERIES ON root.ln.**;`                      
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|CREATE_FUNCTION|register UDFs; path independent| Eg: `create function example 
AS 'org.apache.iotdb.udf.UDTFExample';`                                         
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|DROP_FUNCTION|deregister UDFs; path independent| Eg: `drop function example`  
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|CREATE_TRIGGER|create triggers; path dependent| Eg1: `CREATE TRIGGER 
<TRIGGER-NAME> BEFORE INSERT ON <FULL-PATH> AS <CLASSNAME>`<br />Eg2: `CREATE 
TRIGGER <TRIGGER-NAME> AFTER INSERT ON <FULL-PATH> AS <CLASSNAME>`              
                                                                                
                                                                                
                                                                                
                         [...]
+|DROP_TRIGGER|drop triggers; path dependent| Eg: `drop trigger 
'alert-listener-sg1d1s1'`                                                       
                                                                                
                                                                                
                                                                                
                                                                                
                              [...]
+|START_TRIGGER|start triggers; path dependent| Eg: `start trigger 
lert-listener-sg1d1s1'`                                                         
                                                                                
                                                                                
                                                                                
                                                                                
                           [...]
+|STOP_TRIGGER|stop triggers; path dependent| Eg: `stop trigger 
'alert-listener-sg1d1s1'`                                                       
                                                                                
                                                                                
                                                                                
                                                                                
                              [...]
+|CREATE_CONTINUOUS_QUERY|create continuous queries; path independent| Eg: 
`select s1, s1 into t1, t2 from root.sg.d1`                                     
                                                                                
                                                                                
                                                                                
                                                                                
                   [...]
+|DROP_CONTINUOUS_QUERY|drop continuous queries; path independent| Eg1: `DROP 
CONTINUOUS QUERY cq3`<br />Eg2: `DROP CQ cq3`                                   
                                                                                
                                                                                
                                                                                
                                                                                
                [...]
+|UPDATE_TEMPLATE|create, drop, append and prune schema template; path 
independent| Eg1: `create schema template t1(s1 int32)`                         
                                                                                
                                                                                
                                                                                
                                                                                
                       [...]
+|READ_TEMPLATE|show schema templates and show nodes in schema template; path 
independent| Eg1: `show schema templates`<br/>Eg2: `show nodes in template t1`  
                                                                                
                                                                                
                                                                                
                                                                                
                [...]
+|APPLY_TEMPLATE|set, unset and activate schema template; path dependent| Eg1: 
`set schema template t1 to root.sg.d`<br/>Eg2: `create timeseries of schema 
template on root.sg.d`                                                          
                                                                                
                                                                                
                                                                                
                   [...]
+|READ_TEMPLATE_APPLICATION|show paths set and using schema template; path 
independent| Eg1: `show paths set schema template t1`<br/>Eg2: `show paths 
using schema template t1`                                                       
                                                                                
                                                                                
                                                                                
                        [...]
 
 Note that the following SQL statements need to be granted multiple permissions 
before they can be used:
 
diff --git a/docs/zh/UserGuide/Administration-Management/Administration.md 
b/docs/zh/UserGuide/Administration-Management/Administration.md
index 98658f23a4..5a1feb537d 100644
--- a/docs/zh/UserGuide/Administration-Management/Administration.md
+++ b/docs/zh/UserGuide/Administration-Management/Administration.md
@@ -248,20 +248,41 @@ REVOKE <roleName> FROM <userName>;
 Eg: IoTDB > REVOKE `temprole` FROM tempuser;
 ```
 
-* 列出用户
+* 列出所有用户
 
 ```
 LIST USER
 Eg: IoTDB > LIST USER
 ```
 
-* 列出角色
+* 列出指定角色下所有用户
+
+```
+LIST USER OF ROLE <roleName>;
+Eg: IoTDB > LIST USER OF ROLE `roleuser`;
+```
+
+* 列出所有角色
 
 ```
 LIST ROLE
 Eg: IoTDB > LIST ROLE
 ```
 
+* 列出指定用户下所有角色
+
+```
+LIST ROLE OF USER <username> ;  
+Eg: IoTDB > LIST ROLE OF USER `tempuser`;
+```
+
+* 列出用户所有权限
+
+```
+LIST PRIVILEGES USER <username>;   
+Eg: IoTDB > LIST PRIVILEGES USER `tempuser`;
+```
+
 * 列出用户在具体路径上相关联的权限
 
 ```    
@@ -286,11 +307,11 @@ Total line number = 2
 It costs 0.005s
 ```
 
-* 列出角色权限
+* 列出角色所有权限
 
 ```
-LIST ROLE PRIVILEGES <roleName>
-Eg: IoTDB > LIST ROLE PRIVILEGES `actor`;
+LIST PRIVILEGES ROLE <roleName>;
+Eg: IoTDB > LIST PRIVILEGES ROLE `actor`;
 ```
 
 * 列出角色在具体路径上相关联的权限
@@ -315,27 +336,6 @@ Total line number = 1
 It costs 0.005s
 ```
 
-* 列出用户权限
-
-```
-LIST USER PRIVILEGES <username> ;   
-Eg: IoTDB > LIST USER PRIVILEGES `tempuser`;
-```
-
-* 列出用户所有的角色
-
-```
-LIST ALL ROLE OF USER <username> ;  
-Eg: IoTDB > LIST ALL ROLE OF USER `tempuser`;
-```
-
-* 列出所有用户的角色
-
-```
-LIST ALL USER OF ROLE <roleName>;
-Eg: IoTDB > LIST ALL USER OF ROLE `roleuser`;
-```
-
 * 更新密码
 
 ```
@@ -366,6 +366,7 @@ Eg: IoTDB > ALTER USER `tempuser` SET PASSWORD 'newpwd';
 |DELETE\_STORAGE\_GROUP|删除存储组。路径相关| Eg: `delete storage group root.ln;`        
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
 |CREATE\_TIMESERIES|创建时间序列。路径相关| Eg1: 创建时间序列<br />`create timeseries 
root.ln.wf02.status with datatype=BOOLEAN,encoding=PLAIN;`<br />Eg2: 
创建对齐时间序列<br />`create aligned timeseries root.ln.device1(latitude FLOAT 
encoding=PLAIN compressor=SNAPPY, longitude FLOAT encoding=PLAIN 
compressor=SNAPPY);`                                                            
                                                                                
                                                          [...]
 |INSERT\_TIMESERIES|插入数据。路径相关| Eg1: `insert into 
root.ln.wf02(timestamp,status) values(1,true);`<br />Eg2: `insert into 
root.sg1.d1(time, s1, s2) aligned values(1, 1, 1)`                              
                                                                                
                                                                                
                                                                                
                                                     [...]
+|ALTER\_TIMESERIES|修改时间序列标签。路径相关| Eg1: `alter timeseries root.turbine.d1.s1 
ADD TAGS tag3=v3, tag4=v4;`<br />Eg2: `ALTER timeseries root.turbine.d1.s1 
UPSERT ALIAS=newAlias TAGS(tag2=newV2, tag3=v3) ATTRIBUTES(attr3=v3, 
attr4=v4);`                                                                     
                                                                                
                                                                                
                                 [...]
 |READ\_TIMESERIES|查询数据。路径相关| Eg1: `show storage group;` <br />Eg2: `show child 
paths root.ln, show child nodes root.ln;`<br />Eg3: `show devices;`<br />Eg4: 
`show timeseries root.**;`<br />Eg5: `show schema templates;`<br />Eg6: `show 
all ttl`<br />Eg7: [数据查询](../Query-Data/Overview.md)(这一节之下的查询语句均使用该权限)<br 
/>Eg8: CVS格式数据导出<br />`./export-csv.bat -h 127.0.0.1 -p 6667 -u tempuser -pw 
root -td ./`<br />Eg9: 查询性能追踪<br />`tracing select * from root.**`<br />Eg10: 
UDF查询<br />`select example(* [...]
 |DELETE\_TIMESERIES|删除数据或时间序列。路径相关| Eg1: 删除时间序列<br />`delete timeseries 
root.ln.wf01.wt01.status`<br />Eg2: 删除数据<br />`delete from 
root.ln.wf02.wt02.status where time < 10`                                       
                                                                                
                                                                                
                                                                                
                                          [...]
 |CREATE\_USER|创建用户。路径无关| Eg: `create user thulab 'passwd';`                    
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
diff --git 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
index 25cef9c7e8..183c7576c3 100644
--- 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
+++ 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
@@ -959,7 +959,7 @@ public class IoTDBAuthorizationIT {
           "GRANT ROLE role1 PRIVILEGES 
READ_TIMESERIES,INSERT_TIMESERIES,DELETE_TIMESERIES ON root.j.**.k.*");
       adminStmt.execute("GRANT role1 TO user1");
 
-      ResultSet resultSet = adminStmt.executeQuery("LIST USER PRIVILEGES 
user1");
+      ResultSet resultSet = adminStmt.executeQuery("LIST PRIVILEGES USER 
user1");
       String ans =
           ",root.a.b : READ_TIMESERIES"
               + ",\n"
@@ -1028,7 +1028,7 @@ public class IoTDBAuthorizationIT {
 
         adminStmt.execute("REVOKE role1 from user1");
 
-        resultSet = adminStmt.executeQuery("LIST USER PRIVILEGES user1");
+        resultSet = adminStmt.executeQuery("LIST PRIVILEGES USER user1");
         ans = ",root.a.b : READ_TIMESERIES,\n";
         validateResultSet(resultSet, ans);
 
@@ -1053,7 +1053,7 @@ public class IoTDBAuthorizationIT {
 
     try {
       adminStmt.execute("CREATE ROLE role1");
-      ResultSet resultSet = adminStmt.executeQuery("LIST ROLE PRIVILEGES 
role1");
+      ResultSet resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE 
role1");
       String ans = "";
       try {
         // not granted list role privilege, should return empty
@@ -1064,7 +1064,7 @@ public class IoTDBAuthorizationIT {
         adminStmt.execute(
             "GRANT ROLE role1 PRIVILEGES 
READ_TIMESERIES,INSERT_TIMESERIES,DELETE_TIMESERIES ON root.d.b.c");
 
-        resultSet = adminStmt.executeQuery("LIST ROLE PRIVILEGES role1");
+        resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1");
         ans =
             "root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n"
                 + "root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n";
@@ -1077,7 +1077,7 @@ public class IoTDBAuthorizationIT {
         adminStmt.execute(
             "REVOKE ROLE role1 PRIVILEGES INSERT_TIMESERIES,DELETE_TIMESERIES 
ON root.a.b.c");
 
-        resultSet = adminStmt.executeQuery("LIST ROLE PRIVILEGES role1");
+        resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1");
         ans =
             "root.a.b.c : READ_TIMESERIES,\n"
                 + "root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n";
@@ -1117,7 +1117,7 @@ public class IoTDBAuthorizationIT {
       adminStmt.execute("GRANT zhazha TO chenduxiu");
       adminStmt.execute("GRANT hakase TO chenduxiu");
 
-      ResultSet resultSet = adminStmt.executeQuery("LIST ALL ROLE OF USER 
chenduxiu");
+      ResultSet resultSet = adminStmt.executeQuery("LIST ROLE OF USER 
chenduxiu");
       String ans = "xijing,\n" + "dalao,\n" + "shenshi,\n" + "zhazha,\n" + 
"hakase,\n";
       try {
         validateResultSet(resultSet, ans);
@@ -1125,7 +1125,7 @@ public class IoTDBAuthorizationIT {
         adminStmt.execute("REVOKE dalao FROM chenduxiu");
         adminStmt.execute("REVOKE hakase FROM chenduxiu");
 
-        resultSet = adminStmt.executeQuery("LIST ALL ROLE OF USER chenduxiu");
+        resultSet = adminStmt.executeQuery("LIST ROLE OF USER chenduxiu");
         ans = "xijing,\n" + "shenshi,\n" + "zhazha,\n";
         validateResultSet(resultSet, ans);
       } finally {
@@ -1173,7 +1173,7 @@ public class IoTDBAuthorizationIT {
       adminStmt.execute("CREATE USER RiverSky '2333333'");
       adminStmt.execute("GRANT zhazha TO RiverSky");
 
-      ResultSet resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE 
dalao");
+      ResultSet resultSet = adminStmt.executeQuery("LIST USER OF ROLE dalao");
       String ans =
           "DailySecurity,\n"
               + "DoubleLight,\n"
@@ -1192,12 +1192,12 @@ public class IoTDBAuthorizationIT {
       try {
         validateResultSet(resultSet, ans);
 
-        resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE zhazha");
+        resultSet = adminStmt.executeQuery("LIST USER OF ROLE zhazha");
         ans = "RiverSky,\n";
         validateResultSet(resultSet, ans);
 
         adminStmt.execute("REVOKE zhazha from RiverSky");
-        resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE zhazha");
+        resultSet = adminStmt.executeQuery("LIST USER OF ROLE zhazha");
         ans = "";
         validateResultSet(resultSet, ans);
       } finally {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java 
b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
index e965551040..ec3aaf1195 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
@@ -100,6 +100,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -1126,78 +1127,67 @@ public class LocalConfigNode {
         
AuthorOperator.AuthorType.values()[authorStatement.getAuthorType().ordinal()];
     switch (authorType) {
       case LIST_USER:
-        return executeListUser();
+        return executeListRoleUsers(authorStatement);
       case LIST_ROLE:
-        return executeListRole();
+        return executeListRoles(authorStatement);
       case LIST_USER_PRIVILEGE:
         return executeListUserPrivileges(authorStatement);
       case LIST_ROLE_PRIVILEGE:
         return executeListRolePrivileges(authorStatement);
-      case LIST_USER_ROLES:
-        return executeListUserRoles(authorStatement);
-      case LIST_ROLE_USERS:
-        return executeListRoleUsers(authorStatement);
       default:
         throw new AuthException("Unsupported operation " + authorType);
     }
   }
 
-  public Map<String, List<String>> executeListRole() {
-    List<String> roleList = iAuthorizer.listAllRoles();
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, roleList);
-    return permissionInfo;
-  }
-
-  public Map<String, List<String>> executeListUser() {
-    List<String> userList = iAuthorizer.listAllUsers();
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    permissionInfo.put(IoTDBConstant.COLUMN_USER, userList);
-    return permissionInfo;
-  }
-
   public Map<String, List<String>> executeListRoleUsers(AuthorStatement 
authorStatement)
       throws AuthException {
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    Role role;
-    try {
-      role = iAuthorizer.getRole(authorStatement.getRoleName());
-      if (role == null) {
-        throw new AuthException("No such role : " + 
authorStatement.getRoleName());
-      }
-    } catch (AuthException e) {
-      throw new AuthException(e);
-    }
-    List<String> roleUsersList = new ArrayList<>();
     List<String> userList = iAuthorizer.listAllUsers();
-    for (String userN : userList) {
-      User userObj = iAuthorizer.getUser(userN);
-      if (userObj != null && userObj.hasRole(authorStatement.getRoleName())) {
-        roleUsersList.add(userN);
+    if (authorStatement.getRoleName() != null && 
!authorStatement.getRoleName().isEmpty()) {
+      Role role;
+      try {
+        role = iAuthorizer.getRole(authorStatement.getRoleName());
+        if (role == null) {
+          throw new AuthException("No such role : " + 
authorStatement.getRoleName());
+        }
+      } catch (AuthException e) {
+        throw new AuthException(e);
+      }
+      Iterator<String> itr = userList.iterator();
+      while (itr.hasNext()) {
+        User userObj = iAuthorizer.getUser(itr.next());
+        if (userObj == null || 
!userObj.hasRole(authorStatement.getRoleName())) {
+          itr.remove();
+        }
       }
     }
-    permissionInfo.put(IoTDBConstant.COLUMN_USER, roleUsersList);
+
+    Map<String, List<String>> permissionInfo = new HashMap<>();
+    permissionInfo.put(IoTDBConstant.COLUMN_USER, userList);
     return permissionInfo;
   }
 
-  public Map<String, List<String>> executeListUserRoles(AuthorStatement 
authorStatement)
+  public Map<String, List<String>> executeListRoles(AuthorStatement 
authorStatement)
       throws AuthException {
-    Map<String, List<String>> permissionInfo = new HashMap<>();
-    User user;
-    try {
-      user = iAuthorizer.getUser(authorStatement.getUserName());
-      if (user == null) {
-        throw new AuthException("No such user : " + 
authorStatement.getUserName());
+    List<String> roleList = new ArrayList<>();
+    if (authorStatement.getUserName() == null || 
authorStatement.getUserName().isEmpty()) {
+      roleList.addAll(iAuthorizer.listAllRoles());
+    } else {
+      User user;
+      try {
+        user = iAuthorizer.getUser(authorStatement.getUserName());
+        if (user == null) {
+          throw new AuthException("No such user : " + 
authorStatement.getUserName());
+        }
+      } catch (AuthException e) {
+        throw new AuthException(e);
+      }
+      for (String roleN : user.getRoleList()) {
+        roleList.add(roleN);
       }
-    } catch (AuthException e) {
-      throw new AuthException(e);
-    }
-    List<String> userRoleList = new ArrayList<>();
-    for (String roleN : user.getRoleList()) {
-      userRoleList.add(roleN);
     }
 
-    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, userRoleList);
+    Map<String, List<String>> permissionInfo = new HashMap<>();
+    permissionInfo.put(IoTDBConstant.COLUMN_ROLE, roleList);
     return permissionInfo;
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index e11ada738b..c4dd40d837 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -1712,14 +1712,22 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
 
   @Override
   public Statement visitListUser(IoTDBSqlParser.ListUserContext ctx) {
-    return new AuthorStatement(AuthorOperator.AuthorType.LIST_USER);
+    AuthorStatement authorStatement = new 
AuthorStatement(AuthorOperator.AuthorType.LIST_USER);
+    if (ctx.roleName != null) {
+      authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
+    }
+    return authorStatement;
   }
 
   // List Roles
 
   @Override
   public Statement visitListRole(IoTDBSqlParser.ListRoleContext ctx) {
-    return new AuthorStatement(AuthorOperator.AuthorType.LIST_ROLE);
+    AuthorStatement authorStatement = new 
AuthorStatement(AuthorOperator.AuthorType.LIST_ROLE);
+    if (ctx.userName != null) {
+      authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
+    }
+    return authorStatement;
   }
 
   // List Privileges
@@ -1748,46 +1756,6 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
     return authorStatement;
   }
 
-  // List Privileges of Users
-
-  @Override
-  public Statement 
visitListUserPrivileges(IoTDBSqlParser.ListUserPrivilegesContext ctx) {
-    AuthorStatement authorStatement =
-        new AuthorStatement(AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
-    authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
-    return authorStatement;
-  }
-
-  // List Privileges of Roles
-
-  @Override
-  public Statement 
visitListRolePrivileges(IoTDBSqlParser.ListRolePrivilegesContext ctx) {
-    AuthorStatement authorStatement =
-        new AuthorStatement(AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
-    authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
-    return authorStatement;
-  }
-
-  // List Roles of Users
-
-  @Override
-  public Statement 
visitListAllRoleOfUser(IoTDBSqlParser.ListAllRoleOfUserContext ctx) {
-    AuthorStatement authorStatement =
-        new AuthorStatement(AuthorOperator.AuthorType.LIST_USER_ROLES);
-    authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
-    return authorStatement;
-  }
-
-  // List Users of Role
-
-  @Override
-  public Statement 
visitListAllUserOfRole(IoTDBSqlParser.ListAllUserOfRoleContext ctx) {
-    AuthorStatement authorStatement =
-        new AuthorStatement(AuthorOperator.AuthorType.LIST_ROLE_USERS);
-    authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
-    return authorStatement;
-  }
-
   private String[] parsePrivilege(IoTDBSqlParser.PrivilegesContext ctx) {
     List<IoTDBSqlParser.PrivilegeValueContext> privilegeList = 
ctx.privilegeValue();
     List<String> privileges = new ArrayList<>();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/AuthorStatement.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/AuthorStatement.java
index 8ea486b1ec..40d04f3a07 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/AuthorStatement.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/AuthorStatement.java
@@ -87,12 +87,6 @@ public class AuthorStatement extends Statement implements 
IConfigStatement {
       case LIST_ROLE_PRIVILEGE:
         this.setType(StatementType.LIST_ROLE_PRIVILEGE);
         break;
-      case LIST_USER_ROLES:
-        this.setType(StatementType.LIST_USER_ROLES);
-        break;
-      case LIST_ROLE_USERS:
-        this.setType(StatementType.LIST_ROLE_USERS);
-        break;
       case LIST_USER:
         this.setType(StatementType.LIST_USER);
         break;
@@ -192,8 +186,6 @@ public class AuthorStatement extends Statement implements 
IConfigStatement {
       case LIST_ROLE:
       case LIST_USER_PRIVILEGE:
       case LIST_ROLE_PRIVILEGE:
-      case LIST_USER_ROLES:
-      case LIST_ROLE_USERS:
         queryType = QueryType.READ;
         break;
       default:
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 2d3711b20f..ae9a3a6802 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -2239,16 +2239,18 @@ public class PlanExecutor implements IPlanExecutor {
     try {
       switch (authorType) {
         case LIST_ROLE:
-          dataSet = executeListRole(plan);
+          if (userName != null) {
+            dataSet = executeListUserRoles(userName);
+          } else {
+            dataSet = executeListRole(plan);
+          }
           break;
         case LIST_USER:
-          dataSet = executeListUser(plan);
-          break;
-        case LIST_ROLE_USERS:
-          dataSet = executeListRoleUsers(roleName);
-          break;
-        case LIST_USER_ROLES:
-          dataSet = executeListUserRoles(userName);
+          if (roleName != null) {
+            dataSet = executeListRoleUsers(roleName);
+          } else {
+            dataSet = executeListUser(plan);
+          }
           break;
         case LIST_ROLE_PRIVILEGE:
           dataSet = executeListRolePrivileges(roleName, nodeNameList);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/AuthorOperator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/AuthorOperator.java
index 4378872f5f..6e79d2b00d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/AuthorOperator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/AuthorOperator.java
@@ -143,9 +143,7 @@ public class AuthorOperator extends Operator {
     LIST_USER,
     LIST_ROLE,
     LIST_USER_PRIVILEGE,
-    LIST_ROLE_PRIVILEGE,
-    LIST_USER_ROLES,
-    LIST_ROLE_USERS;
+    LIST_ROLE_PRIVILEGE;
 
     /**
      * deserialize short number.
@@ -185,10 +183,6 @@ public class AuthorOperator extends Operator {
           return LIST_USER_PRIVILEGE;
         case 14:
           return LIST_ROLE_PRIVILEGE;
-        case 15:
-          return LIST_USER_ROLES;
-        case 16:
-          return LIST_ROLE_USERS;
         default:
           return null;
       }
@@ -231,10 +225,6 @@ public class AuthorOperator extends Operator {
           return 13;
         case LIST_ROLE_PRIVILEGE:
           return 14;
-        case LIST_USER_ROLES:
-          return 15;
-        case LIST_ROLE_USERS:
-          return 16;
         default:
           return -1;
       }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
index 06c1a6d9ec..6db520ad4a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
@@ -120,14 +120,6 @@ public class AuthorPlan extends PhysicalPlan {
         this.setQuery(true);
         this.setOperatorType(Operator.OperatorType.LIST_ROLE_PRIVILEGE);
         break;
-      case LIST_USER_ROLES:
-        this.setQuery(true);
-        this.setOperatorType(Operator.OperatorType.LIST_USER_ROLES);
-        break;
-      case LIST_ROLE_USERS:
-        this.setQuery(true);
-        this.setOperatorType(Operator.OperatorType.LIST_ROLE_USERS);
-        break;
       case LIST_USER:
         this.setQuery(true);
         this.setOperatorType(Operator.OperatorType.LIST_USER);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index b0a7aad469..7ac4e8d573 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -2097,14 +2097,24 @@ public class IoTDBSqlVisitor extends 
IoTDBSqlParserBaseVisitor<Operator> {
 
   @Override
   public Operator visitListUser(IoTDBSqlParser.ListUserContext ctx) {
-    return new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER);
+    if (ctx.roleName != null) {
+      operator.setRoleName(parseIdentifier(ctx.roleName.getText()));
+    }
+    return operator;
   }
 
   // List Roles
 
   @Override
   public Operator visitListRole(IoTDBSqlParser.ListRoleContext ctx) {
-    return new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE);
+    if (ctx.userName != null) {
+      operator.setUserName(parseIdentifier(ctx.userName.getText()));
+    }
+    return operator;
   }
 
   // List Privileges
@@ -2137,46 +2147,6 @@ public class IoTDBSqlVisitor extends 
IoTDBSqlParserBaseVisitor<Operator> {
     return operator;
   }
 
-  // List Privileges of Users
-
-  @Override
-  public Operator 
visitListUserPrivileges(IoTDBSqlParser.ListUserPrivilegesContext ctx) {
-    AuthorOperator operator =
-        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
-    operator.setUserName(parseIdentifier(ctx.userName.getText()));
-    return operator;
-  }
-
-  // List Privileges of Roles
-
-  @Override
-  public Operator 
visitListRolePrivileges(IoTDBSqlParser.ListRolePrivilegesContext ctx) {
-    AuthorOperator operator =
-        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
-    operator.setRoleName(parseIdentifier(ctx.roleName.getText()));
-    return operator;
-  }
-
-  // List Roles of Users
-
-  @Override
-  public Operator 
visitListAllRoleOfUser(IoTDBSqlParser.ListAllRoleOfUserContext ctx) {
-    AuthorOperator operator =
-        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER_ROLES);
-    operator.setUserName(parseIdentifier(ctx.userName.getText()));
-    return operator;
-  }
-
-  // List Users of Role
-
-  @Override
-  public Operator 
visitListAllUserOfRole(IoTDBSqlParser.ListAllUserOfRoleContext ctx) {
-    AuthorOperator operator =
-        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE_USERS);
-    operator.setRoleName(parseIdentifier(ctx.roleName.getText()));
-    return operator;
-  }
-
   private String[] parsePrivilege(IoTDBSqlParser.PrivilegesContext ctx) {
     List<IoTDBSqlParser.PrivilegeValueContext> privilegeList = 
ctx.privilegeValue();
     List<String> privileges = new ArrayList<>();
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/PlannerTest.java 
b/server/src/test/java/org/apache/iotdb/db/qp/PlannerTest.java
index c92c8750f0..c9cb46e7d3 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/PlannerTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/PlannerTest.java
@@ -285,7 +285,7 @@ public class PlannerTest {
   public void testRootPrivilege()
       throws QueryProcessException, StorageEngineException, IOException, 
InterruptedException,
           QueryFilterOptimizationException, MetadataException {
-    String listRootPrivilegeStatement = "list user privileges root";
+    String listRootPrivilegeStatement = "list privileges user root";
     PhysicalPlan physicalPlan = 
processor.parseSQLToPhysicalPlan(listRootPrivilegeStatement);
     PlanExecutor executor = new PlanExecutor();
     QueryDataSet queryDataSet = executor.processQuery(physicalPlan, null);

Reply via email to