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

haonan pushed a commit to branch rel/0.11
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/rel/0.11 by this push:
     new c229c55  [To rel/0.11] Add explain sql support (#2843)
c229c55 is described below

commit c229c55b03518e9dc00fa9c2b39b5a1cb9d12d6a
Author: Jackie Tien <[email protected]>
AuthorDate: Mon Mar 15 17:09:39 2021 +0800

    [To rel/0.11] Add explain sql support (#2843)
    
    Co-authored-by: Steve Yurong Su <[email protected]>
    Co-authored-by: wshao08 <[email protected]>
---
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4   |   7 +-
 grafana/pom.xml                                    |   2 +-
 jdbc/pom.xml                                       |   2 +-
 pom.xml                                            |   6 +-
 .../apache/iotdb/db/engine/cache/ChunkCache.java   |   7 +-
 .../iotdb/db/engine/cache/ChunkMetadataCache.java  |   9 +-
 .../db/engine/cache/TimeSeriesMetadataCache.java   |  15 +-
 .../iotdb/db/engine/modification/Modification.java |   9 +
 .../engine/storagegroup/StorageGroupProcessor.java |  17 +-
 .../db/engine/storagegroup/TsFileProcessor.java    |   4 +
 .../iotdb/db/metadata/mnode/MeasurementMNode.java  |   7 +
 .../main/java/org/apache/iotdb/db/qp/Planner.java  |  59 ++--
 .../org/apache/iotdb/db/qp/logical/Operator.java   | 101 +++++-
 .../apache/iotdb/db/qp/physical/PhysicalPlan.java  |  10 +
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 348 +++++++++++----------
 .../iotdb/db/query/context/QueryContext.java       |  11 +
 .../groupby/GroupByWithValueFilterDataSet.java     |   2 +-
 .../iotdb/db/query/executor/LastQueryExecutor.java |   5 +
 .../chunk/metadata/DiskChunkMetadataLoader.java    |  18 +-
 .../org/apache/iotdb/db/service/TSServiceImpl.java |   8 +-
 .../org/apache/iotdb/db/utils/FileLoaderUtils.java |   2 +-
 .../tsfile/file/metadata/TimeseriesMetadata.java   |  12 +
 22 files changed, 423 insertions(+), 238 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
index 4ff3c48..3530344 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4
@@ -20,7 +20,7 @@
 grammar SqlBase;
 
 singleStatement
-    : statement EOF
+    : EXPLAIN? statement EOF
     ;
 
 /*
@@ -1185,6 +1185,11 @@ DESC
 ASC
     : A S C
     ;
+
+EXPLAIN
+    : E X P L A I N
+    ;
+
 //============================
 // End of the keywords list
 //============================
diff --git a/grafana/pom.xml b/grafana/pom.xml
index 357350a..b605e65 100644
--- a/grafana/pom.xml
+++ b/grafana/pom.xml
@@ -165,7 +165,7 @@
                                     <transformer 
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                         
<resource>META-INF/spring.schemas</resource>
                                     </transformer>
-                                    <transformer 
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"
 />
+                                    <transformer 
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                                     <transformer 
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                         <mainClass>${start-class}</mainClass>
                                     </transformer>
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index b44bb46..090fdb0 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -223,7 +223,7 @@
                                                 </goals>
                                             </pluginExecutionFilter>
                                             <action>
-                                                <ignore />
+                                                <ignore/>
                                             </action>
                                         </pluginExecution>
                                     </pluginExecutions>
diff --git a/pom.xml b/pom.xml
index 3a15f55..ec39eb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -139,7 +139,7 @@
         <sonar.exclusions>**/generated-sources</sonar.exclusions>
         <!-- By default, the argLine is empty-->
         <gson.version>2.8.6</gson.version>
-        <argLine />
+        <argLine/>
     </properties>
     <!--
         if we claim dependencies in dependencyManagement, then we do not claim
@@ -599,7 +599,7 @@
                         <id>enforce-version-convergence</id>
                         <configuration>
                             <rules>
-                                <dependencyConvergence />
+                                <dependencyConvergence/>
                             </rules>
                         </configuration>
                         <goals>
@@ -645,7 +645,7 @@
                                 </requireJavaVersion>
                                 <!-- Disabled for now as it breaks the ability 
to build single modules -->
                                 <!--reactorModuleConvergence/-->
-                                <banVulnerable 
implementation="org.sonatype.ossindex.maven.enforcer.BanVulnerableDependencies" 
/>
+                                <banVulnerable 
implementation="org.sonatype.ossindex.maven.enforcer.BanVulnerableDependencies"/>
                             </rules>
                         </configuration>
                     </execution>
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkCache.java 
b/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkCache.java
index 6fccb8b..545b666 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkCache.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkCache.java
@@ -84,6 +84,11 @@ public class ChunkCache {
   }
 
   public Chunk get(ChunkMetadata chunkMetaData, TsFileSequenceReader reader) 
throws IOException {
+    return get(chunkMetaData, reader, false);
+  }
+
+  public Chunk get(ChunkMetadata chunkMetaData, TsFileSequenceReader reader, 
boolean debug)
+      throws IOException {
     if (!CACHE_ENABLE) {
       Chunk chunk = reader.readMemChunk(chunkMetaData);
       return new Chunk(chunk.getHeader(), chunk.getData().duplicate(),
@@ -118,7 +123,7 @@ public class ChunkCache {
       }
     }
 
-    if (config.isDebugOn()) {
+    if (debug) {
       DEBUG_LOGGER.info("get chunk from cache whose meta data is: " + 
chunkMetaData);
     }
     return new Chunk(chunk.getHeader(), chunk.getData().duplicate(), 
chunk.getDeleteIntervalList());
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkMetadataCache.java 
b/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkMetadataCache.java
index f8fd5f3..356da90 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkMetadataCache.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/cache/ChunkMetadataCache.java
@@ -102,11 +102,16 @@ public class ChunkMetadataCache {
     return ChunkMetadataCacheSingleton.INSTANCE;
   }
 
+  public List<ChunkMetadata> get(String filePath, Path seriesPath,
+      TimeseriesMetadata timeseriesMetadata) throws IOException {
+    return get(filePath, seriesPath, timeseriesMetadata, false);
+  }
+
   /**
    * get {@link ChunkMetadata}. THREAD SAFE.
    */
   public List<ChunkMetadata> get(String filePath, Path seriesPath,
-      TimeseriesMetadata timeseriesMetadata) throws IOException {
+      TimeseriesMetadata timeseriesMetadata, boolean debug) throws IOException 
{
     if (timeseriesMetadata == null) {
       return Collections.emptyList();
     }
@@ -144,7 +149,7 @@ public class ChunkMetadataCache {
         lock.writeLock().unlock();
       }
     }
-    if (config.isDebugOn()) {
+    if (debug) {
       DEBUG_LOGGER.info(
           "Chunk meta data list size: " + chunkMetadataList.size() + " key is: 
" + key.getString());
       chunkMetadataList.forEach(c -> DEBUG_LOGGER.info(c.toString()));
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
index d24160e..9aef0db 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
@@ -106,9 +106,14 @@ public class TimeSeriesMetadataCache {
     return TimeSeriesMetadataCache.TimeSeriesMetadataCacheHolder.INSTANCE;
   }
 
-  @SuppressWarnings("squid:S1860") // Suppress synchronize warning
   public TimeseriesMetadata get(TimeSeriesMetadataCacheKey key, Set<String> 
allSensors)
       throws IOException {
+    return get(key, allSensors, false);
+  }
+
+  @SuppressWarnings("squid:S1860") // Suppress synchronize warning
+  public TimeseriesMetadata get(TimeSeriesMetadataCacheKey key, Set<String> 
allSensors, boolean debug)
+      throws IOException {
     if (!CACHE_ENABLE) {
       // bloom filter part
       TsFileSequenceReader reader = 
FileReaderManager.getInstance().get(key.filePath, true);
@@ -134,7 +139,7 @@ public class TimeSeriesMetadataCache {
       cacheHitNum.incrementAndGet();
       printCacheLog(true);
     } else {
-      if (config.isDebugOn()) {
+      if (debug) {
         DEBUG_LOGGER.info(
             "Cache miss: " + key.device + "." + key.measurement + " metadata 
in file: "
                 + key.filePath);
@@ -159,7 +164,7 @@ public class TimeSeriesMetadataCache {
           TsFileSequenceReader reader = 
FileReaderManager.getInstance().get(key.filePath, true);
           BloomFilter bloomFilter = reader.readBloomFilter();
           if (bloomFilter != null && 
!bloomFilter.contains(path.getFullPath())) {
-            if (config.isDebugOn()) {
+            if (debug) {
               DEBUG_LOGGER.info("TimeSeries meta data {} is filter by 
bloomFilter!", key);
             }
             return null;
@@ -185,12 +190,12 @@ public class TimeSeriesMetadataCache {
       }
     }
     if (timeseriesMetadata == null) {
-      if (config.isDebugOn()) {
+      if (debug) {
         DEBUG_LOGGER.info("The file doesn't have this time series {}", key);
       }
       return null;
     } else {
-      if (config.isDebugOn()) {
+      if (debug) {
         DEBUG_LOGGER.info(
             "Get timeseries: {}. {} metadata in file: {} from cache: {}",
             key.device, key.measurement, key.filePath, timeseriesMetadata);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
index 3e3f46e..2c7a757 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/modification/Modification.java
@@ -94,4 +94,13 @@ public abstract class Modification {
   public int hashCode() {
     return Objects.hash(type, path, versionNum);
   }
+
+  @Override
+  public String toString() {
+    return "Modification{" +
+        "type=" + type +
+        ", path=" + path +
+        ", versionNum=" + versionNum +
+        '}';
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
index 751789f..41f5b2e 100755
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
@@ -1415,7 +1415,7 @@ public class StorageGroupProcessor {
       boolean isSeq)
       throws MetadataException {
 
-    if (config.isDebugOn()) {
+    if (context.isDebug()) {
       DEBUG_LOGGER
           .info("Path: {}.{}, get tsfile list: {} isSeq: {} timefilter: {}", 
deviceId.getFullPath(),
               measurementId, tsFileResources, isSeq, (timeFilter == null ? 
"null" : timeFilter));
@@ -1429,7 +1429,7 @@ public class StorageGroupProcessor {
     context.setQueryTimeLowerBound(timeLowerBound);
 
     for (TsFileResource tsFileResource : tsFileResources) {
-      if (!isTsFileResourceSatisfied(tsFileResource, deviceId.getFullPath(), 
timeFilter, isSeq)) {
+      if (!isTsFileResourceSatisfied(tsFileResource, deviceId.getFullPath(), 
timeFilter, isSeq, context.isDebug())) {
         continue;
       }
       closeQueryLock.readLock().lock();
@@ -1450,7 +1450,7 @@ public class StorageGroupProcessor {
     }
     // for upgrade files and old files must be closed
     for (TsFileResource tsFileResource : upgradeTsFileResources) {
-      if (!isTsFileResourceSatisfied(tsFileResource, deviceId.getFullPath(), 
timeFilter, isSeq)) {
+      if (!isTsFileResourceSatisfied(tsFileResource, deviceId.getFullPath(), 
timeFilter, isSeq, context.isDebug())) {
         continue;
       }
       closeQueryLock.readLock().lock();
@@ -1467,9 +1467,9 @@ public class StorageGroupProcessor {
    * @return true if the device is contained in the TsFile and it lives beyond 
TTL
    */
   private boolean isTsFileResourceSatisfied(TsFileResource tsFileResource, 
String deviceId,
-      Filter timeFilter, boolean isSeq) {
+      Filter timeFilter, boolean isSeq, boolean debug) {
     if (!tsFileResource.containsDevice(deviceId)) {
-      if (config.isDebugOn()) {
+      if (debug) {
         DEBUG_LOGGER.info("Path: {} file {} is not satisfied because of no 
device!", deviceId,
             tsFileResource);
       }
@@ -1482,7 +1482,7 @@ public class StorageGroupProcessor {
         : Long.MAX_VALUE;
 
     if (!isAlive(endTime)) {
-      if (config.isDebugOn()) {
+      if (debug) {
         DEBUG_LOGGER
             .info("Path: {} file {} is not satisfied because of ttl!", 
deviceId, tsFileResource);
       }
@@ -1491,7 +1491,7 @@ public class StorageGroupProcessor {
 
     if (timeFilter != null) {
       boolean res = timeFilter.satisfyStartEndTime(startTime, endTime);
-      if (config.isDebugOn() && !res) {
+      if (debug && !res) {
         DEBUG_LOGGER.info("Path: {} file {} is not satisfied because of time 
filter!", deviceId,
             tsFileResource);
       }
@@ -1524,6 +1524,7 @@ public class StorageGroupProcessor {
       for (PartialPath device : devicePaths) {
         // delete Last cache record if necessary
         tryToDeleteLastCache(device, path, startTime, endTime);
+        DEBUG_LOGGER.info("Delete last cache for path: " + path + " with 
deletion interval: " + startTime + " to " + endTime);
       }
 
       // write log to impacted working TsFileProcessors
@@ -1601,6 +1602,8 @@ public class StorageGroupProcessor {
       tsFileResource.getModFile().write(deletion);
       // remember to close mod file
       tsFileResource.getModFile().close();
+      logger.info("[Deletion] Deletion with path:{}, time:{}-{} written into 
mods file.",
+              deletion.getPath(), deletion.getStartTime(), 
deletion.getEndTime());
 
       tsFileResource.updatePlanIndexes(planIndex);
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index d14f257..20b924f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -393,11 +393,15 @@ public class TsFileProcessor {
         for (PartialPath device : devicePaths) {
           workMemTable.delete(deletion.getPath(), device, 
deletion.getStartTime(),
               deletion.getEndTime());
+          logger.info("[Deletion] Delete in-memory data with deletion path: 
{}, time:{}-{}.",
+                  deletion.getPath(), deletion.getStartTime(), 
deletion.getEndTime());
         }
       }
       // flushing memTables are immutable, only record this deletion in these 
memTables for query
       for (IMemTable memTable : flushingMemTables) {
         memTable.delete(deletion);
+        logger.info("[Deletion] delete flushing memtable with deletion path: 
{}, time:{}-{}",
+                deletion.getPath(), deletion.getStartTime(), 
deletion.getEndTime());
       }
     } finally {
       flushQueryLock.writeLock().unlock();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
index 5da9d1c..a4b0ad5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
@@ -29,12 +29,16 @@ import 
org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Represents an MNode which has a Measurement or Sensor attached to it.
  */
 public class MeasurementMNode extends MNode {
 
   private static final long serialVersionUID = -1199657856921206435L;
+  private static final Logger DEBUG_LOGGER = 
LoggerFactory.getLogger("QUERY_DEBUG");
 
   /**
    * measurement's Schema for one timeseries represented by current leaf node
@@ -82,12 +86,14 @@ public class MeasurementMNode extends MNode {
       if (!highPriorityUpdate || latestFlushedTime <= 
timeValuePair.getTimestamp()) {
         cachedLastValuePair =
             new TimeValuePair(timeValuePair.getTimestamp(), 
timeValuePair.getValue());
+        DEBUG_LOGGER.info("[MeasurementMNode] Last cache for path: " + 
fullPath + " is set to: " + timeValuePair.getTimestamp());
       }
     } else if (timeValuePair.getTimestamp() > 
cachedLastValuePair.getTimestamp()
         || (timeValuePair.getTimestamp() == cachedLastValuePair.getTimestamp()
         && highPriorityUpdate)) {
       cachedLastValuePair.setTimestamp(timeValuePair.getTimestamp());
       cachedLastValuePair.setValue(timeValuePair.getValue());
+      DEBUG_LOGGER.info("[MeasurementMNode] Last cache for path: " + fullPath 
+ " is set to: " + timeValuePair.getTimestamp());
     }
   }
 
@@ -98,6 +104,7 @@ public class MeasurementMNode extends MNode {
 
   public void resetCache() {
     cachedLastValuePair = null;
+    DEBUG_LOGGER.info("[MeasurementMNode] Last cache for path: " + fullPath + 
" is set to null");
   }
 
   public long getOffset() {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/Planner.java 
b/server/src/main/java/org/apache/iotdb/db/qp/Planner.java
index 1fa57c4..bd99fd9 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/Planner.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/Planner.java
@@ -45,9 +45,7 @@ import java.util.Set;
 
 import static org.apache.iotdb.db.conf.IoTDBConstant.TIME;
 
-/**
- * provide a integration method for other user.
- */
+/** provide a integration method for other user. */
 public class Planner {
 
   protected LogicalGenerator logicalGenerator;
@@ -57,44 +55,43 @@ public class Planner {
   }
 
   @TestOnly
-  public PhysicalPlan parseSQLToPhysicalPlan(String sqlStr)
-      throws QueryProcessException {
+  public PhysicalPlan parseSQLToPhysicalPlan(String sqlStr) throws 
QueryProcessException {
     return parseSQLToPhysicalPlan(sqlStr, ZoneId.systemDefault(), 1024);
   }
 
-  /**
-   * @param fetchSize this parameter only take effect when it is a query plan
-   */
+  /** @param fetchSize this parameter only take effect when it is a query plan 
*/
   public PhysicalPlan parseSQLToPhysicalPlan(String sqlStr, ZoneId zoneId, int 
fetchSize)
       throws QueryProcessException {
     Operator operator = logicalGenerator.generate(sqlStr, zoneId);
-    int maxDeduplicatedPathNum = QueryResourceManager.getInstance()
-        .getMaxDeduplicatedPathNum(fetchSize);
+    int maxDeduplicatedPathNum =
+        
QueryResourceManager.getInstance().getMaxDeduplicatedPathNum(fetchSize);
     if (operator instanceof SFWOperator && ((SFWOperator) 
operator).isLastQuery()) {
-      // Dataset of last query actually has only three columns, so we 
shouldn't limit the path num while constructing logical plan
-      // To avoid overflowing because logicalOptimize function may do 
maxDeduplicatedPathNum + 1, we set it to Integer.MAX_VALUE - 1
+      // Dataset of last query actually has only three columns, so we 
shouldn't limit the path num
+      // while constructing logical plan
+      // To avoid overflowing because logicalOptimize function may do 
maxDeduplicatedPathNum + 1, we
+      // set it to Integer.MAX_VALUE - 1
       maxDeduplicatedPathNum = Integer.MAX_VALUE - 1;
     }
     operator = logicalOptimize(operator, maxDeduplicatedPathNum);
     PhysicalGenerator physicalGenerator = new PhysicalGenerator();
-    return physicalGenerator.transformToPhysicalPlan(operator, fetchSize);
+    PhysicalPlan physicalPlan = 
physicalGenerator.transformToPhysicalPlan(operator, fetchSize);
+    physicalPlan.setDebug(operator.isDebug());
+    return physicalPlan;
   }
 
-  /**
-   * convert raw data query to physical plan directly
-   */
+  /** convert raw data query to physical plan directly */
   public PhysicalPlan rawDataQueryReqToPhysicalPlan(TSRawDataQueryReq 
rawDataQueryReq)
       throws QueryProcessException, IllegalPathException {
     List<String> paths = rawDataQueryReq.getPaths();
     long startTime = rawDataQueryReq.getStartTime();
     long endTime = rawDataQueryReq.getEndTime();
 
-    //construct query operator and set its global time filter
+    // construct query operator and set its global time filter
     QueryOperator queryOp = new QueryOperator(SQLConstant.TOK_QUERY);
     FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
     SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
 
-    //iterate the path list and add it to from operator
+    // iterate the path list and add it to from operator
     for (String p : paths) {
       PartialPath path = new PartialPath(p);
       fromOp.addPrefixTablePath(path);
@@ -104,7 +101,7 @@ public class Planner {
     queryOp.setSelectOperator(selectOp);
     queryOp.setFromOperator(fromOp);
 
-    //set time filter operator
+    // set time filter operator
     FilterOperator filterOp = new FilterOperator(SQLConstant.KW_AND);
     PartialPath timePath = new PartialPath(TIME);
     filterOp.setSinglePath(timePath);
@@ -113,26 +110,32 @@ public class Planner {
     filterOp.setIsSingle(true);
     filterOp.setPathSet(pathSet);
 
-    BasicFunctionOperator left = new 
BasicFunctionOperator(SQLConstant.GREATERTHANOREQUALTO,
-        timePath, Long.toString(startTime));
-    BasicFunctionOperator right = new 
BasicFunctionOperator(SQLConstant.LESSTHAN, timePath,
-        Long.toString(endTime));
+    BasicFunctionOperator left =
+        new BasicFunctionOperator(
+            SQLConstant.GREATERTHANOREQUALTO, timePath, 
Long.toString(startTime));
+    BasicFunctionOperator right =
+        new BasicFunctionOperator(SQLConstant.LESSTHAN, timePath, 
Long.toString(endTime));
     filterOp.addChildOperator(left);
     filterOp.addChildOperator(right);
 
     queryOp.setFilterOperator(filterOp);
 
-    int maxDeduplicatedPathNum = QueryResourceManager.getInstance()
-        .getMaxDeduplicatedPathNum(rawDataQueryReq.fetchSize);
+    int maxDeduplicatedPathNum =
+        
QueryResourceManager.getInstance().getMaxDeduplicatedPathNum(rawDataQueryReq.fetchSize);
     if (queryOp.isLastQuery()) {
-      // Dataset of last query actually has only three columns, so we 
shouldn't limit the path num while constructing logical plan
-      // To avoid overflowing because logicalOptimize function may do 
maxDeduplicatedPathNum + 1, we set it to Integer.MAX_VALUE - 1
+      // Dataset of last query actually has only three columns, so we 
shouldn't limit the path num
+      // while constructing logical plan
+      // To avoid overflowing because logicalOptimize function may do 
maxDeduplicatedPathNum + 1, we
+      // set it to Integer.MAX_VALUE - 1
       maxDeduplicatedPathNum = Integer.MAX_VALUE - 1;
     }
     SFWOperator op = (SFWOperator) logicalOptimize(queryOp, 
maxDeduplicatedPathNum);
 
     PhysicalGenerator physicalGenerator = new PhysicalGenerator();
-    return physicalGenerator.transformToPhysicalPlan(op, 
rawDataQueryReq.fetchSize);
+    PhysicalPlan physicalPlan =
+        physicalGenerator.transformToPhysicalPlan(op, 
rawDataQueryReq.fetchSize);
+    physicalPlan.setDebug(op.isDebug());
+    return physicalPlan;
   }
 
   /**
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
index 9439913..13b8b5b 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
@@ -20,21 +20,22 @@ package org.apache.iotdb.db.qp.logical;
 
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 
-/**
- * This class is a superclass of all operator.
- */
+/** This class is a superclass of all operator. */
 public abstract class Operator {
 
   // operator type in int format
   protected int tokenIntType;
   // operator type in String format
   protected String tokenName;
+  // flag of "explain"
+  protected boolean isDebug;
 
   protected OperatorType operatorType = OperatorType.NULL;
 
   public Operator(int tokenIntType) {
     this.tokenIntType = tokenIntType;
     this.tokenName = SQLConstant.tokenNames.get(tokenIntType);
+    this.isDebug = false;
   }
 
   public OperatorType getType() {
@@ -57,26 +58,92 @@ public abstract class Operator {
     this.operatorType = operatorType;
   }
 
+  public boolean isDebug() {
+    return isDebug;
+  }
+
+  public void setDebug(boolean debug) {
+    isDebug = debug;
+  }
+
   @Override
   public String toString() {
     return tokenName;
   }
 
-  /**
-   * If you want to add new OperatorType, you must add it in the last.
-   */
+  /** If you want to add new OperatorType, you must add it in the last. */
   public enum OperatorType {
-    SFW, JOIN, UNION, FILTER, GROUPBYTIME, ORDERBY, LIMIT, SELECT, 
SEQTABLESCAN, HASHTABLESCAN,
-    MERGEJOIN, FILEREAD, NULL, TABLESCAN, UPDATE, INSERT, BATCHINSERT, DELETE, 
BASIC_FUNC, IN, QUERY, MERGEQUERY,
-    AGGREGATION, AUTHOR, FROM, FUNC, LOADDATA, METADATA, INDEX, INDEXQUERY, 
FILL,
-    SET_STORAGE_GROUP, CREATE_TIMESERIES, DELETE_TIMESERIES, CREATE_USER, 
DELETE_USER, MODIFY_PASSWORD,
-    GRANT_USER_PRIVILEGE, REVOKE_USER_PRIVILEGE, GRANT_USER_ROLE, 
REVOKE_USER_ROLE, CREATE_ROLE,
-    DELETE_ROLE, GRANT_ROLE_PRIVILEGE, REVOKE_ROLE_PRIVILEGE, LIST_USER, 
LIST_ROLE,
-    LIST_USER_PRIVILEGE, LIST_ROLE_PRIVILEGE, LIST_USER_ROLES, LIST_ROLE_USERS,
-    GRANT_WATERMARK_EMBEDDING, REVOKE_WATERMARK_EMBEDDING,
-    TTL, DELETE_STORAGE_GROUP, LOAD_CONFIGURATION, SHOW, LOAD_FILES, 
REMOVE_FILE, MOVE_FILE, LAST, GROUP_BY_FILL,
-    ALTER_TIMESERIES, FLUSH, MERGE, FULL_MERGE, CLEAR_CACHE,
-    SHOW_MERGE_STATUS, CREATE_SCHEMA_SNAPSHOT, TRACING, DELETE_PARTITION,
+    SFW,
+    JOIN,
+    UNION,
+    FILTER,
+    GROUPBYTIME,
+    ORDERBY,
+    LIMIT,
+    SELECT,
+    SEQTABLESCAN,
+    HASHTABLESCAN,
+    MERGEJOIN,
+    FILEREAD,
+    NULL,
+    TABLESCAN,
+    UPDATE,
+    INSERT,
+    BATCHINSERT,
+    DELETE,
+    BASIC_FUNC,
+    IN,
+    QUERY,
+    MERGEQUERY,
+    AGGREGATION,
+    AUTHOR,
+    FROM,
+    FUNC,
+    LOADDATA,
+    METADATA,
+    INDEX,
+    INDEXQUERY,
+    FILL,
+    SET_STORAGE_GROUP,
+    CREATE_TIMESERIES,
+    DELETE_TIMESERIES,
+    CREATE_USER,
+    DELETE_USER,
+    MODIFY_PASSWORD,
+    GRANT_USER_PRIVILEGE,
+    REVOKE_USER_PRIVILEGE,
+    GRANT_USER_ROLE,
+    REVOKE_USER_ROLE,
+    CREATE_ROLE,
+    DELETE_ROLE,
+    GRANT_ROLE_PRIVILEGE,
+    REVOKE_ROLE_PRIVILEGE,
+    LIST_USER,
+    LIST_ROLE,
+    LIST_USER_PRIVILEGE,
+    LIST_ROLE_PRIVILEGE,
+    LIST_USER_ROLES,
+    LIST_ROLE_USERS,
+    GRANT_WATERMARK_EMBEDDING,
+    REVOKE_WATERMARK_EMBEDDING,
+    TTL,
+    DELETE_STORAGE_GROUP,
+    LOAD_CONFIGURATION,
+    SHOW,
+    LOAD_FILES,
+    REMOVE_FILE,
+    MOVE_FILE,
+    LAST,
+    GROUP_BY_FILL,
+    ALTER_TIMESERIES,
+    FLUSH,
+    MERGE,
+    FULL_MERGE,
+    CLEAR_CACHE,
+    SHOW_MERGE_STATUS,
+    CREATE_SCHEMA_SNAPSHOT,
+    TRACING,
+    DELETE_PARTITION,
     CREATE_MULTI_TIMESERIES,
     BATCH_INSERT_ONE_DEVICE,
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
index c2842f1..1beb2c9 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
@@ -63,6 +63,8 @@ public abstract class PhysicalPlan {
   // a bridge from a cluster raft log to a physical plan
   protected long index;
 
+  private boolean debug;
+
   /**
    * whether the plan can be split into more than one Plans. Only used in the 
cluster mode.
    */
@@ -171,6 +173,14 @@ public abstract class PhysicalPlan {
     this.loginUserName = loginUserName;
   }
 
+  public boolean isDebug() {
+    return debug;
+  }
+
+  public void setDebug(boolean debug) {
+    this.debug = debug;
+  }
+
   public static class Factory {
 
     private Factory() {
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 34415a7..d50ac52 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
@@ -205,8 +205,8 @@ import org.apache.iotdb.tsfile.utils.StringContainer;
 
 public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
   private static final String DELETE_RANGE_ERROR_MSG =
-      "For delete statement, where clause can only contain atomic expressions 
like : " +
-          "time > XXX, time <= XXX, or two atomic expressions connected by 
'AND'";
+      "For delete statement, where clause can only contain atomic expressions 
like : "
+          + "time > XXX, time <= XXX, or two atomic expressions connected by 
'AND'";
   private ZoneId zoneId;
   QueryOperator queryOp;
 
@@ -216,17 +216,22 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitSingleStatement(SingleStatementContext ctx) {
-    return visit(ctx.statement());
+    Operator operator = visit(ctx.statement());
+    if (ctx.EXPLAIN() != null) {
+      operator.setDebug(true);
+    }
+    return operator;
   }
 
   @Override
   public Operator visitCreateTimeseries(CreateTimeseriesContext ctx) {
-    CreateTimeSeriesOperator createTimeSeriesOperator = new 
CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE);
+    CreateTimeSeriesOperator createTimeSeriesOperator =
+        new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE);
     createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
-    if(ctx.alias() != null) {
+    if (ctx.alias() != null) {
       createTimeSeriesOperator.setAlias(ctx.alias().ID().getText());
     }
-    if(ctx.attributeClauses() != null) {
+    if (ctx.attributeClauses() != null) {
       parseAttributeClauses(ctx.attributeClauses(), createTimeSeriesOperator);
     }
     return createTimeSeriesOperator;
@@ -239,15 +244,16 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     for (PrefixPathContext prefixPath : prefixPaths) {
       deletePaths.add(parsePrefixPath(prefixPath));
     }
-    DeleteTimeSeriesOperator deleteTimeSeriesOperator = new 
DeleteTimeSeriesOperator(
-        SQLConstant.TOK_METADATA_DELETE);
+    DeleteTimeSeriesOperator deleteTimeSeriesOperator =
+        new DeleteTimeSeriesOperator(SQLConstant.TOK_METADATA_DELETE);
     deleteTimeSeriesOperator.setDeletePathList(deletePaths);
     return deleteTimeSeriesOperator;
   }
 
   @Override
   public Operator visitAlterTimeseries(AlterTimeseriesContext ctx) {
-    AlterTimeSeriesOperator alterTimeSeriesOperator = new 
AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER);
+    AlterTimeSeriesOperator alterTimeSeriesOperator =
+        new AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER);
     alterTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
     parseAlterClause(ctx.alterClause(), alterTimeSeriesOperator);
     return alterTimeSeriesOperator;
@@ -270,7 +276,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
     fromOp.addPrefixTablePath(parsePrefixPath(ctx.prefixPath()));
     SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_QUERY);
-    for(SetColContext colContext : ctx.setClause().setCol()) {
+    for (SetColContext colContext : ctx.setClause().setCol()) {
       parseSetCol(colContext, selectOp, updateOp);
     }
     FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
@@ -289,7 +295,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
       selectOp.addSelectPath(path);
     }
     deleteDataOp.setSelectOperator(selectOp);
-    if(ctx.whereClause() != null) {
+    if (ctx.whereClause() != null) {
       FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
       deleteDataOp.setFilterOperator(whereOp.getChildren().get(0));
       Pair<Long, Long> timeInterval = parseDeleteTimeInterval(deleteDataOp);
@@ -304,8 +310,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitSetStorageGroup(SetStorageGroupContext ctx) {
-    SetStorageGroupOperator setStorageGroupOperator = new 
SetStorageGroupOperator(
-        SQLConstant.TOK_METADATA_SET_FILE_LEVEL);
+    SetStorageGroupOperator setStorageGroupOperator =
+        new SetStorageGroupOperator(SQLConstant.TOK_METADATA_SET_FILE_LEVEL);
     PartialPath path = parsePrefixPath(ctx.prefixPath());
     setStorageGroupOperator.setPath(path);
     return setStorageGroupOperator;
@@ -318,8 +324,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     for (PrefixPathContext prefixPath : prefixPaths) {
       deletePaths.add(parsePrefixPath(prefixPath));
     }
-    DeleteStorageGroupOperator deleteStorageGroupOperator = new 
DeleteStorageGroupOperator(
-        SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL);
+    DeleteStorageGroupOperator deleteStorageGroupOperator =
+        new 
DeleteStorageGroupOperator(SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL);
     deleteStorageGroupOperator.setDeletePathList(deletePaths);
     return deleteStorageGroupOperator;
   }
@@ -357,8 +363,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitCreateUser(CreateUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE,
-        AuthorOperator.AuthorType.CREATE_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE, 
AuthorOperator.AuthorType.CREATE_USER);
     authorOperator.setUserName(ctx.ID().getText());
     authorOperator.setPassWord(removeStringQuote(ctx.password.getText()));
     return authorOperator;
@@ -366,8 +372,9 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitAlterUser(AlterUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_UPDATE_USER,
-        AuthorOperator.AuthorType.UPDATE_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(
+            SQLConstant.TOK_AUTHOR_UPDATE_USER, 
AuthorOperator.AuthorType.UPDATE_USER);
     if (ctx.ID() != null) {
       authorOperator.setUserName(ctx.ID().getText());
     } else {
@@ -379,32 +386,32 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitDropUser(DropUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_DROP,
-        AuthorOperator.AuthorType.DROP_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP, 
AuthorOperator.AuthorType.DROP_USER);
     authorOperator.setUserName(ctx.ID().getText());
     return authorOperator;
   }
 
   @Override
   public Operator visitCreateRole(CreateRoleContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE,
-        AuthorOperator.AuthorType.CREATE_ROLE);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE, 
AuthorOperator.AuthorType.CREATE_ROLE);
     authorOperator.setRoleName(ctx.ID().getText());
     return authorOperator;
   }
 
   @Override
   public Operator visitDropRole(DropRoleContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_DROP,
-        AuthorOperator.AuthorType.DROP_ROLE);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP, 
AuthorOperator.AuthorType.DROP_ROLE);
     authorOperator.setRoleName(ctx.ID().getText());
     return authorOperator;
   }
 
   @Override
   public Operator visitGrantUser(GrantUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorOperator.AuthorType.GRANT_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, 
AuthorOperator.AuthorType.GRANT_USER);
     authorOperator.setUserName(ctx.ID().getText());
     authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
     authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
@@ -413,8 +420,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitGrantRole(GrantRoleContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorType.GRANT_ROLE);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, 
AuthorType.GRANT_ROLE);
     authorOperator.setRoleName(ctx.ID().getText());
     authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
     authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
@@ -423,8 +430,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitRevokeUser(RevokeUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorType.REVOKE_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, 
AuthorType.REVOKE_USER);
     authorOperator.setUserName(ctx.ID().getText());
     authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
     authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
@@ -433,8 +440,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitRevokeRole(RevokeRoleContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorType.REVOKE_ROLE);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, 
AuthorType.REVOKE_ROLE);
     authorOperator.setRoleName(ctx.ID().getText());
     authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
     authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
@@ -443,8 +450,9 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitGrantRoleToUser(GrantRoleToUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorOperator.AuthorType.GRANT_ROLE_TO_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(
+            SQLConstant.TOK_AUTHOR_GRANT, 
AuthorOperator.AuthorType.GRANT_ROLE_TO_USER);
     authorOperator.setRoleName(ctx.roleName.getText());
     authorOperator.setUserName(ctx.userName.getText());
     return authorOperator;
@@ -452,8 +460,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitRevokeRoleFromUser(RevokeRoleFromUserContext ctx) {
-    AuthorOperator authorOperator = new 
AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
-        AuthorType.REVOKE_ROLE_FROM_USER);
+    AuthorOperator authorOperator =
+        new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, 
AuthorType.REVOKE_ROLE_FROM_USER);
     authorOperator.setRoleName(ctx.roleName.getText());
     authorOperator.setUserName(ctx.userName.getText());
     return authorOperator;
@@ -472,9 +480,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     for (NodeNameContext nodeName : nodeNames) {
       sc.addTail(nodeName.getText());
     }
-    return new LoadDataOperator(SQLConstant.TOK_DATALOAD,
-        removeStringQuote(csvPath),
-        sc.toString());
+    return new LoadDataOperator(
+        SQLConstant.TOK_DATALOAD, removeStringQuote(csvPath), sc.toString());
   }
 
   @Override
@@ -509,8 +516,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitListPrivilegesUser(ListPrivilegesUserContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
     operator.setUserName(ctx.rootOrId().getText());
     operator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
     return operator;
@@ -518,8 +525,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitListPrivilegesRole(ListPrivilegesRoleContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
     operator.setRoleName((ctx.ID().getText()));
     operator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
     return operator;
@@ -527,32 +534,32 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitListUserPrivileges(ListUserPrivilegesContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
     operator.setUserName(ctx.rootOrId().getText());
     return operator;
   }
 
   @Override
   public Operator visitListRolePrivileges(ListRolePrivilegesContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
     operator.setRoleName(ctx.ID().getText());
     return operator;
   }
 
   @Override
   public Operator visitListAllRoleOfUser(ListAllRoleOfUserContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_USER_ROLES);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_USER_ROLES);
     operator.setUserName(ctx.rootOrId().getText());
     return operator;
   }
 
   @Override
   public Operator visitListAllUserOfRole(ListAllUserOfRoleContext ctx) {
-    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
-        AuthorOperator.AuthorType.LIST_ROLE_USERS);
+    AuthorOperator operator =
+        new AuthorOperator(SQLConstant.TOK_LIST, 
AuthorOperator.AuthorType.LIST_ROLE_USERS);
     operator.setRoleName((ctx.ID().getText()));
     return operator;
   }
@@ -603,16 +610,20 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     boolean orderByHeat = ctx.LATEST() != null;
     ShowTimeSeriesOperator showTimeSeriesOperator;
     if (ctx.prefixPath() != null) {
-      showTimeSeriesOperator = new 
ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES,
-          parsePrefixPath(ctx.prefixPath()), orderByHeat);
+      showTimeSeriesOperator =
+          new ShowTimeSeriesOperator(
+              SQLConstant.TOK_TIMESERIES, parsePrefixPath(ctx.prefixPath()), 
orderByHeat);
     } else {
-      showTimeSeriesOperator = new 
ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES, new 
PartialPath(SQLConstant.getSingleRootArray()),
-          orderByHeat);
+      showTimeSeriesOperator =
+          new ShowTimeSeriesOperator(
+              SQLConstant.TOK_TIMESERIES,
+              new PartialPath(SQLConstant.getSingleRootArray()),
+              orderByHeat);
     }
-    if(ctx.showWhereClause() != null) {
+    if (ctx.showWhereClause() != null) {
       parseShowWhereClause(ctx.showWhereClause(), showTimeSeriesOperator);
     }
-    if(ctx.limitClause() != null) {
+    if (ctx.limitClause() != null) {
       parseLimitClause(ctx.limitClause(), showTimeSeriesOperator);
     }
     return showTimeSeriesOperator;
@@ -621,33 +632,32 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitShowStorageGroup(ShowStorageGroupContext ctx) {
     if (ctx.prefixPath() != null) {
-      return new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP,
-          parsePrefixPath(ctx.prefixPath()));
+      return new ShowStorageGroupOperator(
+          SQLConstant.TOK_STORAGE_GROUP, parsePrefixPath(ctx.prefixPath()));
     } else {
-      return new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP,
-          new PartialPath(SQLConstant.getSingleRootArray()));
+      return new ShowStorageGroupOperator(
+          SQLConstant.TOK_STORAGE_GROUP, new 
PartialPath(SQLConstant.getSingleRootArray()));
     }
   }
 
   @Override
   public Operator visitShowChildPaths(ShowChildPathsContext ctx) {
     if (ctx.prefixPath() != null) {
-      return new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS,
-          parsePrefixPath(ctx.prefixPath()));
+      return new ShowChildPathsOperator(
+          SQLConstant.TOK_CHILD_PATHS, parsePrefixPath(ctx.prefixPath()));
     } else {
-      return new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS,
-          new PartialPath(SQLConstant.getSingleRootArray()));
+      return new ShowChildPathsOperator(
+          SQLConstant.TOK_CHILD_PATHS, new 
PartialPath(SQLConstant.getSingleRootArray()));
     }
   }
 
   @Override
   public Operator visitShowDevices(ShowDevicesContext ctx) {
     if (ctx.prefixPath() != null) {
-      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
-          parsePrefixPath(ctx.prefixPath()));
+      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES, 
parsePrefixPath(ctx.prefixPath()));
     } else {
-      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
-          new PartialPath(SQLConstant.getSingleRootArray()));
+      return new ShowDevicesOperator(
+          SQLConstant.TOK_DEVICES, new 
PartialPath(SQLConstant.getSingleRootArray()));
     }
   }
 
@@ -669,34 +679,44 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitCountTimeseries(CountTimeseriesContext ctx) {
     PrefixPathContext pathContext = ctx.prefixPath();
-    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : 
new PartialPath(SQLConstant.getSingleRootArray()));
+    PartialPath path =
+        (pathContext != null
+            ? parsePrefixPath(pathContext)
+            : new PartialPath(SQLConstant.getSingleRootArray()));
     if (ctx.INT() != null) {
-      return new CountOperator(SQLConstant.TOK_COUNT_NODE_TIMESERIES,
-          path, Integer.parseInt(ctx.INT().getText()));
+      return new CountOperator(
+          SQLConstant.TOK_COUNT_NODE_TIMESERIES, path, 
Integer.parseInt(ctx.INT().getText()));
     } else {
-      return new CountOperator(SQLConstant.TOK_COUNT_TIMESERIES,
-          path);
+      return new CountOperator(SQLConstant.TOK_COUNT_TIMESERIES, path);
     }
   }
 
   @Override
   public Operator visitCountDevices(CountDevicesContext ctx) {
     PrefixPathContext pathContext = ctx.prefixPath();
-    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : 
new PartialPath(SQLConstant.getSingleRootArray()));
+    PartialPath path =
+        (pathContext != null
+            ? parsePrefixPath(pathContext)
+            : new PartialPath(SQLConstant.getSingleRootArray()));
     return new CountOperator(SQLConstant.TOK_COUNT_DEVICES, path);
   }
 
   @Override
   public Operator visitCountStorageGroup(CountStorageGroupContext ctx) {
     PrefixPathContext pathContext = ctx.prefixPath();
-    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : 
new PartialPath(SQLConstant.getSingleRootArray()));
+    PartialPath path =
+        (pathContext != null
+            ? parsePrefixPath(pathContext)
+            : new PartialPath(SQLConstant.getSingleRootArray()));
     return new CountOperator(SQLConstant.TOK_COUNT_STORAGE_GROUP, path);
   }
 
   @Override
   public Operator visitCountNodes(CountNodesContext ctx) {
-    return new CountOperator(SQLConstant.TOK_COUNT_NODES,
-        parsePrefixPath(ctx.prefixPath()), 
Integer.parseInt(ctx.INT().getText()));
+    return new CountOperator(
+        SQLConstant.TOK_COUNT_NODES,
+        parsePrefixPath(ctx.prefixPath()),
+        Integer.parseInt(ctx.INT().getText()));
   }
 
   @Override
@@ -715,21 +735,18 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
         return new LoadFilesOperator(
             new File(removeStringQuote(ctx.stringLiteral().getText())),
             
Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
-            Integer.parseInt(ctx.autoCreateSchema().INT().getText())
-        );
+            Integer.parseInt(ctx.autoCreateSchema().INT().getText()));
       } else {
         return new LoadFilesOperator(
             new File(removeStringQuote(ctx.stringLiteral().getText())),
             
Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
-            
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
-        );
+            
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel());
       }
     } else {
       return new LoadFilesOperator(
           new File(removeStringQuote(ctx.stringLiteral().getText())),
           true,
-          
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
-      );
+          
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel());
     }
   }
 
@@ -747,8 +764,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitDeletePartition(DeletePartitionContext ctx) {
-    DeletePartitionOperator deletePartitionOperator = new 
DeletePartitionOperator(
-        SQLConstant.TOK_DELETE_PARTITION);
+    DeletePartitionOperator deletePartitionOperator =
+        new DeletePartitionOperator(SQLConstant.TOK_DELETE_PARTITION);
     
deletePartitionOperator.setStorageGroupName(parsePrefixPath(ctx.prefixPath()));
     Set<Long> idSet = new HashSet<>();
     for (TerminalNode terminalNode : ctx.INT()) {
@@ -765,16 +782,16 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitSelectStatement(SelectStatementContext ctx) {
-    queryOp  = new QueryOperator(SQLConstant.TOK_QUERY);
+    queryOp = new QueryOperator(SQLConstant.TOK_QUERY);
     SelectOperator selectOp = (SelectOperator) visit(ctx.selectElements());
     queryOp.setSelectOperator(selectOp);
     FromOperator fromOp = (FromOperator) visit(ctx.fromClause());
     queryOp.setFromOperator(fromOp);
-    if(ctx.whereClause() != null) {
+    if (ctx.whereClause() != null) {
       FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
       queryOp.setFilterOperator(whereOp.getChildren().get(0));
     }
-    if(ctx.specialClause() != null) {
+    if (ctx.specialClause() != null) {
       visit(ctx.specialClause());
     }
     return queryOp;
@@ -848,11 +865,11 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitLimitStatement(LimitStatementContext ctx) {
     parseLimitClause(ctx.limitClause(), queryOp);
-    if(ctx.slimitClause() != null) {
+    if (ctx.slimitClause() != null) {
       parseSlimitClause(ctx.slimitClause(), queryOp);
     }
-    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
-      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
+    if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if (ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
         parseAlignByDeviceClause(queryOp);
       } else {
         parseDisableAlign(queryOp);
@@ -864,11 +881,11 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitSlimitStatement(SlimitStatementContext ctx) {
     parseSlimitClause(ctx.slimitClause(), queryOp);
-    if(ctx.limitClause() != null) {
+    if (ctx.limitClause() != null) {
       parseLimitClause(ctx.limitClause(), queryOp);
     }
-    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
-      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
+    if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if (ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
         parseAlignByDeviceClause(queryOp);
       } else {
         parseDisableAlign(queryOp);
@@ -880,7 +897,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitAlignByDeviceClauseOrDisableAlignInSpecialLimit(
       AlignByDeviceClauseOrDisableAlignInSpecialLimitContext ctx) {
-    if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) {
+    if (ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) 
{
       parseAlignByDeviceClause(queryOp);
     } else {
       parseDisableAlign(queryOp);
@@ -891,7 +908,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitOrderByTimeStatement(OrderByTimeStatementContext ctx) {
     parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
-    if(ctx.specialLimit() != null) {
+    if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
     }
     return queryOp;
@@ -900,10 +917,10 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitGroupByTimeStatement(GroupByTimeStatementContext ctx) {
     parseGroupByTimeClause(ctx.groupByTimeClause(), queryOp);
-    if(ctx.orderByTimeClause() != null) {
+    if (ctx.orderByTimeClause() != null) {
       parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
     }
-    if(ctx.specialLimit() != null) {
+    if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
     }
     return queryOp;
@@ -912,10 +929,10 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitGroupByFillStatement(GroupByFillStatementContext ctx) {
     parseGroupByFillClause(ctx.groupByFillClause(), queryOp);
-    if(ctx.orderByTimeClause() != null) {
+    if (ctx.orderByTimeClause() != null) {
       parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
     }
-    if(ctx.specialLimit() != null) {
+    if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
     }
     return queryOp;
@@ -924,11 +941,11 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitFillStatement(FillStatementContext ctx) {
     parseFillClause(ctx.fillClause(), queryOp);
-    if(ctx.slimitClause() != null) {
+    if (ctx.slimitClause() != null) {
       parseSlimitClause(ctx.slimitClause(), queryOp);
     }
-    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
-      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
+    if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if (ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
         parseAlignByDeviceClause(queryOp);
       } else {
         parseDisableAlign(queryOp);
@@ -940,8 +957,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitAlignByDeviceStatementOrDisableAlignInSpecialClause(
       AlignByDeviceStatementOrDisableAlignInSpecialClauseContext ctx) {
-    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
-      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
+    if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if (ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != 
null) {
         parseAlignByDeviceClause(queryOp);
       } else {
         parseDisableAlign(queryOp);
@@ -953,10 +970,10 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitGroupByLevelStatement(GroupByLevelStatementContext ctx) 
{
     parseGroupByLevelClause(ctx.groupByLevelClause(), queryOp);
-    if(ctx.orderByTimeClause() != null) {
+    if (ctx.orderByTimeClause() != null) {
       parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
     }
-    if(ctx.specialLimit() != null) {
+    if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
     }
     return queryOp;
@@ -965,13 +982,16 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitSelectElement(SelectElementContext ctx) {
     SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
-    List<SqlBaseParser.SuffixPathOrConstantContext> suffixPathOrConstants = 
ctx.suffixPathOrConstant();
+    List<SqlBaseParser.SuffixPathOrConstantContext> suffixPathOrConstants =
+        ctx.suffixPathOrConstant();
     for (SqlBaseParser.SuffixPathOrConstantContext suffixPathOrConstant : 
suffixPathOrConstants) {
       if (suffixPathOrConstant.suffixPath() != null) {
         PartialPath path = parseSuffixPath(suffixPathOrConstant.suffixPath());
         selectOp.addSelectPath(path);
       } else {
-        PartialPath path = new PartialPath(new 
String[]{suffixPathOrConstant.SINGLE_QUOTE_STRING_LITERAL().getText()});
+        PartialPath path =
+            new PartialPath(
+                new String[] 
{suffixPathOrConstant.SINGLE_QUOTE_STRING_LITERAL().getText()});
         selectOp.addSelectPath(path);
       }
     }
@@ -1018,12 +1038,12 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     if (limit <= 0) {
       throw new SQLParserException("LIMIT <N>: N should be greater than 0.");
     }
-    if(operator instanceof ShowTimeSeriesOperator) {
+    if (operator instanceof ShowTimeSeriesOperator) {
       ((ShowTimeSeriesOperator) operator).setLimit(limit);
     } else {
       ((QueryOperator) operator).setRowLimit(limit);
     }
-    if(ctx.offsetClause() != null) {
+    if (ctx.offsetClause() != null) {
       parseOffsetClause(ctx.offsetClause(), operator);
     }
   }
@@ -1051,14 +1071,13 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     try {
       slimit = Integer.parseInt(ctx.INT().getText());
     } catch (NumberFormatException e) {
-      throw new SQLParserException(
-          "Out of range. SLIMIT <SN>: SN should be Int32.");
+      throw new SQLParserException("Out of range. SLIMIT <SN>: SN should be 
Int32.");
     }
     if (slimit <= 0) {
       throw new SQLParserException("SLIMIT <SN>: SN should be greater than 
0.");
     }
     queryOp.setSeriesLimit(slimit);
-    if(ctx.soffsetClause() != null) {
+    if (ctx.soffsetClause() != null) {
       parseSoffsetClause(ctx.soffsetClause(), queryOp);
     }
   }
@@ -1072,8 +1091,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
           "Out of range. SOFFSET <SOFFSETValue>: SOFFSETValue should be 
Int32.");
     }
     if (soffset < 0) {
-      throw new SQLParserException(
-          "SOFFSET <SOFFSETValue>: SOFFSETValue should >= 0.");
+      throw new SQLParserException("SOFFSET <SOFFSETValue>: SOFFSETValue 
should >= 0.");
     }
     queryOp.setSeriesOffset(soffset);
   }
@@ -1153,13 +1171,15 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   private void parseTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> 
fillTypes) {
     TSDataType dataType = parseType(ctx.dataType().getText());
     if (ctx.linearClause() != null && dataType == TSDataType.TEXT) {
-      throw new SQLParserException(String.format("type %s cannot use %s fill 
function"
-          , dataType, ctx.linearClause().LINEAR().getText()));
+      throw new SQLParserException(
+          String.format(
+              "type %s cannot use %s fill function",
+              dataType, ctx.linearClause().LINEAR().getText()));
     }
 
     int defaultFillInterval = 
IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
 
-    if (ctx.linearClause() != null) {  // linear
+    if (ctx.linearClause() != null) { // linear
       if (ctx.linearClause().DURATION(0) != null) {
         long beforeRange = 
parseDuration(ctx.linearClause().DURATION(0).getText());
         long afterRange = 
parseDuration(ctx.linearClause().DURATION(1).getText());
@@ -1184,9 +1204,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     }
   }
 
-  /**
-   * parse datatype node.
-   */
+  /** parse datatype node. */
   private TSDataType parseType(String datatype) {
     String type = datatype.toLowerCase();
     switch (type) {
@@ -1284,8 +1302,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   private Pair<Long, Long> parseDeleteTimeInterval(DeleteDataOperator 
operator) {
     FilterOperator filterOperator = operator.getFilterOperator();
     if (!filterOperator.isLeaf() && filterOperator.getTokenIntType() != 
SQLConstant.KW_AND) {
-      throw new SQLParserException(
-          DELETE_RANGE_ERROR_MSG);
+      throw new SQLParserException(DELETE_RANGE_ERROR_MSG);
     }
 
     if (filterOperator.isLeaf()) {
@@ -1296,15 +1313,15 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     FilterOperator lOperator = children.get(0);
     FilterOperator rOperator = children.get(1);
     if (!lOperator.isLeaf() || !rOperator.isLeaf()) {
-      throw new SQLParserException(
-          DELETE_RANGE_ERROR_MSG);
+      throw new SQLParserException(DELETE_RANGE_ERROR_MSG);
     }
 
     Pair<Long, Long> leftOpInterval = calcOperatorInterval(lOperator);
     Pair<Long, Long> rightOpInterval = calcOperatorInterval(rOperator);
-    Pair<Long, Long> parsedInterval = new Pair<>(
-        Math.max(leftOpInterval.left, rightOpInterval.left),
-        Math.min(leftOpInterval.right, rightOpInterval.right));
+    Pair<Long, Long> parsedInterval =
+        new Pair<>(
+            Math.max(leftOpInterval.left, rightOpInterval.left),
+            Math.min(leftOpInterval.right, rightOpInterval.right));
     if (parsedInterval.left > parsedInterval.right) {
       throw new SQLParserException(
           "Invalid delete range: [" + parsedInterval.left + ", " + 
parsedInterval.right + "]");
@@ -1326,14 +1343,10 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
       case SQLConstant.EQUAL:
         return new Pair<>(time, time);
       default:
-        throw new SQLParserException(
-            DELETE_RANGE_ERROR_MSG);
+        throw new SQLParserException(DELETE_RANGE_ERROR_MSG);
     }
   }
 
-
-
-
   @Override
   public Operator visitWhereClause(WhereClauseContext ctx) {
     FilterOperator whereOp = new FilterOperator(SQLConstant.TOK_WHERE);
@@ -1438,18 +1451,24 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
       if (!path.equals(TIME_PATH)) {
         throw new SQLParserException(path.getFullPath(), "Date can only be 
used to time");
       }
-      basic = new 
BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path,
-          Long.toString(parseDateExpression(ctx.constant().dateExpression())));
+      basic =
+          new BasicFunctionOperator(
+              ctx.comparisonOperator().type.getType(),
+              path,
+              
Long.toString(parseDateExpression(ctx.constant().dateExpression())));
     } else {
-      basic = new 
BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path,
-          ctx.constant().getText());
+      basic =
+          new BasicFunctionOperator(
+              ctx.comparisonOperator().type.getType(), path, 
ctx.constant().getText());
     }
     return basic;
   }
 
   /**
    * parse time expression, which is addition and subtraction expression of 
duration time, now() or
-   * DataTimeFormat time. <p> eg. now() + 1d - 2h </p>
+   * DataTimeFormat time.
+   *
+   * <p>eg. now() + 1d - 2h
    */
   private Long parseDateExpression(DateExpressionContext ctx) {
     long time;
@@ -1464,7 +1483,6 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     return time;
   }
 
-
   /**
    * parse duration to time value.
    *
@@ -1488,8 +1506,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
           i++;
           unit += durationStr.charAt(i);
         }
-        total += DatetimeUtils
-            .convertDurationStrToLong(tmp, unit.toLowerCase(), 
timestampPrecision);
+        total +=
+            DatetimeUtils.convertDurationStrToLong(tmp, unit.toLowerCase(), 
timestampPrecision);
         tmp = 0;
       }
     }
@@ -1539,9 +1557,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     insertOp.setValueList(valueList.toArray(new String[0]));
   }
 
-
-
-  private void parseAlterClause(AlterClauseContext ctx, 
AlterTimeSeriesOperator alterTimeSeriesOperator) {
+  private void parseAlterClause(
+      AlterClauseContext ctx, AlterTimeSeriesOperator alterTimeSeriesOperator) 
{
     Map<String, String> alterMap = new HashMap<>();
     // rename
     if (ctx.RENAME() != null) {
@@ -1568,20 +1585,21 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     } else {
       // upsert
       alterTimeSeriesOperator.setAlterType(AlterType.UPSERT);
-      if(ctx.aliasClause() != null) {
+      if (ctx.aliasClause() != null) {
         parseAliasClause(ctx.aliasClause(), alterTimeSeriesOperator);
       }
-      if(ctx.tagClause() != null) {
+      if (ctx.tagClause() != null) {
         parseTagClause(ctx.tagClause(), alterTimeSeriesOperator);
       }
-      if(ctx.attributeClause() != null) {
+      if (ctx.attributeClause() != null) {
         parseAttributeClause(ctx.attributeClause(), alterTimeSeriesOperator);
       }
     }
     alterTimeSeriesOperator.setAlterMap(alterMap);
   }
 
-  public void parseAliasClause(AliasClauseContext ctx, AlterTimeSeriesOperator 
alterTimeSeriesOperator) {
+  public void parseAliasClause(
+      AliasClauseContext ctx, AlterTimeSeriesOperator alterTimeSeriesOperator) 
{
     if (alterTimeSeriesOperator != null && ctx.ID() != null) {
       alterTimeSeriesOperator.setAlias(ctx.ID().getText());
     }
@@ -1622,7 +1640,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     return new PartialPath(path);
   }
 
-  public void parseAttributeClauses(AttributeClausesContext ctx, 
CreateTimeSeriesOperator createTimeSeriesOperator) {
+  public void parseAttributeClauses(
+      AttributeClausesContext ctx, CreateTimeSeriesOperator 
createTimeSeriesOperator) {
     final String dataType = ctx.dataType().getChild(0).getText().toUpperCase();
     final TSDataType tsDataType = TSDataType.valueOf(dataType);
     createTimeSeriesOperator.setDataType(tsDataType);
@@ -1646,16 +1665,17 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     if (ctx.property(0) != null) {
       props = new HashMap<>(properties.size());
       for (PropertyContext property : properties) {
-        props.put(property.ID().getText().toLowerCase(),
+        props.put(
+            property.ID().getText().toLowerCase(),
             property.propertyValue().getText().toLowerCase());
       }
     }
     createTimeSeriesOperator.setCompressor(compressor);
     createTimeSeriesOperator.setProps(props);
-    if(ctx.tagClause() != null) {
+    if (ctx.tagClause() != null) {
       parseTagClause(ctx.tagClause(), createTimeSeriesOperator);
     }
-    if(ctx.attributeClause() != null) {
+    if (ctx.attributeClause() != null) {
       parseAttributeClause(ctx.attributeClause(), createTimeSeriesOperator);
     }
   }
@@ -1678,8 +1698,8 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     }
   }
 
-  private Map<String, String> extractMap(List<PropertyContext> property2,
-      PropertyContext property3) {
+  private Map<String, String> extractMap(
+      List<PropertyContext> property2, PropertyContext property3) {
     String value;
     Map<String, String> tags = new HashMap<>(property2.size());
     if (property3 != null) {
@@ -1709,9 +1729,7 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     return new PartialPath(path);
   }
 
-  /**
-   * function for parsing time format.
-   */
+  /** function for parsing time format. */
   public long parseTimeFormat(String timestampStr) throws SQLParserException {
     if (timestampStr == null || timestampStr.trim().equals("")) {
       throw new SQLParserException("input timestamp cannot be empty");
@@ -1733,10 +1751,12 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
     try {
       return DatetimeUtils.convertDatetimeStrToLong(timestampStr, zoneId);
     } catch (Exception e) {
-      throw new SQLParserException(String
-          .format("Input time format %s error. "
-              + "Input like yyyy-MM-dd HH:mm:ss, yyyy-MM-ddTHH:mm:ss or "
-              + "refer to user document for more info.", timestampStr));
+      throw new SQLParserException(
+          String.format(
+              "Input time format %s error. "
+                  + "Input like yyyy-MM-dd HH:mm:ss, yyyy-MM-ddTHH:mm:ss or "
+                  + "refer to user document for more info.",
+              timestampStr));
     }
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java 
b/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
index 863d4c3..a8c11fd 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
@@ -50,6 +50,8 @@ public class QueryContext {
 
   private long queryTimeLowerBound = Long.MIN_VALUE;
 
+  private boolean debug;
+
   public QueryContext() {
   }
 
@@ -57,6 +59,15 @@ public class QueryContext {
     this.queryId = queryId;
   }
 
+  public QueryContext(long queryId, boolean debug) {
+    this.queryId = queryId;
+    this.debug = debug;
+  }
+
+  public boolean isDebug() {
+    return debug;
+  }
+
   /**
    * Find the modifications of timeseries 'path' in 'modFile'. If they are not 
in the cache, read
    * them from 'modFile' and put then into the cache.
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByWithValueFilterDataSet.java
 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByWithValueFilterDataSet.java
index bd37495..64bad5f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByWithValueFilterDataSet.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByWithValueFilterDataSet.java
@@ -74,7 +74,7 @@ public class GroupByWithValueFilterDataSet extends 
GroupByEngineDataSet {
   }
 
   public GroupByWithValueFilterDataSet(long queryId, GroupByTimePlan 
groupByTimePlan) {
-    super(new QueryContext(queryId), groupByTimePlan);
+    super(new QueryContext(queryId, groupByTimePlan.isDebug()), 
groupByTimePlan);
     this.allDataReaderList = new ArrayList<>();
     this.timeStampFetchSize = 
IoTDBDescriptor.getInstance().getConfig().getBatchSize();
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
index e010c5b..527109d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
@@ -54,11 +54,15 @@ 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class LastQueryExecutor {
 
   private List<PartialPath> selectedSeries;
   private List<TSDataType> dataTypes;
   private IExpression expression;
+  private static final Logger DEBUG_LOGGER = 
LoggerFactory.getLogger("QUERY_DEBUG");
   private static final boolean lastCacheEnabled =
           IoTDBDescriptor.getInstance().getConfig().isLastCacheEnabled();
 
@@ -158,6 +162,7 @@ public class LastQueryExecutor {
           resultContainer.get(i).left = true;
           if (lastCacheEnabled) {
             cacheAccessors.get(i).write(resultContainer.get(i).right);
+            DEBUG_LOGGER.info("[LastQueryExecutor] Update last cache for path: 
" + seriesPaths + " with timestamp: " + 
resultContainer.get(i).right.getTimestamp());
           }
         }
       }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
 
b/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
index 95466e9..7bf9e57 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
@@ -31,9 +31,13 @@ import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
 import org.apache.iotdb.tsfile.file.metadata.TimeseriesMetadata;
 import org.apache.iotdb.tsfile.read.controller.IChunkMetadataLoader;
 import org.apache.iotdb.tsfile.read.filter.basic.Filter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DiskChunkMetadataLoader implements IChunkMetadataLoader {
 
+  private static final Logger DEBUG_LOGGER = 
LoggerFactory.getLogger("QUERY_DEBUG");
+
   private TsFileResource resource;
   private PartialPath seriesPath;
   private QueryContext context;
@@ -51,8 +55,8 @@ public class DiskChunkMetadataLoader implements 
IChunkMetadataLoader {
   @Override
   public List<ChunkMetadata> loadChunkMetadataList(TimeseriesMetadata 
timeseriesMetadata)
       throws IOException {
-    List<ChunkMetadata> chunkMetadataList = ChunkMetadataCache
-        .getInstance().get(resource.getTsFilePath(), seriesPath, 
timeseriesMetadata);
+    List<ChunkMetadata> chunkMetadataList = ChunkMetadataCache.getInstance()
+        .get(resource.getTsFilePath(), seriesPath, timeseriesMetadata, 
context.isDebug());
 
     setDiskChunkLoader(chunkMetadataList, resource, seriesPath, context);
 
@@ -82,10 +86,20 @@ public class DiskChunkMetadataLoader implements 
IChunkMetadataLoader {
     List<Modification> pathModifications =
         context.getPathModifications(resource.getModFile(), seriesPath);
 
+    if (context.isDebug()) {
+      DEBUG_LOGGER.info("Modifications size is {} for file Path: {} ", 
pathModifications.size(), resource.getTsFilePath());
+      pathModifications.forEach(c -> DEBUG_LOGGER.info(c.toString()));
+    }
+
     if (!pathModifications.isEmpty()) {
       QueryUtils.modifyChunkMetaData(chunkMetadataList, pathModifications);
     }
 
+    if (context.isDebug()) {
+      DEBUG_LOGGER.info("After modification Chunk meta data list is: ");
+      chunkMetadataList.forEach(c -> DEBUG_LOGGER.info(c.toString()));
+    }
+
     for (ChunkMetadata data : chunkMetadataList) {
       data.setChunkLoader(new DiskChunkLoader(resource));
     }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java 
b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 500ae7a..da62967 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -767,7 +767,7 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
       if (costTime >= config.getSlowQueryThreshold()) {
         SLOW_SQL_LOGGER.info("Cost: " + costTime + " ms, sql is " + statement);
       }
-      if (config.isDebugOn()) {
+      if (plan.isDebug()) {
         SLOW_SQL_LOGGER.info("ChunkCache used memory proportion: " + 
ChunkCache.getInstance()
             .getUsedMemoryProportion() + "\nChunkMetadataCache used memory 
proportion: "
             + ChunkMetadataCache.getInstance().getUsedMemoryProportion()
@@ -1113,14 +1113,14 @@ public class TSServiceImpl implements TSIService.Iface, 
ServerContext {
       throws QueryProcessException, QueryFilterOptimizationException, 
StorageEngineException,
       IOException, MetadataException, SQLException, TException, 
InterruptedException {
 
-    QueryContext context = genQueryContext(queryId);
+    QueryContext context = genQueryContext(queryId, physicalPlan.isDebug());
     QueryDataSet queryDataSet = executor.processQuery(physicalPlan, context);
     queryId2DataSet.put(queryId, queryDataSet);
     return queryDataSet;
   }
 
-  protected QueryContext genQueryContext(long queryId) {
-    return new QueryContext(queryId);
+  protected QueryContext genQueryContext(long queryId, boolean debug) {
+    return new QueryContext(queryId, debug);
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java 
b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
index b3af734..dea1b60 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
@@ -94,7 +94,7 @@ public class FileLoaderUtils {
       }
       timeSeriesMetadata = TimeSeriesMetadataCache.getInstance()
           .get(new 
TimeSeriesMetadataCache.TimeSeriesMetadataCacheKey(resource.getTsFilePath(),
-              seriesPath.getDevice(), seriesPath.getMeasurement()), 
allSensors);
+              seriesPath.getDevice(), seriesPath.getMeasurement()), 
allSensors, context.isDebug());
       if (timeSeriesMetadata != null) {
         timeSeriesMetadata.setChunkMetadataLoader(
             new DiskChunkMetadataLoader(resource, seriesPath, context, 
filter));
diff --git 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java
 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java
index 0869643..692c881 100644
--- 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java
+++ 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java
@@ -169,4 +169,16 @@ public class TimeseriesMetadata implements Accountable {
   public boolean isSeq() {
     return isSeq;
   }
+
+  @Override
+  public String toString() {
+    return "TimeseriesMetadata{" +
+        "measurementId='" + measurementId + '\'' +
+        ", dataType=" + dataType +
+        ", statistics=" + statistics +
+        ", modified=" + modified +
+        ", ramSize=" + ramSize +
+        ", isSeq=" + isSeq +
+        '}';
+  }
 }

Reply via email to