You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xi...@apache.org on 2021/05/25 16:09:02 UTC

[iotdb] branch RequeryV2 created (now ef45eb5)

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

xiangweiwei pushed a change to branch RequeryV2
in repository https://gitbox.apache.org/repos/asf/iotdb.git.


      at ef45eb5  Fix conclicts

This branch includes the following new commits:

     new 2fe8724  Merge master and fix conflicts
     new ad89e3a  Restructure query operator
     new 09a6378  Fix conclicts
     new 17c34d3  Reimplement logical checker
     new dbe29eb  add check for last query
     new ef45eb5  Fix conclicts

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[iotdb] 02/06: Restructure query operator

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ad89e3a6f9d833bf8e624d0036fb79af2c35430c
Author: Alima777 <wx...@gmail.com>
AuthorDate: Wed May 19 21:15:56 2021 +0800

    Restructure query operator
---
 .../query/ClusterPhysicalGeneratorTest.java        |  20 +-
 ...Operator.java => AggregationQueryOperator.java} |  26 +-
 ...{FromOperator.java => FillClauseComponent.java} |  26 +-
 .../{FromOperator.java => FillQueryOperator.java}  |  26 +-
 .../iotdb/db/qp/logical/crud/FilterOperator.java   |   9 +-
 .../crud/{FromOperator.java => FromComponent.java} |  11 +-
 .../db/qp/logical/crud/GroupByClauseComponent.java |  91 +++++++
 ...erator.java => GroupByFillClauseComponent.java} |  26 +-
 ...Operator.java => GroupByFillQueryOperator.java} |  26 +-
 ...rator.java => GroupByLevelClauseComponent.java} |  26 +-
 ...FromOperator.java => GroupByQueryOperator.java} |  26 +-
 .../{FromOperator.java => LastQueryOperator.java}  |  28 +--
 .../iotdb/db/qp/logical/crud/QueryOperator.java    | 270 +++------------------
 .../{SelectOperator.java => SelectComponent.java}  |  16 +-
 .../db/qp/logical/crud/SpecialClauseComponent.java | 128 ++++++++++
 .../{FromOperator.java => UDFQueryOperator.java}   |  26 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 260 +++++++++++++-------
 .../iotdb/db/qp/strategy/LogicalChecker.java       |  21 +-
 .../iotdb/db/qp/strategy/LogicalGenerator.java     |  14 +-
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  99 ++++----
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  27 ++-
 .../apache/iotdb/db/qp/utils/WildcardsRemover.java |  27 +--
 .../iotdb/db/integration/IoTDBGroupByFillIT.java   |   2 +-
 .../iotdb/db/qp/logical/IndexLogicalPlanTest.java  |   8 +-
 .../iotdb/db/qp/logical/LogicalPlanSmallTest.java  |  76 +++---
 25 files changed, 613 insertions(+), 702 deletions(-)

diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
index f1d7d57..fdbe72f 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPhysicalGeneratorTest.java
@@ -23,10 +23,9 @@ import org.apache.iotdb.cluster.common.TestUtils;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.constant.SQLConstant;
-import org.apache.iotdb.db.qp.logical.crud.FromOperator;
+import org.apache.iotdb.db.qp.logical.crud.FromComponent;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
+import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.expression.ResultColumn;
 import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
