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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5cc46a9  [IOTDB-96]Refactor author query (#179)
5cc46a9 is described below

commit 5cc46a97e48468cc905bb29bfee1a0d3fdbff622
Author: Jiang Tian <[email protected]>
AuthorDate: Fri May 31 10:12:25 2019 +0800

    [IOTDB-96]Refactor author query (#179)
    
    * use a more elegant way to return results of Authorization queries like 
'LIST USERS'
    
    * fix tests
    
    * improve client display
    
    * fix a test in windows
    
    * fix client display
---
 .../apache/iotdb/cli/client/AbstractClient.java    |   4 +
 .../apache/iotdb/db/auth/entity/PathPrivilege.java |   1 -
 .../org/apache/iotdb/db/conf/IoTDBConstant.java    |   4 +
 .../db/qp/executor/IQueryProcessExecutor.java      |   3 +-
 .../iotdb/db/qp/executor/OverflowQPExecutor.java   | 263 ++++++++-----
 .../iotdb/db/qp/executor/QueryProcessExecutor.java |  17 +-
 .../apache/iotdb/db/qp/physical/PhysicalPlan.java  |   4 +
 .../iotdb/db/qp/physical/sys/AuthorPlan.java       |   6 +
 .../apache/iotdb/db/query/dataset/AuthDataSet.java |  53 +++
 .../org/apache/iotdb/db/service/TSServiceImpl.java | 195 ++++++----
 .../iotdb/db/integration/IoTDBAuthorizationIT.java | 416 +++++++++++----------
 .../apache/iotdb/db/qp/utils/MemIntQpExecutor.java |   6 +
 .../org/apache/iotdb/jdbc/IoTDBQueryResultSet.java |   9 +
 .../java/org/apache/iotdb/jdbc/IoTDBStatement.java |   9 +-
 service-rpc/src/main/thrift/rpc.thrift             |   1 +
 15 files changed, 616 insertions(+), 375 deletions(-)

diff --git 
a/iotdb-cli/src/main/java/org/apache/iotdb/cli/client/AbstractClient.java 
b/iotdb-cli/src/main/java/org/apache/iotdb/cli/client/AbstractClient.java
index e4c4137..586a5d9 100644
--- a/iotdb-cli/src/main/java/org/apache/iotdb/cli/client/AbstractClient.java
+++ b/iotdb-cli/src/main/java/org/apache/iotdb/cli/client/AbstractClient.java
@@ -42,6 +42,7 @@ import org.apache.iotdb.cli.tool.ImportCsv;
 import org.apache.iotdb.jdbc.IoTDBConnection;
 import org.apache.iotdb.jdbc.IoTDBDatabaseMetadata;
 import org.apache.iotdb.jdbc.IoTDBMetadataResultSet;
+import org.apache.iotdb.jdbc.IoTDBQueryResultSet;
 import org.apache.iotdb.jdbc.IoTDBSQLException;
 import org.apache.iotdb.service.rpc.thrift.ServerProperties;
 import org.apache.thrift.TException;
@@ -188,6 +189,9 @@ public abstract class AbstractClient {
     if (!isShow && resultSetMetaData.getColumnTypeName(0) != null) {
       printTimestamp = 
!res.getMetaData().getColumnTypeName(0).equalsIgnoreCase(NEED_NOT_TO_PRINT_TIMESTAMP);
     }
+    if (res instanceof IoTDBQueryResultSet) {
+      printTimestamp = printTimestamp && ((IoTDBQueryResultSet) 
res).isIgnoreTimeStamp();
+    }
 
     // Output values
     while (res.next()) {
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/auth/entity/PathPrivilege.java 
b/iotdb/src/main/java/org/apache/iotdb/db/auth/entity/PathPrivilege.java
index 11579fe..4339cc1 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/auth/entity/PathPrivilege.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/auth/entity/PathPrivilege.java
@@ -101,7 +101,6 @@ public class PathPrivilege {
     for (Integer privilegeId : privileges) {
       builder.append(" ").append(PrivilegeType.values()[privilegeId]);
     }
-    builder.append("\n");
     return builder.toString();
   }
 }
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java 
b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
index 48e927f..e2775cd 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
@@ -59,4 +59,8 @@ public class IoTDBConstant {
 
   // for cluster, set read consistency level
   public static final String SET_READ_CONSISTENCY_LEVEL_PATTERN = 
"set\\s+read.*level.*";
+
+  public static final String ROLE = "Role";
+  public static final String USER = "User";
+  public static final String PRIVILEGE = "Privilege";
 }
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/IQueryProcessExecutor.java
 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/IQueryProcessExecutor.java
index 920aeef..6377f44 100644
--- 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/IQueryProcessExecutor.java
+++ 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/IQueryProcessExecutor.java
@@ -25,7 +25,6 @@ import org.apache.iotdb.db.exception.FileNodeManagerException;
 import org.apache.iotdb.db.exception.PathErrorException;
 import org.apache.iotdb.db.exception.ProcessorException;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
-import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.fill.IFill;
 import 
org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
@@ -51,7 +50,7 @@ public interface IQueryProcessExecutor {
    * @param queryPlan QueryPlan
    * @return QueryDataSet
    */
-  QueryDataSet processQuery(QueryPlan queryPlan, QueryContext context)
+  QueryDataSet processQuery(PhysicalPlan queryPlan, QueryContext context)
       throws IOException, FileNodeManagerException, PathErrorException,
       QueryFilterOptimizationException, ProcessorException;
 
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
index 9ca337e..e772bf5 100644
--- 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
+++ 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
@@ -18,6 +18,10 @@
  */
 package org.apache.iotdb.db.qp.executor;
 
+import static org.apache.iotdb.db.conf.IoTDBConstant.PRIVILEGE;
+import static org.apache.iotdb.db.conf.IoTDBConstant.ROLE;
+import static org.apache.iotdb.db.conf.IoTDBConstant.USER;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -41,6 +45,7 @@ import org.apache.iotdb.db.metadata.MNode;
 import org.apache.iotdb.db.monitor.MonitorConstants;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
+import org.apache.iotdb.db.qp.logical.sys.AuthorOperator.AuthorType;
 import org.apache.iotdb.db.qp.logical.sys.MetadataOperator;
 import org.apache.iotdb.db.qp.logical.sys.PropertyOperator;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -52,6 +57,7 @@ import org.apache.iotdb.db.qp.physical.sys.LoadDataPlan;
 import org.apache.iotdb.db.qp.physical.sys.MetadataPlan;
 import org.apache.iotdb.db.qp.physical.sys.PropertyPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.query.dataset.AuthDataSet;
 import org.apache.iotdb.db.query.executor.EngineQueryRouter;
 import org.apache.iotdb.db.query.fill.IFill;
 import org.apache.iotdb.db.utils.AuthUtils;
@@ -60,9 +66,12 @@ import 
org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.read.common.Field;
 import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
 import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
+import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.record.TSRecord;
 import org.apache.iotdb.tsfile.write.record.datapoint.DataPoint;
@@ -132,14 +141,16 @@ public class OverflowQPExecutor extends 
QueryProcessExecutor {
       case GRANT_USER_ROLE:
       case MODIFY_PASSWORD:
       case DELETE_USER:
+        AuthorPlan author = (AuthorPlan) plan;
+        return operateAuthor(author);
       case LIST_ROLE:
       case LIST_USER:
       case LIST_ROLE_PRIVILEGE:
       case LIST_ROLE_USERS:
       case LIST_USER_PRIVILEGE:
       case LIST_USER_ROLES:
-        AuthorPlan author = (AuthorPlan) plan;
-        return operateAuthor(author);
+        throw new ProcessorException(String.format("Author query %s is now 
allowed"
+            + " in processNonQuery", plan.getOperatorType()));
       case LOADDATA:
         LoadDataPlan loadData = (LoadDataPlan) plan;
         LoadDataUtils load = new LoadDataUtils();
@@ -312,15 +323,12 @@ public class OverflowQPExecutor extends 
QueryProcessExecutor {
     String newPassword = author.getNewPassword();
     Set<Integer> permissions = author.getPermissions();
     Path nodeName = author.getNodeName();
-    IAuthorizer authorizer = null;
+    IAuthorizer authorizer;
     try {
       authorizer = LocalFileAuthorizer.getInstance();
     } catch (AuthException e) {
       throw new ProcessorException(e);
     }
-    StringBuilder msg;
-    List<String> roleList;
-    List<String> userList;
     try {
       switch (authorType) {
         case UPDATE_USER:
@@ -394,94 +402,6 @@ public class OverflowQPExecutor extends 
QueryProcessExecutor {
             throw new ProcessorException("User " + userName + " does not have 
role " + roleName);
           }
           return true;
-        case LIST_ROLE:
-          roleList = authorizer.listAllRoles();
-          msg = new StringBuilder("Roles are : [ \n");
-          for (String role : roleList) {
-            msg.append(role).append("\n");
-          }
-          msg.append("]");
-          // TODO : use a more elegant way to pass message.
-          throw new ProcessorException(msg.toString());
-        case LIST_USER:
-          userList = authorizer.listAllUsers();
-          msg = new StringBuilder("Users are : [ \n");
-          for (String user : userList) {
-            msg.append(user).append("\n");
-          }
-          msg.append("]");
-          throw new ProcessorException(msg.toString());
-        case LIST_ROLE_USERS:
-          Role role = authorizer.getRole(roleName);
-          if (role == null) {
-            throw new ProcessorException("No such role : " + roleName);
-          }
-          userList = authorizer.listAllUsers();
-          msg = new StringBuilder("Users are : [ \n");
-          for (String userN : userList) {
-            User userObj = authorizer.getUser(userN);
-            if (userObj != null && userObj.hasRole(roleName)) {
-              msg.append(userN).append("\n");
-            }
-          }
-          msg.append("]");
-          throw new ProcessorException(msg.toString());
-        case LIST_USER_ROLES:
-          msg = new StringBuilder("Roles are : [ \n");
-          User user = authorizer.getUser(userName);
-          if (user != null) {
-            for (String roleN : user.getRoleList()) {
-              msg.append(roleN).append("\n");
-            }
-          } else {
-            throw new ProcessorException("No such user : " + userName);
-          }
-          msg.append("]");
-          throw new ProcessorException(msg.toString());
-        case LIST_ROLE_PRIVILEGE:
-          msg = new StringBuilder("Privileges are : [ \n");
-          role = authorizer.getRole(roleName);
-          if (role != null) {
-            for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
-              if (nodeName == null || AuthUtils
-                  .pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
-                msg.append(pathPrivilege.toString());
-              }
-            }
-          } else {
-            throw new ProcessorException("No such role : " + roleName);
-          }
-          msg.append("]");
-          throw new ProcessorException(msg.toString());
-        case LIST_USER_PRIVILEGE:
-          user = authorizer.getUser(userName);
-          if (user == null) {
-            throw new ProcessorException("No such user : " + userName);
-          }
-          msg = new StringBuilder("Privileges are : [ \n");
-          msg.append("From itself : {\n");
-          for (PathPrivilege pathPrivilege : user.getPrivilegeList()) {
-            if (nodeName == null || AuthUtils
-                .pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
-              msg.append(pathPrivilege.toString());
-            }
-          }
-          msg.append("}\n");
-          for (String roleN : user.getRoleList()) {
-            role = authorizer.getRole(roleN);
-            if (role != null) {
-              msg.append("From role ").append(roleN).append(" : {\n");
-              for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
-                if (nodeName == null
-                    || AuthUtils.pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
-                  msg.append(pathPrivilege.toString());
-                }
-              }
-              msg.append("}\n");
-            }
-          }
-          msg.append("]");
-          throw new ProcessorException(msg.toString());
         default:
           throw new ProcessorException("Unsupported operation " + authorType);
       }
@@ -679,4 +599,159 @@ public class OverflowQPExecutor extends 
QueryProcessExecutor {
     }
     return true;
   }
+
+  @Override
+  protected QueryDataSet processAuthorQuery(AuthorPlan plan, QueryContext 
context)
+      throws ProcessorException {
+    AuthorType authorType = plan.getAuthorType();
+    String userName = plan.getUserName();
+    String roleName = plan.getRoleName();
+    Path nodeName = plan.getNodeName();
+    IAuthorizer authorizer;
+    try {
+      authorizer = LocalFileAuthorizer.getInstance();
+    } catch (AuthException e) {
+      throw new ProcessorException(e);
+    }
+    List<Path> headerList = new ArrayList<>();
+    List<TSDataType> typeList = new ArrayList<>();
+    List<String> roleList;
+    List<String> userList;
+    AuthDataSet dataSet;
+    int index = 0;
+    try {
+      switch (authorType) {
+        case LIST_ROLE:
+          headerList.add(new Path(ROLE));
+          typeList.add(TSDataType.TEXT);
+          dataSet = new AuthDataSet(headerList, typeList);
+          roleList = authorizer.listAllRoles();
+          for (String role : roleList) {
+            RowRecord record = new RowRecord(index++);
+            Field field = new Field(TSDataType.TEXT);
+            field.setBinaryV(new Binary(role));
+            record.addField(field);
+            dataSet.putRecord(record);
+          }
+          break;
+        case LIST_USER:
+          userList = authorizer.listAllUsers();
+          headerList.add(new Path(USER));
+          typeList.add(TSDataType.TEXT);
+          dataSet = new AuthDataSet(headerList, typeList);
+          for (String user : userList) {
+            RowRecord record = new RowRecord(index++);
+            Field field = new Field(TSDataType.TEXT);
+            field.setBinaryV(new Binary(user));
+            record.addField(field);
+            dataSet.putRecord(record);
+          }
+          break;
+        case LIST_ROLE_USERS:
+          Role role = authorizer.getRole(roleName);
+          if (role == null) {
+            throw new ProcessorException("No such role : " + roleName);
+          }
+          headerList.add(new Path(USER));
+          typeList.add(TSDataType.TEXT);
+          dataSet = new AuthDataSet(headerList, typeList);
+          userList = authorizer.listAllUsers();
+          for (String userN : userList) {
+            User userObj = authorizer.getUser(userN);
+            if (userObj != null && userObj.hasRole(roleName)) {
+              RowRecord record = new RowRecord(index++);
+              Field field = new Field(TSDataType.TEXT);
+              field.setBinaryV(new Binary(userN));
+              record.addField(field);
+              dataSet.putRecord(record);
+            }
+          }
+          break;
+        case LIST_USER_ROLES:
+          User user = authorizer.getUser(userName);
+          if (user != null) {
+            headerList.add(new Path(ROLE));
+            typeList.add(TSDataType.TEXT);
+            dataSet = new AuthDataSet(headerList, typeList);
+            for (String roleN : user.getRoleList()) {
+              RowRecord record = new RowRecord(index++);
+              Field field = new Field(TSDataType.TEXT);
+              field.setBinaryV(new Binary(roleN));
+              record.addField(field);
+              dataSet.putRecord(record);
+            }
+          } else {
+            throw new ProcessorException("No such user : " + userName);
+          }
+          break;
+        case LIST_ROLE_PRIVILEGE:
+          role = authorizer.getRole(roleName);
+          if (role != null) {
+            headerList.add(new Path(PRIVILEGE));
+            typeList.add(TSDataType.TEXT);
+            dataSet = new AuthDataSet(headerList, typeList);
+            for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
+              if (nodeName == null || AuthUtils
+                  .pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
+                RowRecord record = new RowRecord(index++);
+                Field field = new Field(TSDataType.TEXT);
+                field.setBinaryV(new Binary(pathPrivilege.toString()));
+                record.addField(field);
+                dataSet.putRecord(record);
+              }
+            }
+          } else {
+            throw new ProcessorException("No such role : " + roleName);
+          }
+          break;
+        case LIST_USER_PRIVILEGE:
+          user = authorizer.getUser(userName);
+          if (user == null) {
+            throw new ProcessorException("No such user : " + userName);
+          }
+          headerList.add(new Path(ROLE));
+          headerList.add(new Path(PRIVILEGE));
+          typeList.add(TSDataType.TEXT);
+          typeList.add(TSDataType.TEXT);
+          dataSet = new AuthDataSet(headerList, typeList);
+          for (PathPrivilege pathPrivilege : user.getPrivilegeList()) {
+            if (nodeName == null || AuthUtils
+                .pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
+              RowRecord record = new RowRecord(index++);
+              Field roleF = new Field(TSDataType.TEXT);
+              roleF.setBinaryV(new Binary(""));
+              record.addField(roleF);
+              Field privilegeF = new Field(TSDataType.TEXT);
+              privilegeF.setBinaryV(new Binary(pathPrivilege.toString()));
+              record.addField(privilegeF);
+              dataSet.putRecord(record);
+            }
+          }
+          for (String roleN : user.getRoleList()) {
+            role = authorizer.getRole(roleN);
+            if (role != null) {
+              for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
+                if (nodeName == null
+                    || AuthUtils.pathBelongsTo(nodeName.getFullPath(), 
pathPrivilege.getPath())) {
+                  RowRecord record = new RowRecord(index++);
+                  Field roleF = new Field(TSDataType.TEXT);
+                  roleF.setBinaryV(new Binary(roleN));
+                  record.addField(roleF);
+                  Field privilegeF = new Field(TSDataType.TEXT);
+                  privilegeF.setBinaryV(new Binary(pathPrivilege.toString()));
+                  record.addField(privilegeF);
+                  dataSet.putRecord(record);
+                }
+              }
+            }
+          }
+          break;
+        default:
+          throw new ProcessorException("Unsupported operation " + authorType);
+      }
+    } catch (AuthException e) {
+      throw new ProcessorException(e.getMessage());
+    }
+    return dataSet;
+  }
 }
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
index 17768aa..94939e9 100644
--- 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
+++ 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
 import org.apache.iotdb.db.qp.physical.crud.FillQueryPlan;
 import org.apache.iotdb.db.qp.physical.crud.GroupByPlan;
 import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
+import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.executor.EngineQueryRouter;
 import org.apache.iotdb.db.query.executor.IEngineQueryRouter;
@@ -46,10 +47,24 @@ public abstract class QueryProcessExecutor implements 
IQueryProcessExecutor {
   protected IEngineQueryRouter queryRouter = new EngineQueryRouter();
 
   @Override
-  public QueryDataSet processQuery(QueryPlan queryPlan, QueryContext context)
+  public QueryDataSet processQuery(PhysicalPlan queryPlan, QueryContext 
context)
       throws IOException, FileNodeManagerException, PathErrorException,
       QueryFilterOptimizationException, ProcessorException {
 
+    if (queryPlan instanceof QueryPlan) {
+      return processDataQuery((QueryPlan) queryPlan, context);
+    } else if (queryPlan instanceof AuthorPlan) {
+      return processAuthorQuery((AuthorPlan) queryPlan, context);
+    } else {
+      throw new ProcessorException(String.format("Unrecognized query plan %s", 
queryPlan));
+    }
+  }
+
+  protected abstract QueryDataSet processAuthorQuery(AuthorPlan plan, 
QueryContext context)
+      throws ProcessorException;
+
+  private QueryDataSet processDataQuery(QueryPlan queryPlan, QueryContext 
context)
+      throws FileNodeManagerException, QueryFilterOptimizationException, 
PathErrorException, ProcessorException, IOException {
     QueryExpression queryExpression = 
QueryExpression.create().setSelectSeries(queryPlan.getPaths())
         .setExpression(queryPlan.getExpression());
     if (queryPlan instanceof GroupByPlan) {
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
index d2f7bb9..07d1e75 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
@@ -75,4 +75,8 @@ public abstract class PhysicalPlan implements Serializable {
   public void setProposer(String proposer) {
     this.proposer = proposer;
   }
+
+  public void setQuery(boolean query) {
+    isQuery = query;
+  }
 }
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java 
b/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
index 3ec812c..339f1e0 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/qp/physical/sys/AuthorPlan.java
@@ -99,21 +99,27 @@ public class AuthorPlan extends PhysicalPlan {
         this.setOperatorType(Operator.OperatorType.REVOKE_USER_ROLE);
         break;
       case LIST_USER_PRIVILEGE:
+        this.setQuery(true);
         this.setOperatorType(Operator.OperatorType.LIST_USER_PRIVILEGE);
         break;
       case LIST_ROLE_PRIVILEGE:
+        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);
         break;
       case LIST_ROLE:
+        this.setQuery(true);
         this.setOperatorType(Operator.OperatorType.LIST_ROLE);
         break;
       default:
diff --git 
a/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/AuthDataSet.java 
b/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/AuthDataSet.java
new file mode 100644
index 0000000..1846f12
--- /dev/null
+++ b/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/AuthDataSet.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.query.dataset;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.common.Path;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
+
+public class AuthDataSet extends QueryDataSet {
+
+  List<RowRecord> records = new ArrayList<>();
+  int index = 0;
+
+  public AuthDataSet(List<Path> paths,
+      List<TSDataType> dataTypes) {
+    super(paths, dataTypes);
+  }
+
+  @Override
+  public boolean hasNext() throws IOException {
+    return index < records.size();
+  }
+
+  @Override
+  public RowRecord next() throws IOException {
+    return records.get(index++);
+  }
+
+  public void putRecord(RowRecord newRecord) {
+    records.add(newRecord);
+  }
+}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java 
b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 592b009..4b3d62e 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -18,6 +18,10 @@
  */
 package org.apache.iotdb.db.service;
 
+import static org.apache.iotdb.db.conf.IoTDBConstant.PRIVILEGE;
+import static org.apache.iotdb.db.conf.IoTDBConstant.ROLE;
+import static org.apache.iotdb.db.conf.IoTDBConstant.USER;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.sql.Statement;
@@ -563,80 +567,12 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
       PhysicalPlan plan = processor.parseSQLToPhysicalPlan(statement, 
zoneIds.get());
       plan.setProposer(username.get());
 
-      List<Path> paths;
-      paths = plan.getPaths();
-
-      // check seriesPath exists
-      if (paths.isEmpty()) {
-        return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, 
"Timeseries does not exist.");
-      }
-
-      // check file level set
-
-      try {
-        checkFileLevelSet(paths);
-      } catch (PathErrorException e) {
-        LOGGER.error("meet error while checking file level.", e);
-        return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, 
e.getMessage());
-      }
-
-      // check permissions
-      if (!checkAuthorization(paths, plan)) {
-        return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS,
-            "No permissions for this query.");
-      }
-
-      TSExecuteStatementResp resp = 
getTSExecuteStatementResp(TS_StatusCode.SUCCESS_STATUS, "");
+      TSExecuteStatementResp resp;
       List<String> columns = new ArrayList<>();
-      // Restore column header of aggregate to func(column_name), only
-      // support single aggregate function for now
-      if (plan instanceof QueryPlan) {
-        switch (plan.getOperatorType()) {
-          case QUERY:
-          case FILL:
-            for (Path p : paths) {
-              columns.add(p.getFullPath());
-            }
-            break;
-          case AGGREGATION:
-          case GROUPBY:
-            List<String> aggregations = plan.getAggregations();
-            if (aggregations.size() != paths.size()) {
-              for (int i = 1; i < paths.size(); i++) {
-                aggregations.add(aggregations.get(0));
-              }
-            }
-            for (int i = 0; i < paths.size(); i++) {
-              columns.add(aggregations.get(i) + "(" + 
paths.get(i).getFullPath() + ")");
-            }
-            break;
-          default:
-            throw new TException("unsupported query type: " + 
plan.getOperatorType());
-        }
+      if (!(plan instanceof AuthorPlan)) {
+        resp = executeDataQuery(plan, columns);
       } else {
-        Operator.OperatorType type = plan.getOperatorType();
-        switch (type) {
-          case QUERY:
-          case FILL:
-            for (Path p : paths) {
-              columns.add(p.getFullPath());
-            }
-            break;
-          case AGGREGATION:
-          case GROUPBY:
-            List<String> aggregations = plan.getAggregations();
-            if (aggregations.size() != paths.size()) {
-              for (int i = 1; i < paths.size(); i++) {
-                aggregations.add(aggregations.get(0));
-              }
-            }
-            for (int i = 0; i < paths.size(); i++) {
-              columns.add(aggregations.get(i) + "(" + 
paths.get(i).getFullPath() + ")");
-            }
-            break;
-          default:
-            throw new TException("not support " + type + " in new read 
process");
-        }
+        resp = executeAuthQuery(plan, columns);
       }
 
       resp.setOperationType(plan.getOperatorType().toString());
@@ -655,6 +591,116 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
     }
   }
 
+  private TSExecuteStatementResp executeAuthQuery(PhysicalPlan plan, 
List<String> columns) {
+    TSExecuteStatementResp resp = 
getTSExecuteStatementResp(TS_StatusCode.SUCCESS_STATUS, "");
+    resp.ignoreTimeStamp = true;
+    AuthorPlan authorPlan = (AuthorPlan) plan;
+    switch (authorPlan.getAuthorType()) {
+      case LIST_ROLE:
+        columns.add(ROLE);
+        break;
+      case LIST_USER:
+        columns.add(USER);
+        break;
+      case LIST_ROLE_USERS:
+        columns.add(USER);
+        break;
+      case LIST_USER_ROLES:
+        columns.add(ROLE);
+        break;
+      case LIST_ROLE_PRIVILEGE:
+        columns.add(PRIVILEGE);
+        break;
+      case LIST_USER_PRIVILEGE:
+        columns.add(ROLE);
+        columns.add(PRIVILEGE);
+        break;
+      default:
+        return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, 
String.format("%s is not an "
+            + "auth query", authorPlan.getAuthorType()));
+    }
+    return resp;
+  }
+
+  private TSExecuteStatementResp executeDataQuery(PhysicalPlan plan, 
List<String> columns)
+      throws AuthException, TException {
+    List<Path> paths;
+    paths = plan.getPaths();
+
+    // check seriesPath exists
+    if (paths.isEmpty()) {
+      return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, "Timeseries 
does not exist.");
+    }
+
+    // check file level set
+
+    try {
+      checkFileLevelSet(paths);
+    } catch (PathErrorException e) {
+      LOGGER.error("meet error while checking file level.", e);
+      return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, 
e.getMessage());
+    }
+
+    // check permissions
+    if (!checkAuthorization(paths, plan)) {
+      return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS,
+          "No permissions for this query.");
+    }
+
+    TSExecuteStatementResp resp = 
getTSExecuteStatementResp(TS_StatusCode.SUCCESS_STATUS, "");
+    // Restore column header of aggregate to func(column_name), only
+    // support single aggregate function for now
+    if (plan instanceof QueryPlan) {
+      switch (plan.getOperatorType()) {
+        case QUERY:
+        case FILL:
+          for (Path p : paths) {
+            columns.add(p.getFullPath());
+          }
+          break;
+        case AGGREGATION:
+        case GROUPBY:
+          List<String> aggregations = plan.getAggregations();
+          if (aggregations.size() != paths.size()) {
+            for (int i = 1; i < paths.size(); i++) {
+              aggregations.add(aggregations.get(0));
+            }
+          }
+          for (int i = 0; i < paths.size(); i++) {
+            columns.add(aggregations.get(i) + "(" + paths.get(i).getFullPath() 
+ ")");
+          }
+          break;
+        default:
+          throw new TException("unsupported query type: " + 
plan.getOperatorType());
+      }
+    } else {
+      Operator.OperatorType type = plan.getOperatorType();
+      switch (type) {
+        case QUERY:
+        case FILL:
+          for (Path p : paths) {
+            columns.add(p.getFullPath());
+          }
+          break;
+        case AGGREGATION:
+        case GROUPBY:
+          List<String> aggregations = plan.getAggregations();
+          if (aggregations.size() != paths.size()) {
+            for (int i = 1; i < paths.size(); i++) {
+              aggregations.add(aggregations.get(0));
+            }
+          }
+          for (int i = 0; i < paths.size(); i++) {
+            columns.add(aggregations.get(i) + "(" + paths.get(i).getFullPath() 
+ ")");
+          }
+          break;
+        default:
+          throw new TException("not support " + type + " in new read process");
+      }
+    }
+    return resp;
+  }
+
   protected void checkFileLevelSet(List<Path> paths) throws PathErrorException 
{
     MManager.getInstance().checkFileLevel(paths);
   }