@@ -53,20 +52,19 @@ public class ClusterPhysicalGeneratorTest extends BaseQueryTest {
 
   @Test
   public void test() throws QueryProcessException, IllegalPathException {
-    QueryOperator operator = new QueryOperator(SQLConstant.TOK_QUERY);
+    QueryOperator operator = new QueryOperator();
 
-    SelectOperator selectOperator =
-        new SelectOperator(SQLConstant.TOK_SELECT, ZoneId.systemDefault());
+    SelectComponent selectComponent = new SelectComponent(ZoneId.systemDefault());
     List<ResultColumn> resultColumns = new ArrayList<>();
     for (PartialPath partialPath : pathList) {
       resultColumns.add(new ResultColumn(new TimeSeriesOperand(partialPath)));
     }
-    selectOperator.setResultColumns(resultColumns);
-    FromOperator fromOperator = new FromOperator(SQLConstant.TOK_FROM);
-    fromOperator.addPrefixTablePath(new PartialPath(TestUtils.getTestSg(0)));
+    selectComponent.setResultColumns(resultColumns);
+    FromComponent fromComponent = new FromComponent();
+    fromComponent.addPrefixTablePath(new PartialPath(TestUtils.getTestSg(0)));
 
-    operator.setSelectOperator(selectOperator);
-    operator.setFromOperator(fromOperator);
+    operator.setSelectComponent(selectComponent);
+    operator.setFromComponent(fromComponent);
     RawDataQueryPlan plan =
         (RawDataQueryPlan) physicalGenerator.transformToPhysicalPlan(operator, 1024);
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
index 60fed66..fd790ff 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class AggregationQueryOperator extends QueryOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillClauseComponent.java
similarity index 59%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillClauseComponent.java
index 60fed66..5750ac7 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillClauseComponent.java
@@ -18,28 +18,22 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
+import org.apache.iotdb.db.query.executor.fill.IFill;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
 
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
+public class FillClauseComponent extends SpecialClauseComponent {
 
-  private List<PartialPath> prefixList;
+  private Map<TSDataType, IFill> fillTypes;
 
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
+  public FillClauseComponent() {}
 
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
+  public Map<TSDataType, IFill> getFillTypes() {
+    return fillTypes;
   }
 
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
+  public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
+    this.fillTypes = fillTypes;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
index 60fed66..985ae16 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class FillQueryOperator extends QueryOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FilterOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FilterOperator.java
index 315223e..9fa4c87 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FilterOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FilterOperator.java
@@ -47,13 +47,13 @@ import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_OR;
  */
 public class FilterOperator extends Operator implements Comparable<FilterOperator> {
 
-  // it is the symbol of token. e.g. AND is & and OR is |
+  // The symbol of token. e.g. AND is & and OR is |
   String tokenSymbol;
 
-  private List<FilterOperator> childOperators;
+  private List<FilterOperator> childOperators = new ArrayList<>();
   // leaf filter operator means it doesn't have left and right child filterOperator. Leaf filter
   // should set FunctionOperator.
-  protected boolean isLeaf;
+  protected boolean isLeaf = false;
   // isSingle being true means all recursive children of this filter belong to one seriesPath.
   boolean isSingle = false;
   // if isSingle = false, singlePath must be null
@@ -64,9 +64,6 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
   public FilterOperator(int tokenType) {
     super(tokenType);
     operatorType = OperatorType.FILTER;
-    childOperators = new ArrayList<>();
-    this.tokenIntType = tokenType;
-    isLeaf = false;
     tokenSymbol = SQLConstant.tokenSymbol.get(tokenType);
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromComponent.java
similarity index 81%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromComponent.java
index 60fed66..16b56d1 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromComponent.java
@@ -19,21 +19,16 @@
 package org.apache.iotdb.db.qp.logical.crud;
 
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
+public class FromComponent {
 
-  private List<PartialPath> prefixList;
+  private List<PartialPath> prefixList = new ArrayList<>();;
 
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
+  public FromComponent() {}
 
   public void addPrefixTablePath(PartialPath prefixPath) {
     prefixList.add(prefixPath);
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByClauseComponent.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByClauseComponent.java
new file mode 100644
index 0000000..46b3987
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByClauseComponent.java
@@ -0,0 +1,91 @@
+/*
+ * 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.qp.logical.crud;
+
+public class GroupByClauseComponent extends SpecialClauseComponent {
+
+  private long startTime;
+  private long endTime;
+  // time interval
+  private long unit;
+  // sliding step
+  private long slidingStep;
+  private boolean isIntervalByMonth = false;
+  private boolean isSlidingStepByMonth = false;
+  // if it is left close and right open interval
+  private boolean leftCRightO;
+
+  public GroupByClauseComponent() {}
+
+  public boolean isLeftCRightO() {
+    return leftCRightO;
+  }
+
+  public void setLeftCRightO(boolean leftCRightO) {
+    this.leftCRightO = leftCRightO;
+  }
+
+  public long getUnit() {
+    return unit;
+  }
+
+  public void setUnit(long unit) {
+    this.unit = unit;
+  }
+
+  public long getStartTime() {
+    return startTime;
+  }
+
+  public void setStartTime(long startTime) {
+    this.startTime = startTime;
+  }
+
+  public long getEndTime() {
+    return endTime;
+  }
+
+  public void setEndTime(long endTime) {
+    this.endTime = endTime;
+  }
+
+  public long getSlidingStep() {
+    return slidingStep;
+  }
+
+  public void setSlidingStep(long slidingStep) {
+    this.slidingStep = slidingStep;
+  }
+
+  public boolean isSlidingStepByMonth() {
+    return isSlidingStepByMonth;
+  }
+
+  public void setSlidingStepByMonth(boolean isSlidingStepByMonth) {
+    this.isSlidingStepByMonth = isSlidingStepByMonth;
+  }
+
+  public boolean isIntervalByMonth() {
+    return isIntervalByMonth;
+  }
+
+  public void setIntervalByMonth(boolean isIntervalByMonth) {
+    this.isIntervalByMonth = isIntervalByMonth;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillClauseComponent.java
similarity index 59%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillClauseComponent.java
index 60fed66..616bd59 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillClauseComponent.java
@@ -18,28 +18,22 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
+import org.apache.iotdb.db.query.executor.fill.IFill;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
 
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
+public class GroupByFillClauseComponent extends GroupByClauseComponent {
 
-  private List<PartialPath> prefixList;
+  private Map<TSDataType, IFill> fillTypes;
 
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
+  public GroupByFillClauseComponent() {}
 
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
+  public Map<TSDataType, IFill> getFillTypes() {
+    return fillTypes;
   }
 
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
+  public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
+    this.fillTypes = fillTypes;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillQueryOperator.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillQueryOperator.java
index 60fed66..79cfade 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByFillQueryOperator.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class GroupByFillQueryOperator extends GroupByQueryOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByLevelClauseComponent.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByLevelClauseComponent.java
index 60fed66..5774265 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByLevelClauseComponent.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class GroupByLevelClauseComponent extends SpecialClauseComponent {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
index 60fed66..ec9a938 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class GroupByQueryOperator extends QueryOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
similarity index 58%
copy from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
copy to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
index 60fed66..51b43c6 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
@@ -18,28 +18,14 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
+public class LastQueryOperator extends QueryOperator {
 
-import java.util.ArrayList;
-import java.util.List;
+  public LastQueryOperator() {}
 
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
+  public LastQueryOperator(QueryOperator queryOperator) {
+    this.selectComponent = queryOperator.getSelectComponent();
+    this.fromComponent = queryOperator.getFromComponent();
+    this.filterOperator = queryOperator.getFilterOperator();
+    this.specialClauseComponent = queryOperator.getSpecialClauseComponent();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index 7e3055b..2e70cf3 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@ -19,78 +19,42 @@
 package org.apache.iotdb.db.qp.logical.crud;
 
 import org.apache.iotdb.db.index.common.IndexType;
+import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.RootOperator;
-import org.apache.iotdb.db.query.executor.fill.IFill;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.util.Map;
 
 public class QueryOperator extends RootOperator {
 
-  private SelectOperator selectOperator;
-  private FromOperator fromOperator;
-  private FilterOperator filterOperator;
+  protected SelectComponent selectComponent;
+  protected FromComponent fromComponent;
+  protected FilterOperator filterOperator;
+  protected SpecialClauseComponent specialClauseComponent;
 
-  private long startTime;
-  private long endTime;
-  // time interval
-  private long unit;
-  // sliding step
-  private long slidingStep;
-  private boolean isGroupByTime = false;
-  private boolean isIntervalByMonth = false;
-  private boolean isSlidingStepByMonth = false;
-  // if it is left close and right open interval
-  private boolean leftCRightO;
+  protected Map<String, Object> props;
 
-  private Map<TSDataType, IFill> fillTypes;
-  private boolean isFill = false;
+  protected IndexType indexType;
 
-  private boolean isGroupByLevel = false;
-  private int level = -1;
-
-  private int rowLimit = 0;
-  private int rowOffset = 0;
-  private int seriesLimit = 0;
-  private int seriesOffset = 0;
-
-  private boolean isAlignByDevice = false;
-  private boolean isAlignByTime = true;
-
-  private String column;
-
-  private boolean ascending = true;
-
-  private Map<String, Object> props;
-
-  private IndexType indexType;
-
-  // if true, we don't need the row whose any column is null
-  private boolean withoutAnyNull;
-
-  // if true, we don't need the row whose all columns are null
-  private boolean withoutAllNull;
-
-  public QueryOperator(int tokenIntType) {
-    super(tokenIntType);
+  public QueryOperator() {
+    super(SQLConstant.TOK_QUERY);
     operatorType = Operator.OperatorType.QUERY;
   }
 
-  public SelectOperator getSelectOperator() {
-    return selectOperator;
+  public SelectComponent getSelectComponent() {
+    return selectComponent;
   }
 
-  public void setSelectOperator(SelectOperator selectOperator) {
-    this.selectOperator = selectOperator;
+  public void setSelectComponent(SelectComponent selectComponent) {
+    this.selectComponent = selectComponent;
   }
 
-  public FromOperator getFromOperator() {
-    return fromOperator;
+  public FromComponent getFromComponent() {
+    return fromComponent;
   }
 
-  public void setFromOperator(FromOperator fromOperator) {
-    this.fromOperator = fromOperator;
+  public void setFromComponent(FromComponent fromComponent) {
+    this.fromComponent = fromComponent;
   }
 
   public FilterOperator getFilterOperator() {
@@ -101,6 +65,14 @@ public class QueryOperator extends RootOperator {
     this.filterOperator = filterOperator;
   }
 
+  public void setSpecialClauseComponent(SpecialClauseComponent specialClauseComponent) {
+    this.specialClauseComponent = specialClauseComponent;
+  }
+
+  public SpecialClauseComponent getSpecialClauseComponent() {
+    return specialClauseComponent;
+  }
+
   public Map<String, Object> getProps() {
     return props;
   }
@@ -117,199 +89,23 @@ public class QueryOperator extends RootOperator {
     this.indexType = indexType;
   }
 
-  public boolean isFill() {
-    return isFill;
-  }
-
-  public void setFill(boolean fill) {
-    isFill = fill;
-  }
-
-  public Map<TSDataType, IFill> getFillTypes() {
-    return fillTypes;
-  }
-
-  public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
-    this.fillTypes = fillTypes;
-  }
-
-  public boolean isGroupByLevel() {
-    return isGroupByLevel;
-  }
-
-  public void setGroupByLevel(boolean isGroupBy) {
-    this.isGroupByLevel = isGroupBy;
-  }
-
-  public boolean isLeftCRightO() {
-    return leftCRightO;
-  }
-
-  public void setLeftCRightO(boolean leftCRightO) {
-    this.leftCRightO = leftCRightO;
-  }
-
-  public int getRowLimit() {
-    return rowLimit;
-  }
-
-  public void setRowLimit(int rowLimit) {
-    this.rowLimit = rowLimit;
-  }
-
-  public int getRowOffset() {
-    return rowOffset;
-  }
-
-  public void setRowOffset(int rowOffset) {
-    this.rowOffset = rowOffset;
-  }
-
-  public boolean hasLimit() {
-    return rowLimit > 0;
-  }
-
-  public int getSeriesLimit() {
-    return seriesLimit;
-  }
-
-  public void setSeriesLimit(int seriesLimit) {
-    this.seriesLimit = seriesLimit;
-  }
-
-  public int getSeriesOffset() {
-    return seriesOffset;
-  }
-
-  public void setSeriesOffset(int seriesOffset) {
-    this.seriesOffset = seriesOffset;
-  }
-
-  public boolean hasSlimit() {
-    return seriesLimit > 0;
-  }
-
-  public long getUnit() {
-    return unit;
-  }
-
-  public void setUnit(long unit) {
-    this.unit = unit;
-  }
-
-  public long getStartTime() {
-    return startTime;
-  }
-
-  public void setStartTime(long startTime) {
-    this.startTime = startTime;
-  }
-
-  public long getEndTime() {
-    return endTime;
-  }
-
-  public void setEndTime(long endTime) {
-    this.endTime = endTime;
-  }
-
-  public long getSlidingStep() {
-    return slidingStep;
-  }
-
-  public void setSlidingStep(long slidingStep) {
-    this.slidingStep = slidingStep;
-  }
-
-  public boolean isAlignByDevice() {
-    return isAlignByDevice;
-  }
-
-  public void setAlignByDevice(boolean isAlignByDevice) {
-    this.isAlignByDevice = isAlignByDevice;
-  }
-
-  public boolean isAlignByTime() {
-    return isAlignByTime;
-  }
-
-  public void setAlignByTime(boolean isAlignByTime) {
-    this.isAlignByTime = isAlignByTime;
-  }
-
-  public int getLevel() {
-    return level;
-  }
-
-  public void setLevel(int level) {
-    this.level = level;
-  }
-
-  public boolean isGroupByTime() {
-    return isGroupByTime;
-  }
-
-  public void setGroupByTime(boolean groupByTime) {
-    isGroupByTime = groupByTime;
-  }
-
-  public boolean isSlidingStepByMonth() {
-    return isSlidingStepByMonth;
-  }
-
-  public void setSlidingStepByMonth(boolean isSlidingStepByMonth) {
-    this.isSlidingStepByMonth = isSlidingStepByMonth;
-  }
-
-  public boolean isIntervalByMonth() {
-    return isIntervalByMonth;
-  }
-
-  public void setIntervalByMonth(boolean isIntervalByMonth) {
-    this.isIntervalByMonth = isIntervalByMonth;
-  }
-
-  public String getColumn() {
-    return column;
-  }
-
-  public void setColumn(String column) {
-    this.column = column;
-  }
-
-  public boolean isAscending() {
-    return ascending;
-  }
-
-  public void setAscending(boolean ascending) {
-    this.ascending = ascending;
-  }
-
-  public boolean isLastQuery() {
-    return selectOperator.isLastQuery();
-  }
-
   public boolean hasAggregationFunction() {
-    return selectOperator.hasAggregationFunction();
+    return selectComponent.hasAggregationFunction();
   }
 
   public boolean hasTimeSeriesGeneratingFunction() {
-    return selectOperator.hasTimeSeriesGeneratingFunction();
-  }
-
-  public boolean isWithoutAnyNull() {
-    return withoutAnyNull;
+    return selectComponent.hasTimeSeriesGeneratingFunction();
   }
 
-  public void setWithoutAnyNull(boolean withoutAnyNull) {
-    this.withoutAnyNull = withoutAnyNull;
+  public boolean isAlignByDevice() {
+    return specialClauseComponent != null && specialClauseComponent.isAlignByDevice();
   }
 
-  public boolean isWithoutAllNull() {
-    return withoutAllNull;
+  public boolean isAlignByTime() {
+    return specialClauseComponent == null || specialClauseComponent.isAlignByTime();
   }
 
-  public void setWithoutAllNull(boolean withoutAllNull) {
-    this.withoutAllNull = withoutAllNull;
+  public boolean isGroupByLevel() {
+    return specialClauseComponent != null && specialClauseComponent.getLevel() != -1;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
similarity index 90%
rename from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java
rename to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
index 4c260b9..11bd80b 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
@@ -19,7 +19,6 @@
 package org.apache.iotdb.db.qp.logical.crud;
 
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
 import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
@@ -30,11 +29,10 @@ import java.util.ArrayList;
 import java.util.List;
 
 /** this class maintains information from select clause. */
-public final class SelectOperator extends Operator {
+public final class SelectComponent {
 
   private final ZoneId zoneId;
 
-  private boolean isLastQuery = false;
   private boolean hasAggregationFunction = false;
   private boolean hasTimeSeriesGeneratingFunction = false;
 
@@ -44,9 +42,7 @@ public final class SelectOperator extends Operator {
   private List<String> aggregationFunctionsCache;
 
   /** init with tokenIntType, default operatorType is <code>OperatorType.SELECT</code>. */
-  public SelectOperator(int tokenIntType, ZoneId zoneId) {
-    super(tokenIntType);
-    operatorType = OperatorType.SELECT;
+  public SelectComponent(ZoneId zoneId) {
     this.zoneId = zoneId;
   }
 
@@ -54,14 +50,6 @@ public final class SelectOperator extends Operator {
     return zoneId;
   }
 
-  public void markAsLastQuery() {
-    isLastQuery = true;
-  }
-
-  public boolean isLastQuery() {
-    return isLastQuery;
-  }
-
   public boolean hasAggregationFunction() {
     return hasAggregationFunction;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SpecialClauseComponent.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SpecialClauseComponent.java
new file mode 100644
index 0000000..63de6fd
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SpecialClauseComponent.java
@@ -0,0 +1,128 @@
+/*
+ * 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.qp.logical.crud;
+
+public class SpecialClauseComponent {
+
+  private int rowLimit = 0;
+  private int rowOffset = 0;
+  private int seriesLimit = 0;
+  private int seriesOffset = 0;
+
+  private boolean ascending = true;
+  // if true, we don't need the row whose any column is null
+  private boolean withoutAnyNull;
+  // if true, we don't need the row whose all columns are null
+  private boolean withoutAllNull;
+
+  private int level = -1;
+
+  private boolean isAlignByDevice = false;
+  private boolean isAlignByTime = true;
+
+  public SpecialClauseComponent() {}
+
+  public int getRowLimit() {
+    return rowLimit;
+  }
+
+  public void setRowLimit(int rowLimit) {
+    this.rowLimit = rowLimit;
+  }
+
+  public int getRowOffset() {
+    return rowOffset;
+  }
+
+  public void setRowOffset(int rowOffset) {
+    this.rowOffset = rowOffset;
+  }
+
+  public boolean hasLimit() {
+    return rowLimit > 0;
+  }
+
+  public int getSeriesLimit() {
+    return seriesLimit;
+  }
+
+  public void setSeriesLimit(int seriesLimit) {
+    this.seriesLimit = seriesLimit;
+  }
+
+  public int getSeriesOffset() {
+    return seriesOffset;
+  }
+
+  public void setSeriesOffset(int seriesOffset) {
+    this.seriesOffset = seriesOffset;
+  }
+
+  public boolean hasSlimit() {
+    return seriesLimit > 0;
+  }
+
+  public boolean isAscending() {
+    return ascending;
+  }
+
+  public void setAscending(boolean ascending) {
+    this.ascending = ascending;
+  }
+
+  public boolean isWithoutAnyNull() {
+    return withoutAnyNull;
+  }
+
+  public void setWithoutAnyNull(boolean withoutAnyNull) {
+    this.withoutAnyNull = withoutAnyNull;
+  }
+
+  public boolean isWithoutAllNull() {
+    return withoutAllNull;
+  }
+
+  public void setWithoutAllNull(boolean withoutAllNull) {
+    this.withoutAllNull = withoutAllNull;
+  }
+
+  public int getLevel() {
+    return level;
+  }
+
+  public void setLevel(int level) {
+    this.level = level;
+  }
+
+  public boolean isAlignByDevice() {
+    return isAlignByDevice;
+  }
+
+  public void setAlignByDevice(boolean isAlignByDevice) {
+    this.isAlignByDevice = isAlignByDevice;
+  }
+
+  public boolean isAlignByTime() {
+    return isAlignByTime;
+  }
+
+  public void setAlignByTime(boolean isAlignByTime) {
+    this.isAlignByTime = isAlignByTime;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
similarity index 58%
rename from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
rename to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
index 60fed66..49a6814 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FromOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
@@ -18,28 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.logical.Operator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** this class maintains information of {@code FROM} clause. */
-public class FromOperator extends Operator {
-
-  private List<PartialPath> prefixList;
-
-  public FromOperator(int tokenIntType) {
-    super(tokenIntType);
-    operatorType = OperatorType.FROM;
-    prefixList = new ArrayList<>();
-  }
-
-  public void addPrefixTablePath(PartialPath prefixPath) {
-    prefixList.add(prefixPath);
-  }
-
-  public List<PartialPath> getPrefixPaths() {
-    return prefixList;
-  }
-}
+public class UDFQueryOperator extends QueryOperator {}
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 44d9131..0212a0f 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
@@ -27,14 +27,24 @@ import org.apache.iotdb.db.index.common.IndexUtils;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
+import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
 import org.apache.iotdb.db.qp.logical.crud.DeleteDataOperator;
+import org.apache.iotdb.db.qp.logical.crud.FillClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.FillQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
-import org.apache.iotdb.db.qp.logical.crud.FromOperator;
+import org.apache.iotdb.db.qp.logical.crud.FromComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByFillClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByFillQueryOperator;
+import org.apache.iotdb.db.qp.logical.crud.GroupByLevelClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.InOperator;
 import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
+import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
+import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
+import org.apache.iotdb.db.qp.logical.crud.SpecialClauseComponent;
 import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator;
 import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator.AlterType;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
@@ -77,7 +87,6 @@ import org.apache.iotdb.db.qp.logical.sys.ShowTriggersOperator;
 import org.apache.iotdb.db.qp.logical.sys.StartTriggerOperator;
 import org.apache.iotdb.db.qp.logical.sys.StopTriggerOperator;
 import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
-import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AliasClauseContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseOrDisableAlignContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseOrDisableAlignStatementContext;
@@ -208,6 +217,7 @@ import org.apache.iotdb.db.qp.sql.SqlBaseParser.TriggerAttributeContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.TypeClauseContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.UnsetTTLStatementContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.WhereClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.WithoutNullClauseContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.WithoutNullStatementContext;
 import org.apache.iotdb.db.qp.utils.DatetimeUtils;
 import org.apache.iotdb.db.query.executor.fill.IFill;
@@ -257,7 +267,7 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
       "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;
+  private QueryOperator queryOp;
 
   public void setZoneId(ZoneId zoneId) {
     this.zoneId = zoneId;
@@ -988,37 +998,42 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitSelectStatement(SelectStatementContext ctx) {
-    queryOp = new QueryOperator(SQLConstant.TOK_QUERY);
-    queryOp.setSelectOperator((SelectOperator) visit(ctx.selectClause()));
-    queryOp.setFromOperator((FromOperator) visit(ctx.fromClause()));
+    // 1. Visit special clause first to initialize different query operator
+    if (ctx.specialClause() != null) {
+      queryOp = (QueryOperator) visit(ctx.specialClause());
+    }
+    // 2. There is no special clause in query statement.
+    if (queryOp == null) {
+      queryOp = new QueryOperator();
+    }
+    // 3. Visit select, from, where in sequence
+    parseSelectClause(ctx.selectClause());
+    parseFromClause(ctx.fromClause());
     if (ctx.whereClause() != null) {
       Operator operator = visit(ctx.whereClause());
       if (operator instanceof FilterOperator) {
         queryOp.setFilterOperator(((FilterOperator) operator).getChildren().get(0));
       }
     }
-    if (ctx.specialClause() != null) {
-      visit(ctx.specialClause());
-    }
+
     return queryOp;
   }
 
-  @Override
-  public Operator visitSelectClause(SelectClauseContext ctx) {
-    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT, zoneId);
+  public void parseSelectClause(SelectClauseContext ctx) {
+    SelectComponent selectComponent = new SelectComponent(zoneId);
 
     if (ctx.topClause() != null) {
       // TODO: parse info of top clause into selectOp
       visitTopClause(ctx.topClause());
     } else if (ctx.LAST() != null) {
-      selectOp.markAsLastQuery();
+      queryOp = new LastQueryOperator(queryOp);
     }
 
     for (ResultColumnContext resultColumnContext : ctx.resultColumn()) {
-      selectOp.addResultColumn(parseResultColumn(resultColumnContext));
+      selectComponent.addResultColumn(parseResultColumn(resultColumnContext));
     }
 
-    return selectOp;
+    queryOp.setSelectComponent(selectComponent);
   }
 
   @Override
@@ -1105,9 +1120,12 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitLimitStatement(LimitStatementContext ctx) {
+    if (queryOp == null) {
+      queryOp = new QueryOperator();
+    }
     parseLimitClause(ctx.limitClause(), queryOp);
     if (ctx.slimitClause() != null) {
-      parseSlimitClause(ctx.slimitClause(), queryOp);
+      parseSlimitClause(ctx.slimitClause());
     }
     if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
       parseAlignByDeviceClauseOrDisableAlign(ctx.alignByDeviceClauseOrDisableAlign());
@@ -1117,7 +1135,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitSlimitStatement(SlimitStatementContext ctx) {
-    parseSlimitClause(ctx.slimitClause(), queryOp);
+    if (queryOp == null) {
+      queryOp = new QueryOperator();
+    }
+    parseSlimitClause(ctx.slimitClause());
     if (ctx.limitClause() != null) {
       parseLimitClause(ctx.limitClause(), queryOp);
     }
@@ -1130,30 +1151,38 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
   @Override
   public Operator visitAlignByDeviceClauseOrDisableAlignStatement(
       AlignByDeviceClauseOrDisableAlignStatementContext ctx) {
+    if (queryOp == null) {
+      queryOp = new QueryOperator();
+    }
     parseAlignByDeviceClauseOrDisableAlign(ctx.alignByDeviceClauseOrDisableAlign());
     return queryOp;
   }
 
   private void parseAlignByDeviceClauseOrDisableAlign(
       AlignByDeviceClauseOrDisableAlignContext ctx) {
+    SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+    if (specialClauseComponent == null) {
+      specialClauseComponent = new SpecialClauseComponent();
+    }
     if (ctx.alignByDeviceClause() != null) {
-      parseAlignByDeviceClause(queryOp);
+      parseAlignByDeviceClause(specialClauseComponent);
     } else {
-      parseDisableAlign(queryOp);
+      parseDisableAlign(specialClauseComponent);
     }
+    queryOp.setSpecialClauseComponent(specialClauseComponent);
   }
 
   @Override
   public Operator visitWithoutNullStatement(WithoutNullStatementContext ctx) {
-    if (ctx.withoutNullClause().WITHOUT() != null) {
-      queryOp.setWithoutAllNull(ctx.withoutNullClause().ALL() != null);
-      queryOp.setWithoutAnyNull(ctx.withoutNullClause().ANY() != null);
+    if (queryOp == null) {
+      queryOp = new QueryOperator();
     }
+    parseWithoutNullClause(ctx.withoutNullClause());
     if (ctx.limitClause() != null) {
       parseLimitClause(ctx.limitClause(), queryOp);
     }
     if (ctx.slimitClause() != null) {
-      parseSlimitClause(ctx.slimitClause(), queryOp);
+      parseSlimitClause(ctx.slimitClause());
     }
     if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
       parseAlignByDeviceClauseOrDisableAlign(ctx.alignByDeviceClauseOrDisableAlign());
@@ -1161,9 +1190,20 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     return queryOp;
   }
 
+  private void parseWithoutNullClause(WithoutNullClauseContext ctx) {
+    SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+    if (specialClauseComponent == null) {
+      specialClauseComponent = new SpecialClauseComponent();
+    }
+    specialClauseComponent.setWithoutAnyNull(ctx.ANY() != null);
+    specialClauseComponent.setWithoutAllNull(ctx.ALL() != null);
+    queryOp.setSpecialClauseComponent(specialClauseComponent);
+  }
+
   @Override
   public Operator visitOrderByTimeStatement(OrderByTimeStatementContext ctx) {
-    parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+    queryOp = new QueryOperator();
+    parseOrderByTimeClause(ctx.orderByTimeClause());
     if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
     }
@@ -1172,9 +1212,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitGroupByTimeStatement(GroupByTimeStatementContext ctx) {
-    parseGroupByTimeClause(ctx.groupByTimeClause(), queryOp);
+    queryOp = new GroupByQueryOperator();
+    parseGroupByTimeClause(ctx.groupByTimeClause());
     if (ctx.orderByTimeClause() != null) {
-      parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+      parseOrderByTimeClause(ctx.orderByTimeClause());
     }
     if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
@@ -1184,9 +1225,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitGroupByFillStatement(GroupByFillStatementContext ctx) {
-    parseGroupByFillClause(ctx.groupByFillClause(), queryOp);
+    queryOp = new GroupByFillQueryOperator();
+    parseGroupByFillClause(ctx.groupByFillClause());
     if (ctx.orderByTimeClause() != null) {
-      parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+      parseOrderByTimeClause(ctx.orderByTimeClause());
     }
     if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
@@ -1196,9 +1238,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitFillStatement(FillStatementContext ctx) {
-    parseFillClause(ctx.fillClause(), queryOp);
+    queryOp = new FillQueryOperator();
+    parseFillClause(ctx.fillClause());
     if (ctx.slimitClause() != null) {
-      parseSlimitClause(ctx.slimitClause(), queryOp);
+      parseSlimitClause(ctx.slimitClause());
     }
     if (ctx.alignByDeviceClauseOrDisableAlign() != null) {
       parseAlignByDeviceClauseOrDisableAlign(ctx.alignByDeviceClauseOrDisableAlign());
@@ -1208,9 +1251,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
 
   @Override
   public Operator visitGroupByLevelStatement(GroupByLevelStatementContext ctx) {
-    parseGroupByLevelClause(ctx.groupByLevelClause(), queryOp);
+    queryOp = new AggregationQueryOperator();
+    parseGroupByLevelClause(ctx.groupByLevelClause());
     if (ctx.orderByTimeClause() != null) {
-      parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+      parseOrderByTimeClause(ctx.orderByTimeClause());
     }
     if (ctx.specialLimit() != null) {
       return visit(ctx.specialLimit());
@@ -1218,15 +1262,14 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     return queryOp;
   }
 
-  @Override
-  public Operator visitFromClause(FromClauseContext ctx) {
-    FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
+  public void parseFromClause(FromClauseContext ctx) {
+    FromComponent fromComponent = new FromComponent();
     List<PrefixPathContext> prefixFromPaths = ctx.prefixPath();
     for (PrefixPathContext prefixFromPath : prefixFromPaths) {
       PartialPath path = parsePrefixPath(prefixFromPath);
-      fromOp.addPrefixTablePath(path);
+      fromComponent.addPrefixTablePath(path);
     }
-    return fromOp;
+    queryOp.setFromComponent(fromComponent);
   }
 
   private void parseIndexPredicate(IndexPredicateClauseContext ctx) {
@@ -1239,11 +1282,11 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     }
     if (ctx.LIKE() != null) {
       // whole matching case
-      if (queryOp.getSelectOperator().getResultColumns().size() != 1) {
+      if (queryOp.getSelectComponent().getResultColumns().size() != 1) {
         throw new SQLParserException("Index query statement allows only one select path");
       }
       if (!path.equals(
-          queryOp.getSelectOperator().getResultColumns().get(0).getExpression().toString())) {
+          queryOp.getSelectComponent().getResultColumns().get(0).getExpression().toString())) {
         throw new SQLParserException(
             "In the index query statement, "
                 + "the path in select element and the index predicate should be same");
@@ -1270,7 +1313,7 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
       }
       List<ResultColumn> resultColumns = new ArrayList<>();
       resultColumns.add(new ResultColumn(new TimeSeriesOperand(path)));
-      queryOp.getSelectOperator().setResultColumns(resultColumns);
+      queryOp.getSelectComponent().setResultColumns(resultColumns);
       props.put(PATTERN, compositePattern);
       props.put(THRESHOLD, thresholds);
       queryOp.setIndexType(IndexType.ELB_INDEX);
@@ -1289,26 +1332,28 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     return sequence;
   }
 
-  public void parseGroupByLevelClause(GroupByLevelClauseContext ctx, QueryOperator queryOp) {
-    if (!queryOp.hasAggregationFunction()) {
+  public void parseGroupByLevelClause(GroupByLevelClauseContext ctx) {
+    /*    if (!queryOp.hasAggregationFunction()) {
       throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }
-    queryOp.setGroupByLevel(true);
-    queryOp.setLevel(Integer.parseInt(ctx.INT().getText()));
+    }*/
+    GroupByLevelClauseComponent groupByLevelClauseComponent = new GroupByLevelClauseComponent();
+    groupByLevelClauseComponent.setLevel(Integer.parseInt(ctx.INT().getText()));
+    queryOp.setSpecialClauseComponent(groupByLevelClauseComponent);
   }
 
-  public void parseFillClause(FillClauseContext ctx, QueryOperator queryOp) {
-    FilterOperator filterOperator = queryOp.getFilterOperator();
+  public void parseFillClause(FillClauseContext ctx) {
+    /*    FilterOperator filterOperator = queryOp.getFilterOperator();
     if (!filterOperator.isLeaf() || filterOperator.getTokenIntType() != SQLConstant.EQUAL) {
       throw new SQLParserException("Only \"=\" can be used in fill function");
-    }
+    }*/
+    FillClauseComponent fillClauseComponent = new FillClauseComponent();
     List<TypeClauseContext> list = ctx.typeClause();
     Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class);
     for (TypeClauseContext typeClause : list) {
       parseTypeClause(typeClause, fillTypes);
     }
-    queryOp.setFill(true);
-    queryOp.setFillTypes(fillTypes);
+    fillClauseComponent.setFillTypes(fillTypes);
+    queryOp.setSpecialClauseComponent(fillClauseComponent);
   }
 
   private void parseLimitClause(LimitClauseContext ctx, Operator operator) {
@@ -1326,7 +1371,12 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     } else if (operator instanceof ShowDevicesOperator) {
       ((ShowDevicesOperator) operator).setLimit(limit);
     } else {
-      ((QueryOperator) operator).setRowLimit(limit);
+      SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+      if (specialClauseComponent == null) {
+        specialClauseComponent = new SpecialClauseComponent();
+      }
+      specialClauseComponent.setRowLimit(limit);
+      queryOp.setSpecialClauseComponent(specialClauseComponent);
     }
     if (ctx.offsetClause() != null) {
       parseOffsetClause(ctx.offsetClause(), operator);
@@ -1349,11 +1399,16 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     } else if (operator instanceof ShowDevicesOperator) {
       ((ShowDevicesOperator) operator).setOffset(offset);
     } else {
-      ((QueryOperator) operator).setRowOffset(offset);
+      SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+      if (specialClauseComponent == null) {
+        specialClauseComponent = new SpecialClauseComponent();
+      }
+      specialClauseComponent.setRowOffset(offset);
+      queryOp.setSpecialClauseComponent(specialClauseComponent);
     }
   }
 
-  private void parseSlimitClause(SlimitClauseContext ctx, QueryOperator queryOp) {
+  private void parseSlimitClause(SlimitClauseContext ctx) {
     int slimit;
     try {
       slimit = Integer.parseInt(ctx.INT().getText());
@@ -1363,7 +1418,12 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     if (slimit <= 0) {
       throw new SQLParserException("SLIMIT <SN>: SN should be greater than 0.");
     }
-    queryOp.setSeriesLimit(slimit);
+    SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+    if (specialClauseComponent == null) {
+      specialClauseComponent = new SpecialClauseComponent();
+    }
+    specialClauseComponent.setSeriesLimit(slimit);
+    queryOp.setSpecialClauseComponent(specialClauseComponent);
     if (ctx.soffsetClause() != null) {
       parseSoffsetClause(ctx.soffsetClause(), queryOp);
     }
@@ -1380,50 +1440,57 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     if (soffset < 0) {
       throw new SQLParserException("SOFFSET <SOFFSETValue>: SOFFSETValue should >= 0.");
     }
-    queryOp.setSeriesOffset(soffset);
+    SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+    if (specialClauseComponent == null) {
+      specialClauseComponent = new SpecialClauseComponent();
+    }
+    specialClauseComponent.setSeriesOffset(soffset);
+    queryOp.setSpecialClauseComponent(specialClauseComponent);
   }
 
-  private void parseGroupByTimeClause(GroupByTimeClauseContext ctx, QueryOperator queryOp) {
-    if (!queryOp.hasAggregationFunction()) {
+  private void parseGroupByTimeClause(GroupByTimeClauseContext ctx) {
+    /*    if (!queryOp.hasAggregationFunction()) {
       throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }
-    queryOp.setGroupByTime(true);
-    queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
+    }*/
+    GroupByClauseComponent groupByClauseComponent = new GroupByClauseComponent();
+    groupByClauseComponent.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
     // parse timeUnit
-    queryOp.setUnit(parseTimeUnitOrSlidingStep(queryOp, ctx.DURATION(0).getText(), true));
+    groupByClauseComponent.setUnit(
+        parseTimeUnitOrSlidingStep(ctx.DURATION(0).getText(), true, groupByClauseComponent));
     // parse sliding step
     if (ctx.DURATION().size() == 2) {
-      queryOp.setSlidingStep(parseTimeUnitOrSlidingStep(queryOp, ctx.DURATION(1).getText(), false));
-      if (queryOp.getSlidingStep() < queryOp.getUnit()) {
+      groupByClauseComponent.setSlidingStep(
+          parseTimeUnitOrSlidingStep(ctx.DURATION(1).getText(), false, groupByClauseComponent));
+      if (groupByClauseComponent.getSlidingStep() < groupByClauseComponent.getUnit()) {
         throw new SQLParserException(
             "The third parameter sliding step shouldn't be smaller than the second parameter time interval.");
       }
     } else {
-      queryOp.setSlidingStep(queryOp.getUnit());
-      queryOp.setSlidingStepByMonth(queryOp.isIntervalByMonth());
+      groupByClauseComponent.setSlidingStep(groupByClauseComponent.getUnit());
+      groupByClauseComponent.setSlidingStepByMonth(groupByClauseComponent.isIntervalByMonth());
     }
 
-    parseTimeInterval(ctx.timeInterval(), queryOp);
+    parseTimeInterval(ctx.timeInterval(), groupByClauseComponent);
 
     if (ctx.INT() != null) {
-      queryOp.setGroupByLevel(true);
-      queryOp.setLevel(Integer.parseInt(ctx.INT().getText()));
+      groupByClauseComponent.setLevel(Integer.parseInt(ctx.INT().getText()));
     }
+    queryOp.setSpecialClauseComponent(groupByClauseComponent);
   }
 
-  private void parseGroupByFillClause(GroupByFillClauseContext ctx, QueryOperator queryOp) {
-    if (!queryOp.hasAggregationFunction()) {
+  private void parseGroupByFillClause(GroupByFillClauseContext ctx) {
+    /*    if (!queryOp.hasAggregationFunction()) {
       throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }
-    queryOp.setGroupByTime(true);
-    queryOp.setFill(true);
-    queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
+    }*/
+    GroupByFillClauseComponent groupByFillClauseComponent = new GroupByFillClauseComponent();
+    groupByFillClauseComponent.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
 
     // parse timeUnit
-    queryOp.setUnit(DatetimeUtils.convertDurationStrToLong(ctx.DURATION().getText()));
-    queryOp.setSlidingStep(queryOp.getUnit());
+    groupByFillClauseComponent.setUnit(
+        DatetimeUtils.convertDurationStrToLong(ctx.DURATION().getText()));
+    groupByFillClauseComponent.setSlidingStep(groupByFillClauseComponent.getUnit());
 
-    parseTimeInterval(ctx.timeInterval(), queryOp);
+    parseTimeInterval(ctx.timeInterval(), groupByFillClauseComponent);
 
     List<TypeClauseContext> list = ctx.typeClause();
     Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class);
@@ -1464,8 +1531,8 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
         parseTypeClause(typeClause, fillTypes);
       }
     }
-    queryOp.setFill(true);
-    queryOp.setFillTypes(fillTypes);
+    groupByFillClauseComponent.setFillTypes(fillTypes);
+    queryOp.setSpecialClauseComponent(groupByFillClauseComponent);
   }
 
   private void parseTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> fillTypes) {
@@ -1530,22 +1597,27 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
     }
   }
 
-  private void parseOrderByTimeClause(OrderByTimeClauseContext ctx, QueryOperator queryOp) {
-    queryOp.setColumn(ctx.TIME().getText());
+  private void parseOrderByTimeClause(OrderByTimeClauseContext ctx) {
     if (ctx.DESC() != null) {
-      queryOp.setAscending(false);
+      SpecialClauseComponent specialClauseComponent = queryOp.getSpecialClauseComponent();
+      if (specialClauseComponent == null) {
+        specialClauseComponent = new SpecialClauseComponent();
+      }
+      specialClauseComponent.setAscending(false);
+      queryOp.setSpecialClauseComponent(specialClauseComponent);
     }
   }
 
-  private void parseAlignByDeviceClause(QueryOperator queryOp) {
-    queryOp.setAlignByDevice(true);
+  private void parseAlignByDeviceClause(SpecialClauseComponent specialClauseComponent) {
+    specialClauseComponent.setAlignByDevice(true);
   }
 
-  private void parseDisableAlign(QueryOperator queryOp) {
-    queryOp.setAlignByTime(false);
+  private void parseDisableAlign(SpecialClauseComponent specialClauseComponent) {
+    specialClauseComponent.setAlignByTime(false);
   }
 
-  private void parseTimeInterval(TimeIntervalContext timeInterval, QueryOperator queryOp) {
+  private void parseTimeInterval(
+      TimeIntervalContext timeInterval, GroupByClauseComponent groupByClauseComponent) {
     long startTime;
     long endTime;
     if (timeInterval.timeValue(0).INT() != null) {
@@ -1563,10 +1635,10 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
       endTime = parseTimeFormat(timeInterval.timeValue(1).dateFormat().getText());
     }
 
-    queryOp.setStartTime(startTime);
-    queryOp.setEndTime(endTime);
+    groupByClauseComponent.setStartTime(startTime);
+    groupByClauseComponent.setEndTime(endTime);
     if (startTime >= endTime) {
-      throw new SQLParserException("start time should be smaller than endTime in GroupBy");
+      throw new SQLParserException("Start time should be smaller than endTime in GroupBy");
     }
   }
 
@@ -1793,12 +1865,12 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
    * @return time in milliseconds, microseconds, or nanoseconds depending on the profile
    */
   private long parseTimeUnitOrSlidingStep(
-      QueryOperator queryOp, String durationStr, boolean isParsingTimeUnit) {
+      String durationStr, boolean isParsingTimeUnit, GroupByClauseComponent groupByComponent) {
     if (durationStr.toLowerCase().contains("mo")) {
       if (isParsingTimeUnit) {
-        queryOp.setIntervalByMonth(true);
+        groupByComponent.setIntervalByMonth(true);
       } else {
-        queryOp.setSlidingStepByMonth(true);
+        groupByComponent.setSlidingStepByMonth(true);
       }
     }
     return DatetimeUtils.convertDurationStrToLong(durationStr);
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
index f55fe7c..b5b0d2a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
@@ -22,8 +22,9 @@ package org.apache.iotdb.db.qp.strategy;
 import org.apache.iotdb.db.exception.query.LogicalOperatorException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
+import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
+import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.query.expression.Expression;
 import org.apache.iotdb.db.query.expression.ResultColumn;
 import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
@@ -53,12 +54,12 @@ public class LogicalChecker {
   }
 
   private static void checkLast(QueryOperator queryOperator) throws LogicalOperatorException {
-    SelectOperator selectOperator = queryOperator.getSelectOperator();
-    if (!selectOperator.isLastQuery()) {
+    SelectComponent selectComponent = queryOperator.getSelectComponent();
+    if (!(queryOperator instanceof LastQueryOperator)) {
       return;
     }
 
-    for (ResultColumn resultColumn : selectOperator.getResultColumns()) {
+    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
       Expression expression = resultColumn.getExpression();
       if (!(expression instanceof TimeSeriesOperand)) {
         throw new LogicalOperatorException("Last queries can only be applied on raw time series.");
@@ -68,12 +69,12 @@ public class LogicalChecker {
 
   private static void checkAggregation(QueryOperator queryOperator)
       throws LogicalOperatorException {
-    SelectOperator selectOperator = queryOperator.getSelectOperator();
-    if (!selectOperator.hasAggregationFunction()) {
+    SelectComponent selectComponent = queryOperator.getSelectComponent();
+    if (!selectComponent.hasAggregationFunction()) {
       return;
     }
 
-    for (ResultColumn resultColumn : selectOperator.getResultColumns()) {
+    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
       Expression expression = resultColumn.getExpression();
       if (expression instanceof TimeSeriesOperand) {
         throw new LogicalOperatorException(
@@ -88,12 +89,12 @@ public class LogicalChecker {
       return;
     }
 
-    SelectOperator selectOperator = queryOperator.getSelectOperator();
-    if (selectOperator.hasTimeSeriesGeneratingFunction()) {
+    SelectComponent selectComponent = queryOperator.getSelectComponent();
+    if (selectComponent.hasTimeSeriesGeneratingFunction()) {
       throw new LogicalOperatorException("ALIGN BY DEVICE clause is not supported in UDF queries.");
     }
 
-    for (PartialPath path : selectOperator.getPaths()) {
+    for (PartialPath path : selectComponent.getPaths()) {
       String device = path.getDevice();
       if (!device.isEmpty()) {
         throw new LogicalOperatorException(
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
index 51a5e72..7b216d8 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
@@ -24,9 +24,9 @@ import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
 import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
-import org.apache.iotdb.db.qp.logical.crud.FromOperator;
+import org.apache.iotdb.db.qp.logical.crud.FromComponent;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
+import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.qp.sql.IoTDBSqlVisitor;
 import org.apache.iotdb.db.qp.sql.SqlBaseLexer;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser;
@@ -84,9 +84,9 @@ public class LogicalGenerator {
   public static Operator generate(TSRawDataQueryReq rawDataQueryReq, ZoneId zoneId)
       throws IllegalPathException {
     // 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, zoneId);
+    QueryOperator queryOp = new QueryOperator();
+    FromComponent fromOp = new FromComponent();
+    SelectComponent selectOp = new SelectComponent(zoneId);
 
     // iterate the path list and add it to from operator
     for (String p : rawDataQueryReq.getPaths()) {
@@ -95,8 +95,8 @@ public class LogicalGenerator {
     }
     selectOp.addResultColumn(new ResultColumn(new TimeSeriesOperand(new PartialPath(""))));
 
-    queryOp.setSelectOperator(selectOp);
-    queryOp.setFromOperator(fromOp);
+    queryOp.setSelectComponent(selectOp);
+    queryOp.setFromComponent(fromOp);
 
     // set time filter operator
     FilterOperator filterOp = new FilterOperator(SQLConstant.KW_AND);
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 5c81c6e..223e8fa 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -30,9 +30,17 @@ import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
 import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
 import org.apache.iotdb.db.qp.logical.crud.DeleteDataOperator;
+import org.apache.iotdb.db.qp.logical.crud.FillClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.FillQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
+import org.apache.iotdb.db.qp.logical.crud.GroupByClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByFillClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.GroupByFillQueryOperator;
+import org.apache.iotdb.db.qp.logical.crud.GroupByQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
+import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
+import org.apache.iotdb.db.qp.logical.crud.SpecialClauseComponent;
 import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
 import org.apache.iotdb.db.qp.logical.sys.CountOperator;
@@ -471,41 +479,45 @@ public class PhysicalGenerator {
         throw new QueryProcessException(
             "User-defined and built-in hybrid aggregation is not supported.");
       }
-      if (queryOperator.isGroupByTime() && queryOperator.isFill()) {
+      if (queryOperator instanceof GroupByFillQueryOperator) {
         queryPlan = new GroupByTimeFillPlan();
-      } else if (queryOperator.isGroupByTime()) {
+      } else if (queryOperator instanceof GroupByQueryOperator) {
         queryPlan = new GroupByTimePlan();
       } else {
         queryPlan = new AggregationPlan();
       }
 
-      queryPlan.setPaths(queryOperator.getSelectOperator().getPaths());
-      queryPlan.setAggregations(queryOperator.getSelectOperator().getAggregationFunctions());
+      queryPlan.setPaths(queryOperator.getSelectComponent().getPaths());
+      queryPlan.setAggregations(queryOperator.getSelectComponent().getAggregationFunctions());
 
-      if (queryOperator.isGroupByTime()) {
+      if (queryOperator instanceof GroupByQueryOperator) {
         GroupByTimePlan groupByTimePlan = (GroupByTimePlan) queryPlan;
-        groupByTimePlan.setInterval(queryOperator.getUnit());
-        groupByTimePlan.setIntervalByMonth(queryOperator.isIntervalByMonth());
-        groupByTimePlan.setSlidingStep(queryOperator.getSlidingStep());
-        groupByTimePlan.setSlidingStepByMonth(queryOperator.isSlidingStepByMonth());
-        groupByTimePlan.setLeftCRightO(queryOperator.isLeftCRightO());
-        if (!queryOperator.isLeftCRightO()) {
-          groupByTimePlan.setStartTime(queryOperator.getStartTime() + 1);
-          groupByTimePlan.setEndTime(queryOperator.getEndTime() + 1);
+        GroupByClauseComponent groupByClauseComponent =
+            (GroupByClauseComponent) queryOperator.getSpecialClauseComponent();
+        groupByTimePlan.setInterval(groupByClauseComponent.getUnit());
+        groupByTimePlan.setIntervalByMonth(groupByClauseComponent.isIntervalByMonth());
+        groupByTimePlan.setSlidingStep(groupByClauseComponent.getSlidingStep());
+        groupByTimePlan.setSlidingStepByMonth(groupByClauseComponent.isSlidingStepByMonth());
+        groupByTimePlan.setLeftCRightO(groupByClauseComponent.isLeftCRightO());
+        if (!groupByClauseComponent.isLeftCRightO()) {
+          groupByTimePlan.setStartTime(groupByClauseComponent.getStartTime() + 1);
+          groupByTimePlan.setEndTime(groupByClauseComponent.getEndTime() + 1);
         } else {
-          groupByTimePlan.setStartTime(queryOperator.getStartTime());
-          groupByTimePlan.setEndTime(queryOperator.getEndTime());
+          groupByTimePlan.setStartTime(groupByClauseComponent.getStartTime());
+          groupByTimePlan.setEndTime(groupByClauseComponent.getEndTime());
         }
       }
-      if (queryOperator.isFill()) {
-        ((GroupByTimeFillPlan) queryPlan).setFillType(queryOperator.getFillTypes());
+      if (queryOperator instanceof GroupByFillQueryOperator) {
+        GroupByFillClauseComponent groupByFillClauseComponent =
+            (GroupByFillClauseComponent) queryOperator.getSpecialClauseComponent();
+        ((GroupByTimeFillPlan) queryPlan).setFillType(groupByFillClauseComponent.getFillTypes());
         for (String aggregation : queryPlan.getAggregations()) {
           if (!SQLConstant.LAST_VALUE.equals(aggregation)) {
             throw new QueryProcessException("Group By Fill only support last_value function");
           }
         }
       } else if (queryOperator.isGroupByLevel()) {
-        queryPlan.setLevel(queryOperator.getLevel());
+        queryPlan.setLevel(queryOperator.getSpecialClauseComponent().getLevel());
         try {
           if (!verifyAllAggregationDataTypesEqual(queryOperator)) {
             throw new QueryProcessException("Aggregate among unmatched data types");
@@ -523,17 +535,19 @@ public class PhysicalGenerator {
 
     @Override
     public QueryPlan transform(QueryOperator queryOperator) throws QueryProcessException {
+      FillQueryOperator fillQueryOperator = (FillQueryOperator) queryOperator;
       if (queryOperator.hasTimeSeriesGeneratingFunction()) {
         throw new QueryProcessException("Fill functions are not supported in UDF queries.");
       }
       FillQueryPlan queryPlan = new FillQueryPlan();
-      FilterOperator timeFilter = queryOperator.getFilterOperator();
+      FilterOperator timeFilter = fillQueryOperator.getFilterOperator();
       if (!timeFilter.isSingle()) {
         throw new QueryProcessException("Slice query must select a single time point");
       }
       long time = Long.parseLong(((BasicFunctionOperator) timeFilter).getValue());
       queryPlan.setQueryTime(time);
-      queryPlan.setFillType(queryOperator.getFillTypes());
+      queryPlan.setFillType(
+          ((FillClauseComponent) fillQueryOperator.getSpecialClauseComponent()).getFillTypes());
       return queryPlan;
     }
   }
@@ -544,24 +558,25 @@ public class PhysicalGenerator {
 
     if (queryOperator.hasAggregationFunction()) {
       queryPlan = new AggPhysicalPlanRule().transform(queryOperator);
-    } else if (queryOperator.isFill()) {
+    } else if (queryOperator instanceof FillQueryOperator) {
       queryPlan = new FillPhysicalPlanRule().transform(queryOperator);
-    } else if (queryOperator.isLastQuery()) {
+    } else if (queryOperator instanceof LastQueryOperator) {
       queryPlan = new LastQueryPlan();
     } else if (queryOperator.getIndexType() != null) {
       queryPlan = new QueryIndexPlan();
     } else if (queryOperator.hasTimeSeriesGeneratingFunction()) {
-      queryPlan = new UDTFPlan(queryOperator.getSelectOperator().getZoneId());
+      queryPlan = new UDTFPlan(queryOperator.getSelectComponent().getZoneId());
       ((UDTFPlan) queryPlan)
-          .constructUdfExecutors(queryOperator.getSelectOperator().getResultColumns());
+          .constructUdfExecutors(queryOperator.getSelectComponent().getResultColumns());
     } else {
       queryPlan = new RawDataQueryPlan();
     }
 
-    if (queryOperator.isAlignByDevice()) {
+    if (queryOperator.getSpecialClauseComponent() != null
+        && queryOperator.getSpecialClauseComponent().isAlignByDevice()) {
       queryPlan = getAlignQueryPlan(queryOperator, queryPlan);
     } else {
-      queryPlan.setPaths(queryOperator.getSelectOperator().getPaths());
+      queryPlan.setPaths(queryOperator.getSelectComponent().getPaths());
       // Last query result set will not be affected by alignment
       if (queryPlan instanceof LastQueryPlan && !queryOperator.isAlignByTime()) {
         throw new QueryProcessException("Disable align cannot be applied to LAST query.");
@@ -588,9 +603,6 @@ public class PhysicalGenerator {
       }
     }
 
-    queryPlan.setWithoutAllNull(queryOperator.isWithoutAllNull());
-    queryPlan.setWithoutAnyNull(queryOperator.isWithoutAnyNull());
-
     if (queryOperator.getIndexType() != null) {
       if (queryPlan instanceof QueryIndexPlan) {
         ((QueryIndexPlan) queryPlan).setIndexType(queryOperator.getIndexType());
@@ -599,7 +611,7 @@ public class PhysicalGenerator {
       return queryPlan;
     }
 
-    queryPlan.setResultColumns(queryOperator.getSelectOperator().getResultColumns());
+    queryPlan.setResultColumns(queryOperator.getSelectComponent().getResultColumns());
 
     try {
       List<PartialPath> paths = queryPlan.getPaths();
@@ -611,9 +623,14 @@ public class PhysicalGenerator {
       throw new QueryProcessException(e);
     }
 
-    queryPlan.setRowLimit(queryOperator.getRowLimit());
-    queryPlan.setRowOffset(queryOperator.getRowOffset());
-    queryPlan.setAscending(queryOperator.isAscending());
+    if (queryOperator.getSpecialClauseComponent() != null) {
+      SpecialClauseComponent specialClauseComponent = queryOperator.getSpecialClauseComponent();
+      queryPlan.setWithoutAllNull(specialClauseComponent.isWithoutAllNull());
+      queryPlan.setWithoutAnyNull(specialClauseComponent.isWithoutAnyNull());
+      queryPlan.setRowLimit(specialClauseComponent.getRowLimit());
+      queryPlan.setRowOffset(specialClauseComponent.getRowOffset());
+      queryPlan.setAscending(specialClauseComponent.isAscending());
+    }
 
     return queryPlan;
   }
@@ -634,11 +651,11 @@ public class PhysicalGenerator {
       alignByDevicePlan.setAggregationPlan((AggregationPlan) queryPlan);
     }
 
-    List<PartialPath> prefixPaths = queryOperator.getFromOperator().getPrefixPaths();
+    List<PartialPath> prefixPaths = queryOperator.getFromComponent().getPrefixPaths();
     // remove stars in fromPaths and get deviceId with deduplication
     List<PartialPath> devices = this.removeStarsInDeviceWithUnique(prefixPaths);
-    List<ResultColumn> resultColumns = queryOperator.getSelectOperator().getResultColumns();
-    List<String> originAggregations = queryOperator.getSelectOperator().getAggregationFunctions();
+    List<ResultColumn> resultColumns = queryOperator.getSelectComponent().getResultColumns();
+    List<String> originAggregations = queryOperator.getSelectComponent().getAggregationFunctions();
 
     // to record result measurement columns
     List<String> measurements = new ArrayList<>();
@@ -771,9 +788,9 @@ public class PhysicalGenerator {
     }
 
     // slimit trim on the measurementColumnList
-    if (queryOperator.hasSlimit()) {
-      int seriesSlimit = queryOperator.getSeriesLimit();
-      int seriesOffset = queryOperator.getSeriesOffset();
+    if (queryOperator.getSpecialClauseComponent().hasSlimit()) {
+      int seriesSlimit = queryOperator.getSpecialClauseComponent().getSeriesLimit();
+      int seriesOffset = queryOperator.getSpecialClauseComponent().getSeriesOffset();
       measurements = slimitTrimColumn(measurements, seriesSlimit, seriesOffset);
     }
 
@@ -890,12 +907,12 @@ public class PhysicalGenerator {
 
   private static boolean verifyAllAggregationDataTypesEqual(QueryOperator queryOperator)
       throws MetadataException {
-    List<String> aggregations = queryOperator.getSelectOperator().getAggregationFunctions();
+    List<String> aggregations = queryOperator.getSelectComponent().getAggregationFunctions();
     if (aggregations.isEmpty()) {
       return true;
     }
 
-    List<PartialPath> paths = queryOperator.getSelectOperator().getPaths();
+    List<PartialPath> paths = queryOperator.getSelectComponent().getPaths();
     List<TSDataType> dataTypes = SchemaUtils.getSeriesTypesByPaths(paths);
     String aggType = aggregations.get(0);
     switch (aggType) {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index 89db221..f8b3eb8 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@ -27,10 +27,11 @@ import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
 import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
-import org.apache.iotdb.db.qp.logical.crud.FromOperator;
+import org.apache.iotdb.db.qp.logical.crud.FromComponent;
 import org.apache.iotdb.db.qp.logical.crud.FunctionOperator;
+import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
+import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.qp.utils.WildcardsRemover;
 import org.apache.iotdb.db.query.expression.ResultColumn;
 import org.apache.iotdb.db.service.IoTDB;
@@ -68,13 +69,13 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
   }
 
   private static boolean optimizable(QueryOperator queryOperator) {
-    FromOperator from = queryOperator.getFromOperator();
+    FromComponent from = queryOperator.getFromComponent();
     if (from == null || from.getPrefixPaths().isEmpty()) {
       LOGGER.warn(WARNING_NO_PREFIX_PATHS);
       return false;
     }
 
-    SelectOperator select = queryOperator.getSelectOperator();
+    SelectComponent select = queryOperator.getSelectComponent();
     if (select == null || select.getResultColumns().isEmpty()) {
       LOGGER.warn(WARNING_NO_SUFFIX_PATHS);
       return false;
@@ -84,35 +85,35 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
   }
 
   private void concatSelect(QueryOperator queryOperator) throws LogicalOptimizeException {
-    if (queryOperator.isAlignByDevice() && !queryOperator.isLastQuery()) {
+    if (queryOperator.isAlignByDevice() && !(queryOperator instanceof LastQueryOperator)) {
       return;
     }
 
-    List<PartialPath> prefixPaths = queryOperator.getFromOperator().getPrefixPaths();
+    List<PartialPath> prefixPaths = queryOperator.getFromComponent().getPrefixPaths();
     List<ResultColumn> resultColumns = new ArrayList<>();
-    for (ResultColumn suffixColumn : queryOperator.getSelectOperator().getResultColumns()) {
+    for (ResultColumn suffixColumn : queryOperator.getSelectComponent().getResultColumns()) {
       suffixColumn.concat(prefixPaths, resultColumns);
     }
-    queryOperator.getSelectOperator().setResultColumns(resultColumns);
+    queryOperator.getSelectComponent().setResultColumns(resultColumns);
   }
 
   private void removeWildcardsInSelectPaths(QueryOperator queryOperator, int fetchSize)
       throws LogicalOptimizeException, PathNumOverLimitException {
-    if (queryOperator.isAlignByDevice() && !queryOperator.isLastQuery()
+    if (queryOperator.isAlignByDevice() && !(queryOperator instanceof LastQueryOperator)
         || queryOperator.getIndexType() != null) {
       return;
     }
 
     WildcardsRemover wildcardsRemover = new WildcardsRemover(this, queryOperator, fetchSize);
     List<ResultColumn> resultColumns = new ArrayList<>();
-    for (ResultColumn resultColumn : queryOperator.getSelectOperator().getResultColumns()) {
+    for (ResultColumn resultColumn : queryOperator.getSelectComponent().getResultColumns()) {
       resultColumn.removeWildcards(wildcardsRemover, resultColumns);
       if (wildcardsRemover.checkIfPathNumberIsOverLimit(resultColumns)) {
         break;
       }
     }
     wildcardsRemover.checkIfSoffsetIsExceeded(resultColumns);
-    queryOperator.getSelectOperator().setResultColumns(resultColumns);
+    queryOperator.getSelectComponent().setResultColumns(resultColumns);
   }
 
   private void concatFilter(QueryOperator queryOperator) throws LogicalOptimizeException {
@@ -122,11 +123,11 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
     }
 
     Set<PartialPath> filterPaths = new HashSet<>();
-    if (!queryOperator.isAlignByDevice() || queryOperator.isLastQuery()) {
+    if (!queryOperator.isAlignByDevice() || queryOperator instanceof LastQueryOperator) {
       // GROUP_BY_DEVICE leaves the concatFilter to PhysicalGenerator to optimize filter without
       // prefix first
       queryOperator.setFilterOperator(
-          concatFilter(queryOperator.getFromOperator().getPrefixPaths(), filter, filterPaths));
+          concatFilter(queryOperator.getFromComponent().getPrefixPaths(), filter, filterPaths));
     }
     queryOperator.getFilterOperator().setPathSet(filterPaths);
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java b/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
index d2e6054..d841f0e 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.PathNumOverLimitException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
@@ -39,11 +40,11 @@ public class WildcardsRemover {
   private final ConcatPathOptimizer concatPathOptimizer;
 
   private final int maxDeduplicatedPathNum;
-  private final int soffset;
+  private int soffset = 0;
 
-  private int offset;
-  private int limit;
-  private int consumed;
+  private int offset = 0;
+  private int limit = Integer.MAX_VALUE;
+  private int consumed = 0;
 
   public WildcardsRemover(
       ConcatPathOptimizer concatPathOptimizer, QueryOperator queryOperator, int fetchSize) {
@@ -54,25 +55,21 @@ public class WildcardsRemover {
     // To avoid overflowing because logicalOptimize function may do maxDeduplicatedPathNum + 1, we
     // set it to Integer.MAX_VALUE - 1
     maxDeduplicatedPathNum =
-        queryOperator.isLastQuery()
+        queryOperator instanceof LastQueryOperator
             ? Integer.MAX_VALUE - 1
             : QueryResourceManager.getInstance().getMaxDeduplicatedPathNum(fetchSize);
-    soffset = queryOperator.getSeriesOffset();
-    offset = soffset;
+    if (queryOperator.getSpecialClauseComponent() != null) {
+      soffset = queryOperator.getSpecialClauseComponent().getSeriesOffset();
+      offset = soffset;
 
-    final int slimit = queryOperator.getSeriesLimit();
-    limit = slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
-
-    consumed = 0;
+      final int slimit = queryOperator.getSpecialClauseComponent().getSeriesLimit();
+      limit = slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
+    }
   }
 
   public WildcardsRemover(ConcatPathOptimizer concatPathOptimizer) {
     this.concatPathOptimizer = concatPathOptimizer;
-
     maxDeduplicatedPathNum = Integer.MAX_VALUE - 1;
-    soffset = 0;
-    limit = maxDeduplicatedPathNum + 1;
-    consumed = 0;
   }
 
   public List<PartialPath> removeWildcardFrom(PartialPath path) throws LogicalOptimizeException {
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
index a1c06bb..0db57f3 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
@@ -526,7 +526,7 @@ public class IoTDBGroupByFillIT {
       hasResultSet =
           statement.execute(
               "select last_value(temperature) from root.ln.wf01.wt01 "
-                  + "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast])order by time desc");
+                  + "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast]) order by time desc");
 
       assertTrue(hasResultSet);
       try (ResultSet resultSet = statement.getResultSet()) {
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java b/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
index 38593cb..c8515d2 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
@@ -108,9 +108,9 @@ public class IndexLogicalPlanTest {
     Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
     Assert.assertEquals(
         "Glu",
-        queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
+        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
     Assert.assertEquals(
-        "root.Ery.*", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
+        "root.Ery.*", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
     Assert.assertEquals(IndexType.RTREE_PAA, queryOperator.getIndexType());
     Assert.assertEquals(2, queryOperator.getProps().size());
     Assert.assertEquals(2, (int) queryOperator.getProps().get(TOP_K));
@@ -132,9 +132,9 @@ public class IndexLogicalPlanTest {
     Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
     Assert.assertEquals(
         "Speed",
-        queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
+        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
     Assert.assertEquals(
-        "root.Wind.AZQ02", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
+        "root.Wind.AZQ02", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
     Assert.assertEquals(IndexType.ELB_INDEX, queryOperator.getIndexType());
     Assert.assertEquals(2, queryOperator.getProps().size());
     Assert.assertEquals("[1.0, 2.0, 1.0]", queryOperator.getProps().get(THRESHOLD).toString());
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/logical/LogicalPlanSmallTest.java b/server/src/test/java/org/apache/iotdb/db/qp/logical/LogicalPlanSmallTest.java
index d2e428d..77110f2 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/logical/LogicalPlanSmallTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/logical/LogicalPlanSmallTest.java
@@ -43,63 +43,63 @@ public class LogicalPlanSmallTest {
   @Test
   public void testLimit() {
     String sqlStr = "select * from root.vehicle.d1 limit 10";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
-    Assert.assertEquals(0, ((QueryOperator) operator).getSeriesLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
+    Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
   }
 
   @Test
   public void testOffset() {
     String sqlStr = "select * from root.vehicle.d1 limit 10 offset 20";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
-    Assert.assertEquals(20, ((QueryOperator) operator).getRowOffset());
-    Assert.assertEquals(0, ((QueryOperator) operator).getSeriesLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
+    Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
+    Assert.assertEquals(20, operator.getSpecialClauseComponent().getRowOffset());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
   }
 
   @Test
   public void testSlimit() {
     String sqlStr = "select * from root.vehicle.d1 limit 10 slimit 1";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
-    Assert.assertEquals(1, ((QueryOperator) operator).getSeriesLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
+    Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
+    Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
   }
 
   @Test
   public void testSOffset() {
     String sqlStr =
         "select * from root.vehicle.d1 where s1 < 20 and time <= now() limit 50 slimit 10 soffset 100";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertEquals(50, ((QueryOperator) operator).getRowLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
-    Assert.assertEquals(10, ((QueryOperator) operator).getSeriesLimit());
-    Assert.assertEquals(100, ((QueryOperator) operator).getSeriesOffset());
+    Assert.assertEquals(50, operator.getSpecialClauseComponent().getRowLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
+    Assert.assertEquals(10, operator.getSpecialClauseComponent().getSeriesLimit());
+    Assert.assertEquals(100, operator.getSpecialClauseComponent().getSeriesOffset());
   }
 
   @Test
   public void testSOffsetTimestamp() {
     String sqlStr =
         "select * from root.vehicle.d1 where s1 < 20 and timestamp <= now() limit 50 slimit 10 soffset 100";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertEquals(50, ((QueryOperator) operator).getRowLimit());
-    Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
-    Assert.assertEquals(10, ((QueryOperator) operator).getSeriesLimit());
-    Assert.assertEquals(100, ((QueryOperator) operator).getSeriesOffset());
+    Assert.assertEquals(50, operator.getSpecialClauseComponent().getRowLimit());
+    Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
+    Assert.assertEquals(10, operator.getSpecialClauseComponent().getSeriesLimit());
+    Assert.assertEquals(100, operator.getSpecialClauseComponent().getSeriesOffset());
   }
 
   @Test(expected = SQLParserException.class)
@@ -171,10 +171,10 @@ public class LogicalPlanSmallTest {
   public void testSoffsetNotPositive() {
     String sqlStr =
         "select * from root.vehicle.d1 where s1 < 20 and time <= now() slimit 1 soffset 1";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
-    Assert.assertEquals(1, ((QueryOperator) operator).getSeriesOffset());
-    Assert.assertEquals(1, ((QueryOperator) operator).getSeriesLimit());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesOffset());
+    Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesLimit());
   }
 
   @Test(expected = LogicalOptimizeException.class)
@@ -204,10 +204,10 @@ public class LogicalPlanSmallTest {
   @Test
   public void testDisableAlign() {
     String sqlStr = "select * from root.vehicle disable align";
-    RootOperator operator =
-        (RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
+    QueryOperator operator =
+        (QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
     Assert.assertEquals(QueryOperator.class, operator.getClass());
-    Assert.assertFalse(((QueryOperator) operator).isAlignByTime());
+    Assert.assertFalse(operator.isAlignByTime());
   }
 
   @Test
@@ -239,7 +239,7 @@ public class LogicalPlanSmallTest {
     Assert.assertEquals(QueryOperator.class, operator.getClass());
     ArrayList<PartialPath> paths = new ArrayList<>();
     paths.add(new PartialPath("*"));
-    Assert.assertEquals(paths, ((QueryOperator) operator).getSelectOperator().getPaths());
+    Assert.assertEquals(paths, ((QueryOperator) operator).getSelectComponent().getPaths());
   }
 
   @Test

[iotdb] 01/06: Merge master and fix conflicts

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2fe872483c75291474e6ba18f4c4ad84ee824201
Merge: 0ba9a37 222396c
Author: Alima777 <wx...@gmail.com>
AuthorDate: Tue May 18 22:01:49 2021 +0800

    Merge master and fix conflicts

 .github/workflows/client.yml                       |   7 +-
 .github/workflows/main-unix.yml                    |   2 +-
 .github/workflows/main-win.yml                     |   2 +-
 .../ContributeGuide.md => CONTRIBUTING.md          |  63 +++---
 Jenkinsfile                                        |   2 +-
 LICENSE-binary                                     |   2 +-
 README.md                                          |  22 +-
 README_ZH.md                                       |  16 +-
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4   |  19 +-
 .../main/java/org/apache/iotdb/tool/ImportCsv.java |   3 +
 client-cpp/src/main/CMakeLists.txt                 |   2 +-
 client-cpp/src/test/CMakeLists.txt                 |   2 +-
 client-py/README.md                                |   5 +-
 cluster/pom.xml                                    |   2 +-
 .../resources/conf/iotdb-cluster.properties        |   3 +
 .../java/org/apache/iotdb/cluster/ClusterMain.java |  13 ++
 .../cluster/client/async/AsyncDataClient.java      |   4 +-
 .../client/async/AsyncDataHeartbeatClient.java     |   4 +-
 .../cluster/client/async/AsyncMetaClient.java      |   4 +-
 .../client/async/AsyncMetaHeartbeatClient.java     |   4 +-
 .../iotdb/cluster/client/sync/SyncDataClient.java  |   2 +
 .../client/sync/SyncDataHeartbeatClient.java       |   2 +
 .../iotdb/cluster/client/sync/SyncMetaClient.java  |   2 +
 .../client/sync/SyncMetaHeartbeatClient.java       |   2 +
 .../apache/iotdb/cluster/config/ClusterConfig.java |   9 +
 .../iotdb/cluster/config/ClusterDescriptor.java    |   9 +-
 .../iotdb/cluster/log/applier/BaseApplier.java     |  37 +++-
 .../apache/iotdb/cluster/metadata/CMManager.java   |  12 +-
 .../cluster/query/ClusterDataQueryExecutor.java    |   5 +-
 .../cluster/query/reader/ClusterReaderFactory.java |  12 +-
 .../query/reader/mult/RemoteMultSeriesReader.java  |   7 +-
 .../iotdb/cluster/server/MetaClusterServer.java    |  27 ++-
 .../server/clusterinfo/ClusterInfoServer.java      |  94 ++++++++
 .../server/clusterinfo/ClusterInfoServerMBean.java |  23 +-
 .../server/clusterinfo/ClusterInfoServiceImpl.java |  71 ++++++
 .../ClusterInfoServiceThriftHandler.java           |  55 +++++
 .../cluster/utils/nodetool/ClusterMonitor.java     |   2 +
 .../utils/nodetool/ClusterMonitorMBean.java        |   2 +-
 .../cluster/client/sync/SyncDataClientTest.java    |   6 +-
 .../cluster/client/sync/SyncMetaClientTest.java    |   6 +-
 .../cluster/common/TestAsyncClientFactory.java     |   4 +-
 .../cluster/common/TestSyncClientFactory.java      |  13 ++
 .../cluster/log/applier/DataLogApplierTest.java    |  35 +++
 .../cluster/log/snapshot/DataSnapshotTest.java     |  14 ++
 .../cluster/log/snapshot/PullSnapshotTaskTest.java |  14 ++
 .../query/groupby/MergeGroupByExecutorTest.java    |  23 +-
 .../query/groupby/RemoteGroupByExecutorTest.java   |  23 +-
 .../server/clusterinfo/ClusterInfoServerTest.java  |  96 ++++++++
 .../clusterinfo/ClusterInfoServiceImplTest.java    |  98 +++++++++
 .../cluster/server/member/DataGroupMemberTest.java |  28 ++-
 .../cluster/server/member/MetaGroupMemberTest.java |  20 +-
 .../resources/node1conf/iotdb-cluster.properties   |   1 +
 .../resources/node2conf/iotdb-cluster.properties   |   1 +
 .../resources/node3conf/iotdb-cluster.properties   |   1 +
 compile-tools/thrift/pom.xml                       |   2 +-
 docs/Development/ContributeGuide.md                |  62 +++---
 docs/UserGuide/API/Programming-Java-Native-API.md  |  98 +++++++++
 .../Administration-Management/Administration.md    |   7 +-
 docs/UserGuide/Cluster/Cluster-Setup.md            |   9 +
 .../Data-Concept/Data-Model-and-Terminology.md     |   4 +-
 .../Ecosystem Integration/Zeppelin-IoTDB.md        |   2 +-
 .../DDL-Data-Definition-Language.md                |   2 +-
 .../DML-Data-Manipulation-Language.md              |  14 ++
 docs/zh/Development/ContributeGuide.md             |  26 +--
 .../UserGuide/API/Programming-Java-Native-API.md   |  95 ++++++++
 .../Administration-Management/Administration.md    |   5 +-
 docs/zh/UserGuide/Cluster/Cluster-Setup.md         |   9 +
 .../Data-Concept/Data-Model-and-Terminology.md     |   4 +-
 .../Ecosystem Integration/Zeppelin-IoTDB.md        |   2 +-
 .../DDL-Data-Definition-Language.md                |   2 +-
 .../DML-Data-Manipulation-Language.md              |  14 ++
 example/pom.xml                                    |   6 +
 {thrift-sync => example/rabbitmq}/pom.xml          |  42 +---
 example/rabbitmq/readme.md                         |  63 ++++++
 .../java/org/apache/iotdb/rabbitmq/Constant.java   |  68 ++++++
 .../iotdb/rabbitmq/RabbitMQChannelUtils.java       |  49 +++++
 .../apache/iotdb/rabbitmq/RabbitMQConsumer.java    | 132 +++++++++++
 .../apache/iotdb/rabbitmq/RabbitMQProducer.java    |  49 +++++
 example/trigger/pom.xml                            |  66 +++---
 .../apache/iotdb/tsfile/TsFileSequenceRead.java    |   5 +
 example/udf/pom.xml                                |  66 +++---
 jdbc/src/main/feature/feature.xml                  |   2 +-
 .../org/apache/iotdb/jdbc/IoTDBConnection.java     |   9 +-
 .../iotdb/jdbc/IoTDBNonAlignJDBCResultSet.java     |   9 +-
 .../java/org/apache/iotdb/jdbc/IoTDBStatement.java |  24 +-
 pom.xml                                            |  25 ++-
 server/pom.xml                                     |  12 +-
 .../resources/conf/iotdb-engine.properties         |  13 +-
 .../apache/iotdb/db/auth/entity/PrivilegeType.java |   1 +
 .../org/apache/iotdb/db/concurrent/ThreadName.java |   3 +-
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  34 ++-
 .../org/apache/iotdb/db/conf/IoTDBConfigCheck.java |  28 ++-
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  19 ++
 .../db/engine/cache/TimeSeriesMetadataCache.java   | 121 +++++++++++
 .../db/engine/compaction/TsFileManagement.java     |  21 +-
 .../level/LevelCompactionTsFileManagement.java     |  51 +++--
 .../engine/compaction/utils/CompactionUtils.java   |  81 +++++--
 .../engine/storagegroup/StorageGroupProcessor.java |  42 +++-
 .../db/engine/storagegroup/TsFileResource.java     |  15 +-
 .../org/apache/iotdb/db/metadata/MManager.java     |  64 ++++--
 .../org/apache/iotdb/db/metadata/PartialPath.java  |  15 ++
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |   9 +-
 .../iotdb/db/qp/logical/crud/QueryOperator.java    |  22 ++
 .../org/apache/iotdb/db/qp/physical/BatchPlan.java |  54 +++--
 .../db/qp/physical/crud/InsertMultiTabletPlan.java |  39 +++-
 .../physical/crud/InsertRowsOfOneDevicePlan.java   |  33 ++-
 .../iotdb/db/qp/physical/crud/InsertRowsPlan.java  |  39 +++-
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |  22 ++
 .../qp/physical/sys/CreateMultiTimeSeriesPlan.java |  39 +++-
 .../apache/iotdb/db/qp/physical/sys/ShowPlan.java  |   1 -
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 147 ++++++-------
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |   5 +-
 .../apache/iotdb/db/qp/utils/DatetimeUtils.java    |  33 ++-
 .../dataset/RawQueryDataSetWithoutValueFilter.java |  79 +++++--
 .../apache/iotdb/db/query/dataset/ShowDataSet.java |  12 +-
 .../db/query/executor/fill/LastPointReader.java    |  51 ++---
 .../chunk/metadata/DiskChunkMetadataLoader.java    |   2 +-
 .../query/reader/series/SeriesAggregateReader.java |   2 +-
 .../reader/series/SeriesRawDataBatchReader.java    |   4 +-
 .../iotdb/db/query/reader/series/SeriesReader.java |  13 +-
 .../reader/series/SeriesReaderByTimestamp.java     |   2 +-
 .../query/reader/series/SeriesReaderFactory.java   |  94 --------
 .../db/query/reader/series/VectorSeriesReader.java | 144 ------------
 .../org/apache/iotdb/db/service/ServiceType.java   |   5 +-
 .../org/apache/iotdb/db/service/TSServiceImpl.java |   3 +-
 .../apache/iotdb/db/sync/conf/SyncConstant.java    |   5 +-
 .../iotdb/db/sync/sender/transfer/SyncClient.java  |  27 ++-
 .../java/org/apache/iotdb/db/utils/AuthUtils.java  |   2 -
 .../org/apache/iotdb/db/utils/FileLoaderUtils.java |  94 +++++++-
 .../apache/iotdb/db/utils/QueryDataSetUtils.java   |  18 +-
 .../iotdb/db/utils/datastructure/VectorTVList.java |   6 +-
 .../apache/iotdb/db/auth/AuthorityCheckerTest.java |   2 -
 .../auth/authorizer/LocalFileAuthorizerTest.java   |   6 +-
 .../db/engine/compaction/CompactionChunkTest.java  |   4 +-
 .../compaction/LevelCompactionCacheTest.java       |   3 +-
 .../engine/compaction/LevelCompactionLogTest.java  |   3 +-
 .../compaction/LevelCompactionMergeTest.java       |  83 ++++++-
 .../compaction/LevelCompactionMoreDataTest.java    |   3 +-
 .../NoCompactionTsFileManagementTest.java          |   4 +-
 .../iotdb/db/integration/IoTDBGroupByMonthIT.java  |  29 +++
 .../iotdb/db/integration/IoTDBSimpleQueryIT.java   |  36 +++
 .../db/integration/IoTDBWithoutAllNullIT.java      | 192 ++++++++++++++++
 .../db/integration/IoTDBWithoutAnyNullIT.java      | 221 +++++++++++++++++++
 .../iotdb/db/metadata/MManagerBasicTest.java       | 242 +++++++++++++++++++++
 .../db/qp/utils/DatetimeQueryDataSetUtilsTest.java |  28 +++
 .../org/apache/iotdb/db/script/EnvScriptIT.java    |   6 +-
 .../apache/iotdb/db/sink/LocalIoTDBSinkTest.java   |   3 +-
 .../apache/iotdb/db/utils/EnvironmentUtils.java    |  12 +-
 .../iotdb/rpc/AutoScalingBufferReadTransport.java  |  13 ++
 .../iotdb/rpc/AutoScalingBufferWriteTransport.java |  15 ++
 .../java/org/apache/iotdb/rpc/IoTDBRpcDataSet.java |  20 +-
 .../org/apache/iotdb/rpc/RpcTransportFactory.java  |   3 +-
 .../rpc/TCompressedElasticFramedTransport.java     |   2 +-
 .../org/apache/iotdb/rpc/TConfigurationConst.java  |  28 +--
 .../apache/iotdb/rpc/TElasticFramedTransport.java  |  20 +-
 .../iotdb/rpc/TNonblockingSocketWrapper.java       |  60 +++++
 .../java/org/apache/iotdb/rpc/TSocketWrapper.java  |  68 ++++++
 .../apache/iotdb/session/SessionConnection.java    |  13 +-
 .../apache/iotdb/session/pool/SessionPoolTest.java | 117 +++++++---
 session/src/test/resources/logback.xml             |  40 ++++
 .../test/java/org/apache/iotdb/db/sql/Cases.java   | 149 +++++++++++++
 .../java/org/apache/iotdb/db/sql/ClusterIT.java    | 150 +++++--------
 .../java/org/apache/iotdb/db/sql/SingleNodeIT.java |  92 ++------
 .../iotdb/db/sql/node1/OneNodeClusterIT.java       |  54 +++++
 .../db/sql/nodes3/AbstractThreeNodeClusterIT.java  |  61 ++++++
 .../iotdb/db/sql/nodes3/ThreeNodeCluster1IT.java   |  24 +-
 .../iotdb/db/sql/nodes3/ThreeNodeCluster2IT.java   |  27 +--
 .../db/sql/nodes5/AbstractFiveNodeClusterIT.java   |  85 ++++++++
 .../iotdb/db/sql/nodes5/FiveNodeCluster1IT.java    |  24 +-
 .../iotdb/db/sql/nodes5/FiveNodeCluster2IT.java    |  27 +--
 .../iotdb/db/sql/nodes5/FiveNodeCluster4IT.java    |  27 +--
 .../test/resources/1node/iotdb-cluster.properties  |   2 +-
 thrift-cluster/src/main/thrift/cluster.thrift      |  52 ++++-
 thrift-sync/pom.xml                                |   5 -
 .../tsfile/common/constant/TsFileConstant.java     |   3 +
 .../iotdb/tsfile/file/metadata/ChunkMetadata.java  |  16 ++
 .../iotdb/tsfile/file/metadata/IChunkMetadata.java |   6 +
 .../tsfile/file/metadata/ITimeSeriesMetadata.java  |   3 +
 .../file/metadata/MetadataIndexConstructor.java    |  54 ++++-
 .../tsfile/file/metadata/MetadataIndexNode.java    |   2 +-
 .../tsfile/file/metadata/TimeseriesMetadata.java   |  20 +-
 .../tsfile/file/metadata/VectorChunkMetadata.java  |  24 ++
 .../file/metadata/VectorTimeSeriesMetadata.java    |  16 ++
 .../iotdb/tsfile/read/TsFileSequenceReader.java    |  80 +++++--
 .../apache/iotdb/tsfile/read/common/RowRecord.java |  38 +++-
 .../tsfile/read/query/dataset/QueryDataSet.java    |  29 ++-
 .../tsfile/v2/file/metadata/TsFileMetadataV2.java  |   9 +-
 .../tsfile/v2/read/TsFileSequenceReaderForV2.java  |  16 +-
 .../iotdb/tsfile/write/chunk/TimeChunkWriter.java  |   3 +-
 .../iotdb/tsfile/write/chunk/ValueChunkWriter.java |   3 +-
 .../iotdb/tsfile/write/writer/TsFileIOWriter.java  | 121 ++++++++---
 191 files changed, 4597 insertions(+), 1336 deletions(-)

diff --cc server/pom.xml
index 4d0f08d,08944e2..07219f6
--- a/server/pom.xml
+++ b/server/pom.xml
@@@ -213,12 -213,6 +213,12 @@@
              <version>4.3.5</version>
              <scope>compile</scope>
          </dependency>
-       <dependency>
-         <groupId>org.apache.calcite</groupId>
-         <artifactId>calcite-linq4j</artifactId>
-         <version>1.10.0</version>
-         <scope>compile</scope>
-       </dependency>
++        <dependency>
++            <groupId>org.apache.calcite</groupId>
++            <artifactId>calcite-linq4j</artifactId>
++            <version>1.10.0</version>
++            <scope>compile</scope>
++        </dependency>
      </dependencies>
      <build>
          <plugins>
diff --cc server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index e52dd92,c640470..7e3055b
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@@ -279,15 -257,19 +285,31 @@@ public class QueryOperator extends Root
      this.ascending = ascending;
    }
  
 +  public boolean isLastQuery() {
 +    return selectOperator.isLastQuery();
 +  }
 +
 +  public boolean hasAggregationFunction() {
 +    return selectOperator.hasAggregationFunction();
 +  }
 +
 +  public boolean hasTimeSeriesGeneratingFunction() {
 +    return selectOperator.hasTimeSeriesGeneratingFunction();
 +  }
++
+   public boolean isWithoutAnyNull() {
+     return withoutAnyNull;
+   }
+ 
+   public void setWithoutAnyNull(boolean withoutAnyNull) {
+     this.withoutAnyNull = withoutAnyNull;
+   }
+ 
+   public boolean isWithoutAllNull() {
+     return withoutAllNull;
+   }
+ 
+   public void setWithoutAllNull(boolean withoutAllNull) {
+     this.withoutAllNull = withoutAllNull;
+   }
  }
diff --cc server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
index 6bd6ce4,a13de6f..d43413f
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
@@@ -157,11 -157,19 +163,27 @@@ public abstract class QueryPlan extend
      this.vectorPathToIndex = vectorPathToIndex;
    }
  
 +  public List<ResultColumn> getResultColumns() {
 +    return resultColumns;
 +  }
 +
 +  public void setResultColumns(List<ResultColumn> resultColumns) {
 +    this.resultColumns = resultColumns;
 +  }
++
+   public boolean isWithoutAnyNull() {
+     return withoutAnyNull;
+   }
+ 
+   public void setWithoutAnyNull(boolean withoutAnyNull) {
+     this.withoutAnyNull = withoutAnyNull;
+   }
+ 
+   public boolean isWithoutAllNull() {
+     return withoutAllNull;
+   }
+ 
+   public void setWithoutAllNull(boolean withoutAllNull) {
+     this.withoutAllNull = withoutAllNull;
+   }
  }
diff --cc server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 82ef1e0,faa4499..44d9131
--- 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
@@@ -78,9 -78,11 +78,9 @@@ import org.apache.iotdb.db.qp.logical.s
  import org.apache.iotdb.db.qp.logical.sys.StopTriggerOperator;
  import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
  import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 -import org.apache.iotdb.db.qp.sql.SqlBaseParser.AggregationCallContext;
 -import org.apache.iotdb.db.qp.sql.SqlBaseParser.AggregationElementContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.AliasClauseContext;
- import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseOrDisableAlignInSpecialLimitContext;
- import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceStatementOrDisableAlignInSpecialClauseContext;
+ import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseOrDisableAlignContext;
+ import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseOrDisableAlignStatementContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterClauseContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterTimeseriesContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterUserContext;
@@@ -206,8 -212,11 +206,9 @@@ import org.apache.iotdb.db.qp.sql.SqlBa
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOnContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.TriggerAttributeContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.TypeClauseContext;
 -import org.apache.iotdb.db.qp.sql.SqlBaseParser.UdfAttributeContext;
 -import org.apache.iotdb.db.qp.sql.SqlBaseParser.UdfCallContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.UnsetTTLStatementContext;
  import org.apache.iotdb.db.qp.sql.SqlBaseParser.WhereClauseContext;
+ import org.apache.iotdb.db.qp.sql.SqlBaseParser.WithoutNullStatementContext;
  import org.apache.iotdb.db.qp.utils.DatetimeUtils;
  import org.apache.iotdb.db.query.executor.fill.IFill;
  import org.apache.iotdb.db.query.executor.fill.LinearFill;
diff --cc server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 9bfc7e1,217a3bb..5c81c6e
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@@ -540,9 -540,9 +540,9 @@@ public class PhysicalGenerator 
  
    @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
    private PhysicalPlan transformQuery(QueryOperator queryOperator) throws QueryProcessException {
-     QueryPlan queryPlan = null;
+     QueryPlan queryPlan;
  
 -    if (queryOperator.hasAggregation()) {
 +    if (queryOperator.hasAggregationFunction()) {
        queryPlan = new AggPhysicalPlanRule().transform(queryOperator);
      } else if (queryOperator.isFill()) {
        queryPlan = new FillPhysicalPlanRule().transform(queryOperator);

[iotdb] 04/06: Reimplement logical checker

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 17c34d37000ec228fda0410507c76767af9e08b1
Author: Alima777 <wx...@gmail.com>
AuthorDate: Thu May 20 11:12:59 2021 +0800

    Reimplement logical checker
---
 .../qp/logical/crud/AggregationQueryOperator.java  | 36 +++++++++-
 .../db/qp/logical/crud/FillQueryOperator.java      | 19 ++++-
 .../db/qp/logical/crud/GroupByQueryOperator.java   |  2 +-
 .../db/qp/logical/crud/LastQueryOperator.java      | 17 +++++
 .../iotdb/db/qp/logical/crud/QueryOperator.java    | 22 +++++-
 .../iotdb/db/qp/logical/crud/UDFQueryOperator.java | 12 +++-
 .../iotdb/db/qp/physical/crud/AggregationPlan.java |  8 ---
 .../iotdb/db/qp/physical/crud/FillQueryPlan.java   |  9 ---
 .../iotdb/db/qp/physical/crud/GroupByTimePlan.java |  2 -
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |  3 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 30 ++++----
 .../iotdb/db/qp/strategy/LogicalChecker.java       | 81 ++--------------------
 .../iotdb/db/integration/IOTDBGroupByIT.java       |  4 +-
 .../iotdb/db/integration/IoTDBDisableAlignIT.java  | 19 ++---
 .../iotdb/db/integration/IoTDBGroupByFillIT.java   |  4 +-
 .../aggregation/IoTDBAggregationByLevelIT.java     |  4 +-
 16 files changed, 138 insertions(+), 134 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
index fd790ff..66eecef 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/AggregationQueryOperator.java
@@ -18,4 +18,38 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-public class AggregationQueryOperator extends QueryOperator {}
+import org.apache.iotdb.db.exception.query.LogicalOperatorException;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.db.query.expression.ResultColumn;
+import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+
+public class AggregationQueryOperator extends QueryOperator {
+
+  public static final String ERROR_MESSAGE1 =
+      "Common queries and aggregated queries are not allowed to appear at the same time";
+
+  public AggregationQueryOperator() {}
+
+  public AggregationQueryOperator(QueryOperator queryOperator) {
+    this.selectComponent = queryOperator.getSelectComponent();
+    this.fromComponent = queryOperator.getFromComponent();
+    this.filterOperator = queryOperator.getFilterOperator();
+    this.specialClauseComponent = queryOperator.getSpecialClauseComponent();
+  }
+
+  @Override
+  public void check() throws LogicalOperatorException {
+    super.check();
+
+    if (!isAlignByTime()) {
+      throw new LogicalOperatorException("AGGREGATION doesn't support disable align clause.");
+    }
+
+    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
+      Expression expression = resultColumn.getExpression();
+      if (expression instanceof TimeSeriesOperand) {
+        throw new LogicalOperatorException(ERROR_MESSAGE1);
+      }
+    }
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
index 985ae16..b18de97 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/FillQueryOperator.java
@@ -18,4 +18,21 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-public class FillQueryOperator extends QueryOperator {}
+import org.apache.iotdb.db.exception.query.LogicalOperatorException;
+import org.apache.iotdb.db.qp.constant.SQLConstant;
+
+public class FillQueryOperator extends QueryOperator {
+
+  @Override
+  public void check() throws LogicalOperatorException {
+    super.check();
+
+    if (!isAlignByTime()) {
+      throw new LogicalOperatorException("FILL doesn't support disable align clause.");
+    }
+
+    if (!filterOperator.isLeaf() || filterOperator.getTokenIntType() != SQLConstant.EQUAL) {
+      throw new LogicalOperatorException("Only \"=\" can be used in fill function");
+    }
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
index ec9a938..10835bb 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/GroupByQueryOperator.java
@@ -18,4 +18,4 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-public class GroupByQueryOperator extends QueryOperator {}
+public class GroupByQueryOperator extends AggregationQueryOperator {}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
index 51b43c6..72b73d4 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
@@ -18,6 +18,11 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
+import org.apache.iotdb.db.exception.query.LogicalOperatorException;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.db.query.expression.ResultColumn;
+import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
+
 public class LastQueryOperator extends QueryOperator {
 
   public LastQueryOperator() {}
@@ -28,4 +33,16 @@ public class LastQueryOperator extends QueryOperator {
     this.filterOperator = queryOperator.getFilterOperator();
     this.specialClauseComponent = queryOperator.getSpecialClauseComponent();
   }
+
+  @Override
+  public void check() throws LogicalOperatorException {
+    super.check();
+
+    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
+      Expression expression = resultColumn.getExpression();
+      if (!(expression instanceof TimeSeriesOperand)) {
+        throw new LogicalOperatorException("Last queries can only be applied on raw time series.");
+      }
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index 2e70cf3..5a5ddfd 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@ -18,7 +18,9 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
+import org.apache.iotdb.db.exception.query.LogicalOperatorException;
 import org.apache.iotdb.db.index.common.IndexType;
+import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.RootOperator;
@@ -33,7 +35,6 @@ public class QueryOperator extends RootOperator {
   protected SpecialClauseComponent specialClauseComponent;
 
   protected Map<String, Object> props;
-
   protected IndexType indexType;
 
   public QueryOperator() {
@@ -108,4 +109,23 @@ public class QueryOperator extends RootOperator {
   public boolean isGroupByLevel() {
     return specialClauseComponent != null && specialClauseComponent.getLevel() != -1;
   }
+
+  public void check() throws LogicalOperatorException {
+    if (isAlignByDevice()) {
+      if (selectComponent.hasTimeSeriesGeneratingFunction()) {
+        throw new LogicalOperatorException(
+            "ALIGN BY DEVICE clause is not supported in UDF queries.");
+      }
+
+      for (PartialPath path : selectComponent.getPaths()) {
+        String device = path.getDevice();
+        if (!device.isEmpty()) {
+          throw new LogicalOperatorException(
+              "The paths of the SELECT clause can only be single level. In other words, "
+                  + "the paths of the SELECT clause can only be measurements or STAR, without DOT."
+                  + " For more details please refer to the SQL document.");
+        }
+      }
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
index 49a6814..ab3af83 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
@@ -18,4 +18,14 @@
  */
 package org.apache.iotdb.db.qp.logical.crud;
 
-public class UDFQueryOperator extends QueryOperator {}
+public class UDFQueryOperator extends QueryOperator {
+
+  public UDFQueryOperator() {}
+
+  public UDFQueryOperator(QueryOperator queryOperator) {
+    this.selectComponent = queryOperator.getSelectComponent();
+    this.fromComponent = queryOperator.getFromComponent();
+    this.filterOperator = queryOperator.getFilterOperator();
+    this.specialClauseComponent = queryOperator.getSpecialClauseComponent();
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/AggregationPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/AggregationPlan.java
index ee98f49..bccd004 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/AggregationPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/AggregationPlan.java
@@ -104,14 +104,6 @@ public class AggregationPlan extends RawDataQueryPlan {
   }
 
   @Override
-  public void setAlignByTime(boolean align) throws QueryProcessException {
-    if (!align) {
-      throw new QueryProcessException(
-          getOperatorType().name() + " doesn't support disable align clause.");
-    }
-  }
-
-  @Override
   public String getColumnForReaderFromPath(PartialPath path, int pathIndex) {
     return resultColumns.get(pathIndex).getResultColumnName();
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/FillQueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/FillQueryPlan.java
index c40274a..300cc85 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/FillQueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/FillQueryPlan.java
@@ -18,7 +18,6 @@
  */
 package org.apache.iotdb.db.qp.physical.crud;
 
-import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.query.executor.fill.IFill;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -52,14 +51,6 @@ public class FillQueryPlan extends RawDataQueryPlan {
   }
 
   @Override
-  public void setAlignByTime(boolean align) throws QueryProcessException {
-    if (!align) {
-      throw new QueryProcessException(
-          getOperatorType().name() + " doesn't support disable align clause.");
-    }
-  }
-
-  @Override
   public boolean isRawQuery() {
     return false;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
index c530daf..6c906bf 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
@@ -22,8 +22,6 @@ import org.apache.iotdb.db.qp.logical.Operator;
 
 public class GroupByTimePlan extends AggregationPlan {
 
-  public static final String LACK_FUNC_ERROR_MESSAGE =
-      "Lack aggregation function in group by query";
   // [startTime, endTime)
   private long startTime;
   private long endTime;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
index c28d9c6..b9456cc 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
@@ -20,7 +20,6 @@ package org.apache.iotdb.db.qp.physical.crud;
 
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -109,7 +108,7 @@ public abstract class QueryPlan extends PhysicalPlan {
     return alignByTime;
   }
 
-  public void setAlignByTime(boolean align) throws QueryProcessException {
+  public void setAlignByTime(boolean align) {
     alignByTime = align;
   }
 
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 0212a0f..74ecb18 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
@@ -45,6 +45,7 @@ import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
 import org.apache.iotdb.db.qp.logical.crud.SpecialClauseComponent;
+import org.apache.iotdb.db.qp.logical.crud.UDFQueryOperator;
 import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator;
 import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator.AlterType;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
@@ -1029,13 +1030,29 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
       queryOp = new LastQueryOperator(queryOp);
     }
 
+    boolean isFirstElement = true;
     for (ResultColumnContext resultColumnContext : ctx.resultColumn()) {
       selectComponent.addResultColumn(parseResultColumn(resultColumnContext));
+      // judge query type according to the first select element
+      if (!hasDecidedQueryType() && isFirstElement) {
+        if (selectComponent.hasAggregationFunction()) {
+          queryOp = new AggregationQueryOperator(queryOp);
+        } else if (selectComponent.hasTimeSeriesGeneratingFunction()) {
+          queryOp = new UDFQueryOperator(queryOp);
+        }
+        isFirstElement = false;
+      }
     }
 
     queryOp.setSelectComponent(selectComponent);
   }
 
+  private boolean hasDecidedQueryType() {
+    return queryOp instanceof GroupByQueryOperator
+        || queryOp instanceof FillQueryOperator
+        || queryOp instanceof LastQueryOperator;
+  }
+
   @Override
   public Operator visitTopClause(TopClauseContext ctx) {
     Map<String, Object> props = new HashMap<>();
@@ -1333,19 +1350,12 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
   }
 
   public void parseGroupByLevelClause(GroupByLevelClauseContext ctx) {
-    /*    if (!queryOp.hasAggregationFunction()) {
-      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }*/
     GroupByLevelClauseComponent groupByLevelClauseComponent = new GroupByLevelClauseComponent();
     groupByLevelClauseComponent.setLevel(Integer.parseInt(ctx.INT().getText()));
     queryOp.setSpecialClauseComponent(groupByLevelClauseComponent);
   }
 
   public void parseFillClause(FillClauseContext ctx) {
-    /*    FilterOperator filterOperator = queryOp.getFilterOperator();
-    if (!filterOperator.isLeaf() || filterOperator.getTokenIntType() != SQLConstant.EQUAL) {
-      throw new SQLParserException("Only \"=\" can be used in fill function");
-    }*/
     FillClauseComponent fillClauseComponent = new FillClauseComponent();
     List<TypeClauseContext> list = ctx.typeClause();
     Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class);
@@ -1449,9 +1459,6 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
   }
 
   private void parseGroupByTimeClause(GroupByTimeClauseContext ctx) {
-    /*    if (!queryOp.hasAggregationFunction()) {
-      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }*/
     GroupByClauseComponent groupByClauseComponent = new GroupByClauseComponent();
     groupByClauseComponent.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
     // parse timeUnit
@@ -1479,9 +1486,6 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
   }
 
   private void parseGroupByFillClause(GroupByFillClauseContext ctx) {
-    /*    if (!queryOp.hasAggregationFunction()) {
-      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
-    }*/
     GroupByFillClauseComponent groupByFillClauseComponent = new GroupByFillClauseComponent();
     groupByFillClauseComponent.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
index b5b0d2a..9354bd2 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalChecker.java
@@ -20,90 +20,17 @@
 package org.apache.iotdb.db.qp.strategy;
 
 import org.apache.iotdb.db.exception.query.LogicalOperatorException;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
-import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
-import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
 
 public class LogicalChecker {
 
-  /**
-   * TODO: make check() an abstract method and call check() in this method or outside the
-   * LogicalChecker.
-   */
+  private LogicalChecker() {}
+
+  /** To check whether illegal component exists in specific operator */
   public static void check(Operator operator) throws LogicalOperatorException {
     if (operator instanceof QueryOperator) {
-      checkQueryOperator((QueryOperator) operator);
+      ((QueryOperator) operator).check();
     }
   }
-
-  private static void checkQueryOperator(QueryOperator queryOperator)
-      throws LogicalOperatorException {
-    checkSelectOperator(queryOperator);
-  }
-
-  private static void checkSelectOperator(QueryOperator queryOperator)
-      throws LogicalOperatorException {
-    checkLast(queryOperator);
-    checkAggregation(queryOperator);
-    checkAlignByDevice(queryOperator);
-  }
-
-  private static void checkLast(QueryOperator queryOperator) throws LogicalOperatorException {
-    SelectComponent selectComponent = queryOperator.getSelectComponent();
-    if (!(queryOperator instanceof LastQueryOperator)) {
-      return;
-    }
-
-    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
-      Expression expression = resultColumn.getExpression();
-      if (!(expression instanceof TimeSeriesOperand)) {
-        throw new LogicalOperatorException("Last queries can only be applied on raw time series.");
-      }
-    }
-  }
-
-  private static void checkAggregation(QueryOperator queryOperator)
-      throws LogicalOperatorException {
-    SelectComponent selectComponent = queryOperator.getSelectComponent();
-    if (!selectComponent.hasAggregationFunction()) {
-      return;
-    }
-
-    for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
-      Expression expression = resultColumn.getExpression();
-      if (expression instanceof TimeSeriesOperand) {
-        throw new LogicalOperatorException(
-            "Common queries and aggregated queries are not allowed to appear at the same time");
-      }
-    }
-  }
-
-  private static void checkAlignByDevice(QueryOperator queryOperator)
-      throws LogicalOperatorException {
-    if (!queryOperator.isAlignByDevice()) {
-      return;
-    }
-
-    SelectComponent selectComponent = queryOperator.getSelectComponent();
-    if (selectComponent.hasTimeSeriesGeneratingFunction()) {
-      throw new LogicalOperatorException("ALIGN BY DEVICE clause is not supported in UDF queries.");
-    }
-
-    for (PartialPath path : selectComponent.getPaths()) {
-      String device = path.getDevice();
-      if (!device.isEmpty()) {
-        throw new LogicalOperatorException(
-            "The paths of the SELECT clause can only be single level. In other words, "
-                + "the paths of the SELECT clause can only be measurements or STAR, without DOT."
-                + " For more details please refer to the SQL document.");
-      }
-    }
-  }
-
-  private LogicalChecker() {}
 }
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
index 624977f..3e99996 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.integration;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.compaction.CompactionStrategy;
-import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
+import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 
@@ -946,7 +946,7 @@ public class IOTDBGroupByIT {
 
       fail("No expected exception thrown");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+      Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
     }
   }
 
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDisableAlignIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDisableAlignIT.java
index f96648d..6883be7 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDisableAlignIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBDisableAlignIT.java
@@ -351,12 +351,11 @@ public class IoTDBDisableAlignIT {
             DriverManager.getConnection(
                 Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
         Statement statement = connection.createStatement()) {
-      boolean hasResultSet =
-          statement.execute(
-              "select * from root.vehicle where time = 3 Fill(int32[previous, 5ms]) disable align");
+      statement.execute(
+          "select * from root.vehicle where time = 3 Fill(int32[previous, 5ms]) disable align");
       fail("No exception thrown.");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains("FILL doesn't support disable align clause."));
+      Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
     }
   }
 
@@ -367,13 +366,10 @@ public class IoTDBDisableAlignIT {
             DriverManager.getConnection(
                 Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
         Statement statement = connection.createStatement()) {
-      boolean hasResultSet =
-          statement.execute(
-              "select count(*) from root.vehicle GROUP BY ([2,50),20ms) disable align");
+      statement.execute("select count(*) from root.vehicle GROUP BY ([2,50),20ms) disable align");
       fail("No exception thrown.");
     } catch (Exception e) {
-      Assert.assertTrue(
-          e.getMessage().contains("GROUPBYTIME doesn't support disable align clause."));
+      Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
     }
   }
 
@@ -384,11 +380,10 @@ public class IoTDBDisableAlignIT {
             DriverManager.getConnection(
                 Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
         Statement statement = connection.createStatement()) {
-      boolean hasResultSet = statement.execute("select count(*) from root disable align");
+      statement.execute("select count(*) from root disable align");
       fail("No exception thrown.");
     } catch (Exception e) {
-      Assert.assertTrue(
-          e.getMessage().contains("AGGREGATION doesn't support disable align clause."));
+      Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
     }
   }
 
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
index 0db57f3..aaae8eb 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
@@ -19,7 +19,7 @@
 package org.apache.iotdb.db.integration;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
+import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 import org.apache.iotdb.jdbc.IoTDBSQLException;
@@ -804,7 +804,7 @@ public class IoTDBGroupByFillIT {
 
       fail("No expected exception thrown");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+      Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
     }
   }
 
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java b/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
index 0da4e16..dbedae7 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
@@ -20,7 +20,7 @@ package org.apache.iotdb.db.integration.aggregation;
 
 import org.apache.iotdb.db.constant.TestConstant;
 import org.apache.iotdb.db.qp.Planner;
-import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
+import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 
@@ -339,7 +339,7 @@ public class IoTDBAggregationByLevelIT {
 
       fail("No expected exception thrown");
     } catch (Exception e) {
-      Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+      Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
     }
   }
 

[iotdb] 05/06: add check for last query

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit dbe29eb9348268336171724a02c3bb22134fe51d
Author: Alima777 <wx...@gmail.com>
AuthorDate: Fri May 21 14:16:16 2021 +0800

    add check for last query
---
 .../java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
index 72b73d4..4f8b91a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/LastQueryOperator.java
@@ -38,6 +38,10 @@ public class LastQueryOperator extends QueryOperator {
   public void check() throws LogicalOperatorException {
     super.check();
 
+    if (isAlignByDevice()) {
+      throw new LogicalOperatorException("Last query doesn't support align by device.");
+    }
+
     for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
       Expression expression = resultColumn.getExpression();
       if (!(expression instanceof TimeSeriesOperand)) {

[iotdb] 03/06: Fix conclicts

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 09a6378d0825eb96ce6e6f15d6fce638319c10e7
Merge: ad89e3a e6216ad
Author: Alima777 <wx...@gmail.com>
AuthorDate: Wed May 19 21:16:58 2021 +0800

    Fix conclicts

 .../cluster/query/ClusterPhysicalGenerator.java    |  4 ++--
 server/pom.xml                                     |  6 ------
 .../org/apache/iotdb/db/metadata/MManager.java     |  3 ---
 .../org/apache/iotdb/db/metadata/PartialPath.java  | 14 --------------
 .../iotdb/db/qp/physical/crud/AggregationPlan.java |  6 +-----
 .../iotdb/db/qp/physical/crud/LastQueryPlan.java   | 22 +++++++++++-----------
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |  8 ++------
 .../apache/iotdb/db/qp/utils/WildcardsRemover.java | 14 --------------
 .../query/expression/unary/TimeSeriesOperand.java  | 10 ++--------
 9 files changed, 18 insertions(+), 69 deletions(-)


[iotdb] 06/06: Fix conclicts

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ef45eb5eceebfff0275591b51cbc69746ec11018
Merge: dbe29eb aca9faa
Author: Alima777 <wx...@gmail.com>
AuthorDate: Tue May 25 21:57:06 2021 +0800

    Fix conclicts

 .github/workflows/sonar-coveralls.yml              |   8 +-
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4   |   2 +-
 .../cluster/query/ClusterConcatPathOptimizer.java  |  37 ---
 .../apache/iotdb/cluster/query/ClusterPlanner.java |   6 -
 .../iotdb/cluster/query/LocalQueryExecutor.java    |  58 +++--
 .../cluster/query/aggregate/ClusterAggregator.java |  10 +-
 cluster/src/test/resources/logback.xml             |   4 -
 cluster/src/test/resources/node1conf/logback.xml   | 282 +++++++++++++++++++++
 cluster/src/test/resources/node2conf/logback.xml   | 282 +++++++++++++++++++++
 cluster/src/test/resources/node3conf/logback.xml   | 282 +++++++++++++++++++++
 docs/UserGuide/Advanced-Features/Triggers.md       |   6 +-
 docs/UserGuide/Cluster/Cluster-Setup-Example.md    |  37 ++-
 docs/UserGuide/Cluster/Cluster-Setup.md            |   2 -
 docs/zh/UserGuide/Advanced-Features/Triggers.md    |   7 +-
 docs/zh/UserGuide/Cluster/Cluster-Setup-Example.md |  37 ++-
 docs/zh/UserGuide/Cluster/Cluster-Setup.md         |   2 -
 .../java/org/apache/iotdb/rabbitmq/Constant.java   |   2 +-
 .../iotdb/rabbitmq/RabbitMQChannelUtils.java       |   1 +
 .../apache/iotdb/rabbitmq/RabbitMQConsumer.java    |   2 +-
 .../apache/iotdb/jdbc/IoTDBPreparedStatement.java  |   2 +-
 .../iotdb/jdbc/IoTDBPreparedStatementTest.java     |  42 ++-
 .../resources/conf/iotdb-engine.properties         |   8 +
 server/src/assembly/resources/conf/iotdb-env.bat   |  12 +-
 .../org/apache/iotdb/db/auth/AuthorityChecker.java |   3 +-
 .../db/auth/authorizer/LocalFileAuthorizer.java    |   3 +-
 .../iotdb/db/auth/user/BasicUserManager.java       |  10 +-
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  22 +-
 .../org/apache/iotdb/db/conf/IoTDBConstant.java    |   2 -
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  30 +--
 .../db/engine/compaction/TsFileManagement.java     |   4 +-
 .../level/LevelCompactionTsFileManagement.java     |   6 +-
 .../iotdb/db/engine/merge/task/MergeFileTask.java  |   8 +-
 .../db/engine/merge/task/MergeMultiChunkTask.java  |  13 +-
 .../db/engine/storagegroup/TsFileProcessor.java    |   4 +-
 .../iotdb/db/metrics/server/ServerArgument.java    |  12 +-
 .../main/java/org/apache/iotdb/db/qp/Planner.java  |   6 +-
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  67 ++---
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  69 ++---
 .../apache/iotdb/db/qp/utils/WildcardsRemover.java |  68 +++--
 .../db/query/dataset/AlignByDeviceDataSet.java     |   3 +
 .../dataset/groupby/LocalGroupByExecutor.java      |   3 +
 .../iotdb/db/query/expression/Expression.java      |  22 +-
 .../iotdb/db/query/expression/ResultColumn.java    |  46 ++++
 .../query/expression/binary/BinaryExpression.java  |   8 +-
 .../query/expression/unary/FunctionExpression.java |  34 ++-
 .../db/query/expression/unary/MinusExpression.java |   2 +-
 .../query/expression/unary/TimeSeriesOperand.java  |   2 +-
 .../apache/iotdb/db/service/MetricsService.java    |   3 +
 .../org/apache/iotdb/db/service/StartupChecks.java |   2 +-
 .../apache/iotdb/db/utils/QueryDataSetUtils.java   |   2 +
 .../auth/authorizer/LocalFileAuthorizerTest.java   |   4 +-
 .../db/auth/user/LocalFileUserManagerTest.java     |   4 +-
 .../iotdb/db/engine/merge/MergeTaskTest.java       |   7 +-
 .../iotdb/db/integration/IoTDBGroupByUnseqIT.java  | 136 ++++++++++
 .../db/integration/IoTDBWithoutAllNullIT.java      |  72 ++++++
 .../iotdb/db/metadata/MManagerBasicTest.java       |   1 +
 .../org/apache/iotdb/db/metadata/MTreeTest.java    |   1 +
 .../iotdb/db/qp/logical/IndexLogicalPlanTest.java  |   6 +
 .../apache/iotdb/session/IoTDBSessionSimpleIT.java |  81 ++++++
 .../java/org/apache/iotdb/session/SessionUT.java   |   2 +-
 site/src/main/.vuepress/config.js                  |   4 +-
 .../test/java/org/apache/iotdb/db/sql/Cases.java   |  78 +++++-
 .../java/org/apache/iotdb/db/sql/ClusterIT.java    |   3 +
 .../java/org/apache/iotdb/db/sql/SingleNodeIT.java |   3 +
 .../apache/iotdb/tsfile/read/common/RowRecord.java |   5 +
 .../tsfile/read/query/dataset/QueryDataSet.java    |   4 +
 .../org/apache/iotdb/tsfile/utils/PublicBAOS.java  |   1 +
 .../zeppelin/iotdb/IoTDBInterpreterTest.java       |  27 +-
 68 files changed, 1704 insertions(+), 320 deletions(-)

diff --cc server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 74ecb18,132fdba..097b877
--- 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
@@@ -1020,9 -1003,10 +1020,8 @@@ public class IoTDBSqlVisitor extends Sq
      return queryOp;
    }
  
 -  @Override
 -  public Operator visitSelectClause(SelectClauseContext ctx) {
 -    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT, zoneId);
 -
 +  public void parseSelectClause(SelectClauseContext ctx) {
 +    SelectComponent selectComponent = new SelectComponent(zoneId);
- 
      if (ctx.topClause() != null) {
        // TODO: parse info of top clause into selectOp
        visitTopClause(ctx.topClause());
@@@ -1360,12 -1305,46 +1359,46 @@@
      List<TypeClauseContext> list = ctx.typeClause();
      Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class);
      for (TypeClauseContext typeClause : list) {
-       parseTypeClause(typeClause, fillTypes);
+       if (typeClause.ALL() != null) {
+         if (typeClause.linearClause() != null) {
+           throw new SQLParserException("fill all doesn't support linear fill");
+         }
+         parseAllTypeClause(typeClause, fillTypes);
+         break;
+       } else {
+         parsePrimitiveTypeClause(typeClause, fillTypes);
+       }
      }
 -    queryOp.setFill(true);
 -    queryOp.setFillTypes(fillTypes);
 +    fillClauseComponent.setFillTypes(fillTypes);
 +    queryOp.setSpecialClauseComponent(fillClauseComponent);
    }
  
+   private void parseAllTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> fillTypes) {
+     IFill fill;
+     long preRange;
+     if (ctx.previousUntilLastClause() != null) {
+       if (ctx.previousUntilLastClause().DURATION() != null) {
+         preRange =
+             DatetimeUtils.convertDurationStrToLong(
+                 ctx.previousUntilLastClause().DURATION().getText());
+       } else {
+         preRange = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
+       }
+       fill = new PreviousFill(preRange, true);
+     } else {
+       if (ctx.previousClause().DURATION() != null) {
+         preRange =
+             DatetimeUtils.convertDurationStrToLong(ctx.previousClause().DURATION().getText());
+       } else {
+         preRange = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
+       }
+       fill = new PreviousFill(preRange);
+     }
+     for (TSDataType tsDataType : TSDataType.values()) {
+       fillTypes.put(tsDataType, fill.copy());
+     }
+   }
+ 
    private void parseLimitClause(LimitClauseContext ctx, Operator operator) {
      int limit;
      try {
@@@ -1505,41 -1468,17 +1538,17 @@@
        }
        // all type use the same fill way
        if (typeClause.ALL() != null) {
-         IFill fill;
-         if (typeClause.previousUntilLastClause() != null) {
-           long preRange;
-           if (typeClause.previousUntilLastClause().DURATION() != null) {
-             preRange =
-                 DatetimeUtils.convertDurationStrToLong(
-                     typeClause.previousUntilLastClause().DURATION().getText());
-           } else {
-             preRange = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
-           }
-           fill = new PreviousFill(preRange, true);
-         } else {
-           long preRange;
-           if (typeClause.previousClause().DURATION() != null) {
-             preRange =
-                 DatetimeUtils.convertDurationStrToLong(
-                     typeClause.previousClause().DURATION().getText());
-           } else {
-             preRange = IoTDBDescriptor.getInstance().getConfig().getDefaultFillInterval();
-           }
-           fill = new PreviousFill(preRange);
-         }
-         for (TSDataType tsDataType : TSDataType.values()) {
-           fillTypes.put(tsDataType, fill.copy());
-         }
+         parseAllTypeClause(typeClause, fillTypes);
          break;
        } else {
-         parseTypeClause(typeClause, fillTypes);
+         parsePrimitiveTypeClause(typeClause, fillTypes);
        }
      }
 -    queryOp.setFill(true);
 -    queryOp.setFillTypes(fillTypes);
 +    groupByFillClauseComponent.setFillTypes(fillTypes);
 +    queryOp.setSpecialClauseComponent(groupByFillClauseComponent);
    }
  
-   private void parseTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> fillTypes) {
+   private void parsePrimitiveTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> fillTypes) {
      TSDataType dataType = parseType(ctx.dataType().getText());
      if (ctx.linearClause() != null && dataType == TSDataType.TEXT) {
        throw new SQLParserException(
diff --cc server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index f8b3eb8,69c6d94..33982d6
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@@ -27,11 -27,10 +27,10 @@@ import org.apache.iotdb.db.qp.constant.
  import org.apache.iotdb.db.qp.logical.Operator;
  import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
  import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
 -import org.apache.iotdb.db.qp.logical.crud.FromOperator;
 +import org.apache.iotdb.db.qp.logical.crud.FromComponent;
  import org.apache.iotdb.db.qp.logical.crud.FunctionOperator;
- import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
  import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
 -import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
 +import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
  import org.apache.iotdb.db.qp.utils.WildcardsRemover;
  import org.apache.iotdb.db.query.expression.ResultColumn;
  import org.apache.iotdb.db.service.IoTDB;
@@@ -81,20 -77,22 +77,22 @@@ public class ConcatPathOptimizer implem
        return false;
      }
  
 -    FromOperator from = queryOperator.getFromOperator();
++    FromComponent from = queryOperator.getFromComponent();
+     if (from == null || from.getPrefixPaths().isEmpty()) {
+       LOGGER.warn(WARNING_NO_PREFIX_PATHS);
+       return false;
+     }
+ 
      return true;
    }
  
    private void concatSelect(QueryOperator queryOperator) throws LogicalOptimizeException {
-     if (queryOperator.isAlignByDevice() && !(queryOperator instanceof LastQueryOperator)) {
-       return;
-     }
- 
 -    List<PartialPath> prefixPaths = queryOperator.getFromOperator().getPrefixPaths();
 +    List<PartialPath> prefixPaths = queryOperator.getFromComponent().getPrefixPaths();
      List<ResultColumn> resultColumns = new ArrayList<>();
 -    for (ResultColumn suffixColumn : queryOperator.getSelectOperator().getResultColumns()) {
 +    for (ResultColumn suffixColumn : queryOperator.getSelectComponent().getResultColumns()) {
        suffixColumn.concat(prefixPaths, resultColumns);
      }
 -    queryOperator.getSelectOperator().setResultColumns(resultColumns);
 +    queryOperator.getSelectComponent().setResultColumns(resultColumns);
    }
  
    private void removeWildcardsInSelectPaths(QueryOperator queryOperator, int fetchSize)
@@@ -104,31 -101,29 +101,29 @@@
        return;
      }
  
-     WildcardsRemover wildcardsRemover = new WildcardsRemover(this, queryOperator, fetchSize);
+     WildcardsRemover wildcardsRemover = new WildcardsRemover(queryOperator, fetchSize);
      List<ResultColumn> resultColumns = new ArrayList<>();
 -    for (ResultColumn resultColumn : queryOperator.getSelectOperator().getResultColumns()) {
 +    for (ResultColumn resultColumn : queryOperator.getSelectComponent().getResultColumns()) {
        resultColumn.removeWildcards(wildcardsRemover, resultColumns);
        if (wildcardsRemover.checkIfPathNumberIsOverLimit(resultColumns)) {
          break;
        }
      }
      wildcardsRemover.checkIfSoffsetIsExceeded(resultColumns);
 -    queryOperator.getSelectOperator().setResultColumns(resultColumns);
 +    queryOperator.getSelectComponent().setResultColumns(resultColumns);
    }
  
-   private void concatFilter(QueryOperator queryOperator) throws LogicalOptimizeException {
+   private void concatFilterAndRemoveWildcards(QueryOperator queryOperator)
+       throws LogicalOptimizeException {
      FilterOperator filter = queryOperator.getFilterOperator();
      if (filter == null) {
        return;
      }
  
      Set<PartialPath> filterPaths = new HashSet<>();
-     if (!queryOperator.isAlignByDevice() || queryOperator instanceof LastQueryOperator) {
-       // GROUP_BY_DEVICE leaves the concatFilter to PhysicalGenerator to optimize filter without
-       // prefix first
-       queryOperator.setFilterOperator(
-           concatFilter(queryOperator.getFromComponent().getPrefixPaths(), filter, filterPaths));
-     }
+     queryOperator.setFilterOperator(
+         concatFilterAndRemoveWildcards(
 -            queryOperator.getFromOperator().getPrefixPaths(), filter, filterPaths));
++            queryOperator.getFromComponent().getPrefixPaths(), filter, filterPaths));
      queryOperator.getFilterOperator().setPathSet(filterPaths);
    }
  
diff --cc server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
index 6e85e8e,eb3e02b..2e261f4
--- a/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/utils/WildcardsRemover.java
@@@ -35,41 -35,42 +36,36 @@@ import java.util.ArrayList
  import java.util.Collections;
  import java.util.List;
  
 -/** Removes wildcards (applying memory control and slimit/soffset control) */
  public class WildcardsRemover {
  
-   private final ConcatPathOptimizer concatPathOptimizer;
- 
    private final int maxDeduplicatedPathNum;
 -  private final int soffset;
 +  private int soffset = 0;
  
-   private int offset = 0;
-   private int limit = Integer.MAX_VALUE;
 -  private int currentOffset;
 -  private int currentLimit;
 -
 -  /** Records the path number that the MManager totally returned. */
 -  private int consumed;
++  private int currentOffset = 0;
++  private int currentLimit = Integer.MAX_VALUE;
 +  private int consumed = 0;
  
-   public WildcardsRemover(
-       ConcatPathOptimizer concatPathOptimizer, QueryOperator queryOperator, int fetchSize) {
-     this.concatPathOptimizer = concatPathOptimizer;
- 
+   public WildcardsRemover(QueryOperator queryOperator, int fetchSize) {
      // 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 =
 -        queryOperator.isLastQuery()
 +        queryOperator instanceof LastQueryOperator
              ? Integer.MAX_VALUE - 1
              : QueryResourceManager.getInstance().getMaxDeduplicatedPathNum(fetchSize);
 -    soffset = queryOperator.getSeriesOffset();
 -    currentOffset = soffset;
 -
 -    final int slimit = queryOperator.getSeriesLimit();
 -    currentLimit =
 -        slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
 +    if (queryOperator.getSpecialClauseComponent() != null) {
 +      soffset = queryOperator.getSpecialClauseComponent().getSeriesOffset();
-       offset = soffset;
++      currentOffset = soffset;
  
 -    consumed = 0;
 +      final int slimit = queryOperator.getSpecialClauseComponent().getSeriesLimit();
-       limit = slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
++      currentLimit =
++          slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
 +    }
    }
  
-   public WildcardsRemover(ConcatPathOptimizer concatPathOptimizer) {
-     this.concatPathOptimizer = concatPathOptimizer;
+   public WildcardsRemover() {
      maxDeduplicatedPathNum = Integer.MAX_VALUE - 1;
 -    soffset = 0;
 -    currentLimit = maxDeduplicatedPathNum + 1;
 -    consumed = 0;
    }
  
    public List<PartialPath> removeWildcardFrom(PartialPath path) throws LogicalOptimizeException {
diff --cc server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
index c8515d2,38593cb..14ec78d
--- a/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/logical/IndexLogicalPlanTest.java
@@@ -108,9 -108,9 +108,12 @@@ public class IndexLogicalPlanTest 
      Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
      Assert.assertEquals(
          "Glu",
 -        queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
 +        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
      Assert.assertEquals(
 -        "root.Ery.*", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
++        "Glu",
++        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
++    Assert.assertEquals(
 +        "root.Ery.*", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
      Assert.assertEquals(IndexType.RTREE_PAA, queryOperator.getIndexType());
      Assert.assertEquals(2, queryOperator.getProps().size());
      Assert.assertEquals(2, (int) queryOperator.getProps().get(TOP_K));
@@@ -132,9 -132,9 +135,12 @@@
      Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
      Assert.assertEquals(
          "Speed",
 -        queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
 +        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
 +    Assert.assertEquals(
++        "Speed",
++        queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
+     Assert.assertEquals(
 -        "root.Wind.AZQ02", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
 +        "root.Wind.AZQ02", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
      Assert.assertEquals(IndexType.ELB_INDEX, queryOperator.getIndexType());
      Assert.assertEquals(2, queryOperator.getProps().size());
      Assert.assertEquals("[1.0, 2.0, 1.0]", queryOperator.getProps().get(THRESHOLD).toString());