@@ -700,13 +746,15 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
     PhysicalPlan physicalPlan = queryStatus.get().get(statement);
     processor.getExecutor().setFetchSize(fetchSize);
 
+    QueryDataSet queryDataSet;
     QueryContext context = new 
QueryContext(QueryResourceManager.getInstance().assignJobId());
 
     initContextMap();
     contextMapLocal.get().put(req.queryId, context);
 
-    QueryDataSet queryDataSet = 
processor.getExecutor().processQuery((QueryPlan) physicalPlan,
+    queryDataSet = processor.getExecutor().processQuery(physicalPlan,
         context);
+
     queryRet.get().put(statement, queryDataSet);
     return queryDataSet;
   }
@@ -898,5 +946,6 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
     
properties.getSupportedTimeAggregationOperations().add(IoTDBConstant.MIN_TIME);
     return properties;
   }
+
 }
 
diff --git 
a/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java 
b/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
index 4484bc7..d9385ff 100644
--- 
a/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
+++ 
b/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertTrue;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import org.apache.iotdb.db.service.IoTDB;
@@ -654,37 +656,43 @@ public class IoTDBAuthorizationIT {
     Statement adminStmt = adminCon.createStatement();
 
     try {
-      adminStmt.execute("LIST USER");
-    } catch (SQLException e) {
-      assertEquals("Users are : [ \n" + "root\n" + "]", e.getMessage());
-    }
+      ResultSet resultSet = adminStmt.executeQuery("LIST USER");
+      String ans = String.format("0,root,\n");
+      validateResultSet(resultSet, ans);
 
-    for (int i = 0; i < 10; i++) {
-      adminStmt.execute("CREATE USER user" + i + " password" + i);
-    }
-    try {
-      adminStmt.execute("LIST USER");
-    } catch (SQLException e) {
-      assertEquals(
-          "Users are : [ \n" + "root\n" + "user0\n" + "user1\n" + "user2\n" + 
"user3\n" + "user4\n"
-              + "user5\n" + "user6\n" + "user7\n" + "user8\n" + "user9\n" + 
"]", e.getMessage());
-    }
-
-    for (int i = 0; i < 10; i++) {
-      if (i % 2 == 0) {
-        adminStmt.execute("DROP USER user" + i);
+      for (int i = 0; i < 10; i++) {
+        adminStmt.execute("CREATE USER user" + i + " password" + i);
       }
+      resultSet = adminStmt.executeQuery("LIST USER");
+      ans = "0,root,\n"
+          + "1,user0,\n"
+          + "2,user1,\n"
+          + "3,user2,\n"
+          + "4,user3,\n"
+          + "5,user4,\n"
+          + "6,user5,\n"
+          + "7,user6,\n"
+          + "8,user7,\n"
+          + "9,user8,\n"
+          + "10,user9,\n";
+      validateResultSet(resultSet, ans);
+
+      for (int i = 0; i < 10; i++) {
+        if (i % 2 == 0) {
+          adminStmt.execute("DROP USER user" + i);
+        }
+      }
+      resultSet = adminStmt.executeQuery("LIST USER");
+      ans = "0,root,\n"
+          + "1,user1,\n"
+          + "2,user3,\n"
+          + "3,user5,\n"
+          + "4,user7,\n"
+          + "5,user9,\n";
+      validateResultSet(resultSet, ans);
+    } finally {
+      adminCon.close();
     }
-    try {
-      adminStmt.execute("LIST USER");
-    } catch (SQLException e) {
-      assertEquals(
-          "Users are : [ \n" + "root\n" + "user1\n" + "user3\n" + "user5\n" + 
"user7\n" + "user9\n"
-              + "]",
-          e.getMessage());
-    }
-
-    adminCon.close();
   }
 
   @Test
@@ -695,36 +703,43 @@ public class IoTDBAuthorizationIT {
     Statement adminStmt = adminCon.createStatement();
 
     try {
-      adminStmt.execute("LIST ROLE");
-    } catch (SQLException e) {
-      assertEquals("Roles are : [ \n" + "]", e.getMessage());
-    }
+      ResultSet resultSet = adminStmt.executeQuery("LIST ROLE");
+      String ans = "";
+      validateResultSet(resultSet, ans);
 
-    for (int i = 0; i < 10; i++) {
-      adminStmt.execute("CREATE ROLE role" + i);
-    }
-    try {
-      adminStmt.execute("LIST ROLE");
-    } catch (SQLException e) {
-      assertEquals(
-          "Roles are : [ \n" + "role0\n" + "role1\n" + "role2\n" + "role3\n" + 
"role4\n" + "role5\n"
-              + "role6\n" + "role7\n" + "role8\n" + "role9\n" + "]", 
e.getMessage());
-    }
+      for (int i = 0; i < 10; i++) {
+        adminStmt.execute("CREATE ROLE role" + i);
+      }
 
-    for (int i = 0; i < 10; i++) {
-      if (i % 2 == 0) {
-        adminStmt.execute("DROP ROLE role" + i);
+      resultSet = adminStmt.executeQuery("LIST ROLE");
+      ans = "0,role0,\n"
+          + "1,role1,\n"
+          + "2,role2,\n"
+          + "3,role3,\n"
+          + "4,role4,\n"
+          + "5,role5,\n"
+          + "6,role6,\n"
+          + "7,role7,\n"
+          + "8,role8,\n"
+          + "9,role9,\n";
+      validateResultSet(resultSet, ans);
+
+      for (int i = 0; i < 10; i++) {
+        if (i % 2 == 0) {
+          adminStmt.execute("DROP ROLE role" + i);
+        }
       }
-    }
-    try {
-      adminStmt.execute("LIST ROLE");
-    } catch (SQLException e) {
-      assertEquals(
-          "Roles are : [ \n" + "role1\n" + "role3\n" + "role5\n" + "role7\n" + 
"role9\n" + "]",
-          e.getMessage());
-    }
+      resultSet = adminStmt.executeQuery("LIST ROLE");
+      ans = "0,role1,\n"
+          + "1,role3,\n"
+          + "2,role5,\n"
+          + "3,role7,\n"
+          + "4,role9,\n";
+      validateResultSet(resultSet, ans);
 
-    adminCon.close();
+    } finally {
+      adminCon.close();
+    }
   }
 
   @Test
@@ -734,56 +749,44 @@ public class IoTDBAuthorizationIT {
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", 
"root");
     Statement adminStmt = adminCon.createStatement();
 
-    adminStmt.execute("CREATE USER user1 password1");
-    adminStmt.execute("GRANT USER user1 PRIVILEGES 'READ_TIMESERIES' ON 
root.a.b");
-    adminStmt.execute("CREATE ROLE role1");
-    adminStmt.execute(
-        "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.a.b.c");
-    adminStmt.execute(
-        "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.d.b.c");
-    adminStmt.execute("GRANT role1 TO user1");
-
-    try {
-      adminStmt.execute("LIST USER PRIVILEGES  user1");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n" + "From itself : {\n" + "root.a.b : 
READ_TIMESERIES\n" + "}\n"
-              + "From role role1 : {\n"
-              + "root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n"
-              + "root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n" + "}\n" + "]",
-          e.getMessage());
-    }
-
-    try {
-      adminStmt.execute("LIST PRIVILEGES USER user1 ON root.a.b.c");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n" + "From itself : {\n" + "root.a.b : 
READ_TIMESERIES\n" + "}\n"
-              + "From role role1 : {\n"
-              + "root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n" + "}\n" + "]",
-          e.getMessage());
-    }
-
-    adminStmt.execute("REVOKE role1 from user1");
-    try {
-      adminStmt.execute("LIST USER PRIVILEGES  user1");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n" + "From itself : {\n" + "root.a.b : 
READ_TIMESERIES\n" + "}\n"
-              + "]",
-          e.getMessage());
-    }
-
     try {
-      adminStmt.execute("LIST PRIVILEGES USER user1 ON root.a.b.c");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n" + "From itself : {\n" + "root.a.b : 
READ_TIMESERIES\n" + "}\n"
-              + "]",
-          e.getMessage());
+      adminStmt.execute("CREATE USER user1 password1");
+      adminStmt.execute("GRANT USER user1 PRIVILEGES 'READ_TIMESERIES' ON 
root.a.b");
+      adminStmt.execute("CREATE ROLE role1");
+      adminStmt.execute(
+          "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.a.b.c");
+      adminStmt.execute(
+          "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.d.b.c");
+      adminStmt.execute("GRANT role1 TO user1");
+
+      ResultSet resultSet = adminStmt.executeQuery("LIST USER PRIVILEGES  
user1");
+      String ans = "0,,root.a.b : READ_TIMESERIES"
+          + ",\n"
+          + "1,role1,root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES"
+          + ",\n"
+          + "2,role1,root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES"
+          + ",\n";
+      validateResultSet(resultSet, ans);
+
+      resultSet = adminStmt.executeQuery("LIST PRIVILEGES USER user1 ON 
root.a.b.c");
+      ans = "0,,root.a.b : READ_TIMESERIES"
+          + ",\n"
+          + "1,role1,root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES"
+          + ",\n";
+      validateResultSet(resultSet, ans);
+
+      adminStmt.execute("REVOKE role1 from user1");
+
+      resultSet = adminStmt.executeQuery("LIST USER PRIVILEGES  user1");
+      ans = "0,,root.a.b : READ_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
+
+      resultSet = adminStmt.executeQuery("LIST PRIVILEGES USER user1 ON 
root.a.b.c");
+      ans = "0,,root.a.b : READ_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
+    } finally {
+      adminCon.close();
     }
-
-    adminCon.close();
   }
 
   @Test
@@ -793,50 +796,36 @@ public class IoTDBAuthorizationIT {
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", 
"root");
     Statement adminStmt = adminCon.createStatement();
 
-    adminStmt.execute("CREATE ROLE role1");
-    adminStmt.execute(
-        "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.a.b.c");
-    adminStmt.execute(
-        "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.d.b.c");
-
     try {
-      adminStmt.execute("LIST ROLE PRIVILEGES role1");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n"
-              + "root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n"
-              + "root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n" + "]",
-          e.getMessage());
-    }
+      adminStmt.execute("CREATE ROLE role1");
+      adminStmt.execute(
+          "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.a.b.c");
+      adminStmt.execute(
+          "GRANT ROLE role1 PRIVILEGES 
'READ_TIMESERIES','INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.d.b.c");
 
-    try {
-      adminStmt.execute("LIST PRIVILEGES ROLE role1 ON root.a.b.c");
-    } catch (SQLException e) {
-      assertEquals("Privileges are : [ \n"
-          + "root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n"
-          + "]", e.getMessage());
-    }
+      ResultSet resultSet = adminStmt.executeQuery("LIST ROLE PRIVILEGES 
role1");
+      String ans = "0,root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n"
+          + "1,root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
 
-    adminStmt.execute(
-        "REVOKE ROLE role1 PRIVILEGES 'INSERT_TIMESERIES','DELETE_TIMESERIES' 
ON root.a.b.c");
+      resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1 ON 
root.a.b.c");
+      ans = "0,root.a.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
 
-    try {
-      adminStmt.execute("LIST ROLE PRIVILEGES role1");
-    } catch (SQLException e) {
-      assertEquals(
-          "Privileges are : [ \n" + "root.a.b.c : READ_TIMESERIES\n"
-              + "root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES\n" + "]",
-          e.getMessage());
-    }
+      adminStmt.execute(
+          "REVOKE ROLE role1 PRIVILEGES 
'INSERT_TIMESERIES','DELETE_TIMESERIES' ON root.a.b.c");
 
-    try {
-      adminStmt.execute("LIST PRIVILEGES ROLE role1 ON root.a.b.c");
-    } catch (SQLException e) {
-      assertEquals("Privileges are : [ \n" + "root.a.b.c : READ_TIMESERIES\n" 
+ "]",
-          e.getMessage());
-    }
+      resultSet = adminStmt.executeQuery("LIST ROLE PRIVILEGES role1");
+      ans = "0,root.a.b.c : READ_TIMESERIES,\n"
+          + "1,root.d.b.c : INSERT_TIMESERIES READ_TIMESERIES 
DELETE_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
 
-    adminCon.close();
+      resultSet = adminStmt.executeQuery("LIST PRIVILEGES ROLE role1 ON 
root.a.b.c");
+      ans = "0,root.a.b.c : READ_TIMESERIES,\n";
+      validateResultSet(resultSet, ans);
+    } finally {
+      adminCon.close();
+    }
   }
 
   @Test
@@ -846,39 +835,40 @@ public class IoTDBAuthorizationIT {
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", 
"root");
     Statement adminStmt = adminCon.createStatement();
 
-    adminStmt.execute("CREATE USER chenduxiu orange");
+    try {
+      adminStmt.execute("CREATE USER chenduxiu orange");
 
-    adminStmt.execute("CREATE ROLE xijing");
-    adminStmt.execute("CREATE ROLE dalao");
-    adminStmt.execute("CREATE ROLE shenshi");
-    adminStmt.execute("CREATE ROLE zhazha");
-    adminStmt.execute("CREATE ROLE hakase");
+      adminStmt.execute("CREATE ROLE xijing");
+      adminStmt.execute("CREATE ROLE dalao");
+      adminStmt.execute("CREATE ROLE shenshi");
+      adminStmt.execute("CREATE ROLE zhazha");
+      adminStmt.execute("CREATE ROLE hakase");
 
-    adminStmt.execute("GRANT xijing TO chenduxiu");
-    adminStmt.execute("GRANT dalao TO chenduxiu");
-    adminStmt.execute("GRANT shenshi TO chenduxiu");
-    adminStmt.execute("GRANT zhazha TO chenduxiu");
-    adminStmt.execute("GRANT hakase TO chenduxiu");
+      adminStmt.execute("GRANT xijing TO chenduxiu");
+      adminStmt.execute("GRANT dalao TO chenduxiu");
+      adminStmt.execute("GRANT shenshi TO chenduxiu");
+      adminStmt.execute("GRANT zhazha TO chenduxiu");
+      adminStmt.execute("GRANT hakase TO chenduxiu");
 
-    try {
-      adminStmt.execute("LIST ALL ROLE OF USER chenduxiu");
-    } catch (SQLException e) {
-      assertEquals(
-          "Roles are : [ \n" + "xijing\n" + "dalao\n" + "shenshi\n" + 
"zhazha\n" + "hakase\n" + "]",
-          e.getMessage());
-    }
+      ResultSet resultSet = adminStmt.executeQuery("LIST ALL ROLE OF USER 
chenduxiu");
+      String ans = "0,xijing,\n"
+          + "1,dalao,\n"
+          + "2,shenshi,\n"
+          + "3,zhazha,\n"
+          + "4,hakase,\n";
+      validateResultSet(resultSet, ans);
 
-    adminStmt.execute("REVOKE dalao FROM chenduxiu");
-    adminStmt.execute("REVOKE hakase FROM chenduxiu");
+      adminStmt.execute("REVOKE dalao FROM chenduxiu");
+      adminStmt.execute("REVOKE hakase FROM chenduxiu");
 
-    try {
-      adminStmt.execute("LIST ALL ROLE OF USER chenduxiu");
-    } catch (SQLException e) {
-      assertEquals("Roles are : [ \n" + "xijing\n" + "shenshi\n" + "zhazha\n" 
+ "]",
-          e.getMessage());
+      resultSet = adminStmt.executeQuery("LIST ALL ROLE OF USER chenduxiu");
+      ans = "0,xijing,\n"
+          + "1,shenshi,\n"
+          + "2,zhazha,\n";
+      validateResultSet(resultSet, ans);
+    } finally {
+      adminCon.close();
     }
-
-    adminCon.close();
   }
 
   @Test
@@ -888,46 +878,68 @@ public class IoTDBAuthorizationIT {
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", 
"root");
     Statement adminStmt = adminCon.createStatement();
 
-    adminStmt.execute("CREATE ROLE dalao");
-    adminStmt.execute("CREATE ROLE zhazha");
-
-    String[] members = {"HighFly", "SunComparison", "Persistence", 
"GoodWoods", "HealthHonor",
-        "GoldLuck",
-        "DoubleLight", "Eastwards", "ScentEffusion", "Smart", "East", 
"DailySecurity", "Moon",
-        "RayBud",
-        "RiverSky"};
-
-    for (int i = 0; i < members.length - 1; i++) {
-      adminStmt.execute("CREATE USER " + members[i] + " 666666");
-      adminStmt.execute("GRANT dalao TO  " + members[i]);
-    }
-    adminStmt.execute("CREATE USER RiverSky 2333333");
-    adminStmt.execute("GRANT zhazha TO RiverSky");
-
     try {
-      adminStmt.execute("LIST ALL USER OF ROLE dalao");
-    } catch (SQLException e) {
-      assertEquals(
-          "Users are : [ \n" + "DailySecurity\n" + "DoubleLight\n" + "East\n" 
+ "Eastwards\n"
-              + "GoldLuck\n" + "GoodWoods\n" + "HealthHonor\n" + "HighFly\n" + 
"Moon\n"
-              + "Persistence\n"
-              + "RayBud\n" + "ScentEffusion\n" + "Smart\n" + "SunComparison\n" 
+ "]",
-          e.getMessage());
-    }
+      adminStmt.execute("CREATE ROLE dalao");
+      adminStmt.execute("CREATE ROLE zhazha");
 
-    try {
-      adminStmt.execute("LIST ALL USER OF ROLE zhazha");
-    } catch (SQLException e) {
-      assertEquals("Users are : [ \n" + "RiverSky\n" + "]", e.getMessage());
+      String[] members = {"HighFly", "SunComparison", "Persistence", 
"GoodWoods", "HealthHonor",
+          "GoldLuck",
+          "DoubleLight", "Eastwards", "ScentEffusion", "Smart", "East", 
"DailySecurity", "Moon",
+          "RayBud",
+          "RiverSky"};
+
+      for (int i = 0; i < members.length - 1; i++) {
+        adminStmt.execute("CREATE USER " + members[i] + " 666666");
+        adminStmt.execute("GRANT dalao TO  " + members[i]);
+      }
+      adminStmt.execute("CREATE USER RiverSky 2333333");
+      adminStmt.execute("GRANT zhazha TO RiverSky");
+
+      ResultSet resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE 
dalao");
+      String ans = "0,DailySecurity,\n"
+          + "1,DoubleLight,\n"
+          + "2,East,\n"
+          + "3,Eastwards,\n"
+          + "4,GoldLuck,\n"
+          + "5,GoodWoods,\n"
+          + "6,HealthHonor,\n"
+          + "7,HighFly,\n"
+          + "8,Moon,\n"
+          + "9,Persistence,\n"
+          + "10,RayBud,\n"
+          + "11,ScentEffusion,\n"
+          + "12,Smart,\n"
+          + "13,SunComparison,\n";
+      validateResultSet(resultSet, ans);
+
+      resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE zhazha");
+      ans = "0,RiverSky,\n";
+      validateResultSet(resultSet, ans);
+
+      adminStmt.execute("REVOKE zhazha from RiverSky");
+      resultSet = adminStmt.executeQuery("LIST ALL USER OF ROLE zhazha");
+      ans = "";
+      validateResultSet(resultSet, ans);
+
+    } finally {
+      adminCon.close();
     }
+  }
 
-    adminStmt.execute("REVOKE zhazha from RiverSky");
+  private void validateResultSet(ResultSet set, String ans) throws 
SQLException {
     try {
-      adminStmt.execute("LIST ALL USER OF ROLE zhazha");
-    } catch (SQLException e) {
-      assertEquals("Users are : [ \n" + "]", e.getMessage());
+      StringBuilder builder = new StringBuilder();
+      ResultSetMetaData metaData = set.getMetaData();
+      int colNum = metaData.getColumnCount();
+      while (set.next()) {
+        for (int i = 1; i <= colNum; i++) {
+          builder.append(set.getString(i)).append(",");
+        }
+        builder.append("\n");
+      }
+      assertEquals(ans, builder.toString());
+    } finally {
+      set.close();
     }
-
-    adminCon.close();
   }
 }
diff --git 
a/iotdb/src/test/java/org/apache/iotdb/db/qp/utils/MemIntQpExecutor.java 
b/iotdb/src/test/java/org/apache/iotdb/db/qp/utils/MemIntQpExecutor.java
index 71df644..7afced3 100644
--- a/iotdb/src/test/java/org/apache/iotdb/db/qp/utils/MemIntQpExecutor.java
+++ b/iotdb/src/test/java/org/apache/iotdb/db/qp/utils/MemIntQpExecutor.java
@@ -36,6 +36,7 @@ import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
 import org.apache.iotdb.db.qp.physical.crud.UpdatePlan;
+import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.executor.EngineQueryRouter;
 import org.apache.iotdb.db.query.fill.IFill;
@@ -206,6 +207,11 @@ public class MemIntQpExecutor extends QueryProcessExecutor 
{
     return 0;
   }
 
+  @Override
+  protected QueryDataSet processAuthorQuery(AuthorPlan plan, QueryContext 
context) {
+    return null;
+  }
+
   private class TestSeries {
 
     public TreeMap<Long, Integer> data = new TreeMap<>();
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBQueryResultSet.java 
b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBQueryResultSet.java
index c9b2b2c..58ed56e 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBQueryResultSet.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBQueryResultSet.java
@@ -87,6 +87,7 @@ public class IoTDBQueryResultSet implements ResultSet {
   // 0 means it is not constrained in sql, or the offset position has been 
reached
   private int rowsOffset = 0;
   private long queryId;
+  private boolean ignoreTimeStamp = false;
 
   /*
    * Combine maxRows and the LIMIT constraints. maxRowsOrRowsLimit = 0 means 
that neither maxRows
@@ -1245,4 +1246,12 @@ public class IoTDBQueryResultSet implements ResultSet {
     }
     return null;
   }
+
+  public boolean isIgnoreTimeStamp() {
+    return ignoreTimeStamp;
+  }
+
+  public void setIgnoreTimeStamp(boolean ignoreTimeStamp) {
+    this.ignoreTimeStamp = ignoreTimeStamp;
+  }
 }
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java 
b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
index fe56bbc..3c4e298 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
@@ -252,9 +252,12 @@ public class IoTDBStatement implements Statement {
       operationHandle = execResp.getOperationHandle();
       Utils.verifySuccess(execResp.getStatus());
       if (execResp.getOperationHandle().hasResultSet) {
-        resultSet = new IoTDBQueryResultSet(this, execResp.getColumns(), 
client,
+        IoTDBQueryResultSet resSet = new IoTDBQueryResultSet(this,
+            execResp.getColumns(), client,
             operationHandle, sql, execResp.getOperationType(),
             getColumnsType(execResp.getColumns()), queryId.getAndIncrement());
+        resSet.setIgnoreTimeStamp(execResp.ignoreTimeStamp);
+        this.resultSet = resSet;
         return true;
       }
       return false;
@@ -348,9 +351,11 @@ public class IoTDBStatement implements Statement {
     TSExecuteStatementResp execResp = client.executeQueryStatement(execReq);
     operationHandle = execResp.getOperationHandle();
     Utils.verifySuccess(execResp.getStatus());
-    resultSet = new IoTDBQueryResultSet(this, execResp.getColumns(), client,
+    IoTDBQueryResultSet resSet = new IoTDBQueryResultSet(this, 
execResp.getColumns(), client,
         operationHandle, sql, execResp.getOperationType(), 
getColumnsType(execResp.getColumns()),
         queryId.getAndIncrement());
+    resSet.setIgnoreTimeStamp(execResp.ignoreTimeStamp);
+    this.resultSet = resSet;
     return resultSet;
   }
 
diff --git a/service-rpc/src/main/thrift/rpc.thrift 
b/service-rpc/src/main/thrift/rpc.thrift
index de18cfe..6e857e8 100644
--- a/service-rpc/src/main/thrift/rpc.thrift
+++ b/service-rpc/src/main/thrift/rpc.thrift
@@ -73,6 +73,7 @@ struct TSExecuteStatementResp {
   // Column names in select statement of SQL
        3: optional list<string> columns
        4: optional string operationType
+       5: optional bool ignoreTimeStamp
 }
 
 enum TSProtocolVersion {

Reply via email to