You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@iotdb.apache.org by GitBox <gi...@apache.org> on 2020/11/19 07:36:23 UTC

[GitHub] [iotdb] Ring-k commented on a change in pull request #2034: Change listener to visitor in antlr in order to improve prase speed.

Ring-k commented on a change in pull request #2034:
URL: https://github.com/apache/iotdb/pull/2034#discussion_r526557793



##########
File path: server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
##########
@@ -0,0 +1,1739 @@
+/*
+ * 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.sql;
+
+import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH;
+
+import java.io.File;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.runtime.SQLParserException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.constant.DatetimeUtils;
+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.DeleteDataOperator;
+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.InOperator;
+import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
+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.UpdateOperator;
+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;
+import org.apache.iotdb.db.qp.logical.sys.AuthorOperator.AuthorType;
+import org.apache.iotdb.db.qp.logical.sys.ClearCacheOperator;
+import org.apache.iotdb.db.qp.logical.sys.CountOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateSnapshotOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.DataAuthOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeletePartitionOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.FlushOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator.LoadConfigurationOperatorType;
+import org.apache.iotdb.db.qp.logical.sys.LoadDataOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadFilesOperator;
+import org.apache.iotdb.db.qp.logical.sys.MergeOperator;
+import org.apache.iotdb.db.qp.logical.sys.MoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.RemoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowChildPathsOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowDevicesOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowMergeStatusOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
+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.AlterClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AndExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClausesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ClearcacheContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ConstantContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountNodesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateSnapshotContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DateExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeletePartitionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FlushContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FromClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullMergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionCallContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleToUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertColumnSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertValuesSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllRoleOfUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllUserOfRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRolePrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserPrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadConfigurationStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadFilesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameWithoutStarContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PredicateContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrefixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyValueContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RemoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleFromUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RootOrIdContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetColContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowAllTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowChildPathsContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowFlushTaskInfoContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowMergeStatusContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowVersionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowWhereClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SingleStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SoffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SpecialLimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.StringLiteralContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SuffixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TagClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TimeIntervalContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOffContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOnContext;
+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.UpdateStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.WhereClauseContext;
+import org.apache.iotdb.db.query.executor.fill.IFill;
+import org.apache.iotdb.db.query.executor.fill.LinearFill;
+import org.apache.iotdb.db.query.executor.fill.PreviousFill;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.utils.StringContainer;
+
+public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
+  private static final String DELETE_RANGE_ERROR_MSG =
+      "For delete statement, where clause can only contain atomic expressions like : " +
+          "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'";
+  private ZoneId zoneId;
+  QueryOperator queryOp;
+
+  public void setZoneId(ZoneId zoneId) {
+    this.zoneId = zoneId;
+  }
+
+  @Override
+  public Operator visitSingleStatement(SingleStatementContext ctx) {
+    return visit(ctx.statement());
+  }
+
+  @Override
+  public Operator visitCreateTimeseries(CreateTimeseriesContext ctx) {
+    CreateTimeSeriesOperator createTimeSeriesOperator = new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE);
+    createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    if(ctx.alias() != null) {
+      createTimeSeriesOperator.setAlias(ctx.alias().ID().getText());
+    }
+    if(ctx.attributeClauses() != null) {
+      parseAttributeClauses(ctx.attributeClauses(), createTimeSeriesOperator);
+    }
+    return createTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitDeleteTimeseries(DeleteTimeseriesContext ctx) {
+    List<PartialPath> deletePaths = new ArrayList<>();
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      deletePaths.add(parsePrefixPath(prefixPath));
+    }
+    DeleteTimeSeriesOperator deleteTimeSeriesOperator = new DeleteTimeSeriesOperator(
+        SQLConstant.TOK_METADATA_DELETE);
+    deleteTimeSeriesOperator.setDeletePathList(deletePaths);
+    return deleteTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitAlterTimeseries(AlterTimeseriesContext ctx) {
+    AlterTimeSeriesOperator alterTimeSeriesOperator = new AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER);
+    alterTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    parseAlterClause(ctx.alterClause(), alterTimeSeriesOperator);
+    return alterTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitInsertStatement(InsertStatementContext ctx) {
+    InsertOperator insertOp = new InsertOperator(SQLConstant.TOK_INSERT);
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    selectOp.addSelectPath(parsePrefixPath(ctx.prefixPath()));
+    insertOp.setSelectOperator(selectOp);
+    parseInsertColumnSpec(ctx.insertColumnSpec(), insertOp);

Review comment:
       Please name it "insertColumnsSpec". You may need to modify the .g4 file.

##########
File path: server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
##########
@@ -0,0 +1,1739 @@
+/*
+ * 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.sql;
+
+import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH;
+
+import java.io.File;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.runtime.SQLParserException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.constant.DatetimeUtils;
+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.DeleteDataOperator;
+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.InOperator;
+import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
+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.UpdateOperator;
+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;
+import org.apache.iotdb.db.qp.logical.sys.AuthorOperator.AuthorType;
+import org.apache.iotdb.db.qp.logical.sys.ClearCacheOperator;
+import org.apache.iotdb.db.qp.logical.sys.CountOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateSnapshotOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.DataAuthOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeletePartitionOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.FlushOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator.LoadConfigurationOperatorType;
+import org.apache.iotdb.db.qp.logical.sys.LoadDataOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadFilesOperator;
+import org.apache.iotdb.db.qp.logical.sys.MergeOperator;
+import org.apache.iotdb.db.qp.logical.sys.MoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.RemoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowChildPathsOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowDevicesOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowMergeStatusOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
+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.AlterClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AndExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClausesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ClearcacheContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ConstantContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountNodesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateSnapshotContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DateExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeletePartitionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FlushContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FromClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullMergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionCallContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleToUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertColumnSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertValuesSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllRoleOfUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllUserOfRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRolePrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserPrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadConfigurationStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadFilesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameWithoutStarContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PredicateContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrefixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyValueContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RemoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleFromUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RootOrIdContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetColContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowAllTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowChildPathsContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowFlushTaskInfoContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowMergeStatusContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowVersionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowWhereClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SingleStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SoffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SpecialLimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.StringLiteralContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SuffixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TagClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TimeIntervalContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOffContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOnContext;
+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.UpdateStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.WhereClauseContext;
+import org.apache.iotdb.db.query.executor.fill.IFill;
+import org.apache.iotdb.db.query.executor.fill.LinearFill;
+import org.apache.iotdb.db.query.executor.fill.PreviousFill;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.utils.StringContainer;
+
+public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
+  private static final String DELETE_RANGE_ERROR_MSG =
+      "For delete statement, where clause can only contain atomic expressions like : " +
+          "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'";
+  private ZoneId zoneId;
+  QueryOperator queryOp;
+
+  public void setZoneId(ZoneId zoneId) {
+    this.zoneId = zoneId;
+  }
+
+  @Override
+  public Operator visitSingleStatement(SingleStatementContext ctx) {
+    return visit(ctx.statement());
+  }
+
+  @Override
+  public Operator visitCreateTimeseries(CreateTimeseriesContext ctx) {
+    CreateTimeSeriesOperator createTimeSeriesOperator = new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE);
+    createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    if(ctx.alias() != null) {
+      createTimeSeriesOperator.setAlias(ctx.alias().ID().getText());
+    }
+    if(ctx.attributeClauses() != null) {
+      parseAttributeClauses(ctx.attributeClauses(), createTimeSeriesOperator);
+    }
+    return createTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitDeleteTimeseries(DeleteTimeseriesContext ctx) {
+    List<PartialPath> deletePaths = new ArrayList<>();
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      deletePaths.add(parsePrefixPath(prefixPath));
+    }
+    DeleteTimeSeriesOperator deleteTimeSeriesOperator = new DeleteTimeSeriesOperator(
+        SQLConstant.TOK_METADATA_DELETE);
+    deleteTimeSeriesOperator.setDeletePathList(deletePaths);
+    return deleteTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitAlterTimeseries(AlterTimeseriesContext ctx) {
+    AlterTimeSeriesOperator alterTimeSeriesOperator = new AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER);
+    alterTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    parseAlterClause(ctx.alterClause(), alterTimeSeriesOperator);
+    return alterTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitInsertStatement(InsertStatementContext ctx) {
+    InsertOperator insertOp = new InsertOperator(SQLConstant.TOK_INSERT);
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    selectOp.addSelectPath(parsePrefixPath(ctx.prefixPath()));
+    insertOp.setSelectOperator(selectOp);
+    parseInsertColumnSpec(ctx.insertColumnSpec(), insertOp);
+    parseInsertValuesSpec(ctx.insertValuesSpec(), insertOp);
+    return insertOp;
+  }
+
+  @Override
+  public Operator visitUpdateStatement(UpdateStatementContext ctx) {
+    UpdateOperator updateOp = new UpdateOperator(SQLConstant.TOK_UPDATE);
+    FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
+    fromOp.addPrefixTablePath(parsePrefixPath(ctx.prefixPath()));
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_QUERY);
+    for(SetColContext colContext : ctx.setClause().setCol()) {
+      parseSetCol(colContext, selectOp, updateOp);
+    }
+    FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
+    updateOp.setFilterOperator(whereOp.getChildren().get(0));
+    updateOp.setSelectOperator(selectOp);
+    return updateOp;
+  }
+
+  @Override
+  public Operator visitDeleteStatement(DeleteStatementContext ctx) {
+    DeleteDataOperator deleteDataOp = new DeleteDataOperator(SQLConstant.TOK_DELETE);
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      PartialPath path = parsePrefixPath(prefixPath);
+      selectOp.addSelectPath(path);
+    }
+    deleteDataOp.setSelectOperator(selectOp);
+    if(ctx.whereClause() != null) {

Review comment:
       In the following four (may be more) methods:
   visitDeleteStatement(), visitShowTimeseries(), visitSelectStatement(), visitUpdateStatement()
   there are similar logics adding a whereOp to the operator. You could extract a method `addFilter(operator, ctx.whereClause())`, which contains branches implementing what to do with the operator if there is a where clause, according to the type of operator. This will make these visit methods more neat. And if there are more operator which need to add a filter, you could just add some logic in the extracted method.

##########
File path: server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
##########
@@ -0,0 +1,1739 @@
+/*
+ * 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.sql;
+
+import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH;
+
+import java.io.File;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.runtime.SQLParserException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.constant.DatetimeUtils;
+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.DeleteDataOperator;
+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.InOperator;
+import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
+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.UpdateOperator;
+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;
+import org.apache.iotdb.db.qp.logical.sys.AuthorOperator.AuthorType;
+import org.apache.iotdb.db.qp.logical.sys.ClearCacheOperator;
+import org.apache.iotdb.db.qp.logical.sys.CountOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateSnapshotOperator;
+import org.apache.iotdb.db.qp.logical.sys.CreateTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.DataAuthOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeletePartitionOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.DeleteTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.FlushOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadConfigurationOperator.LoadConfigurationOperatorType;
+import org.apache.iotdb.db.qp.logical.sys.LoadDataOperator;
+import org.apache.iotdb.db.qp.logical.sys.LoadFilesOperator;
+import org.apache.iotdb.db.qp.logical.sys.MergeOperator;
+import org.apache.iotdb.db.qp.logical.sys.MoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.RemoveFileOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.SetTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowChildPathsOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowDevicesOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowMergeStatusOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowStorageGroupOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTTLOperator;
+import org.apache.iotdb.db.qp.logical.sys.ShowTimeSeriesOperator;
+import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
+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.AlterClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlterUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AndExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.AttributeClausesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ClearcacheContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ConstantContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountNodesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CountTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateSnapshotContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.CreateUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DateExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeletePartitionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DeleteTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.DropUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FlushContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FromClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullMergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FullPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionAsElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionCallContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.FunctionElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantRoleToUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GrantWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByFillStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByLevelStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.GroupByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertColumnSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.InsertValuesSpecContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LastElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllRoleOfUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListAllUserOfRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListPrivilegesUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListRolePrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ListUserPrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadConfigurationStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadFilesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.LoadStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MergeContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.MoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.NodeNameWithoutStarContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrExpressionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PredicateContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrefixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PrivilegesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.PropertyValueContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RemoveFileContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeRoleFromUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeUserContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RevokeWatermarkEmbeddingContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.RootOrIdContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectElementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SelectStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetColContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SetTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowAllTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowChildPathsContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowDevicesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowFlushTaskInfoContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowMergeStatusContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowStorageGroupContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTTLStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowTimeseriesContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowVersionContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.ShowWhereClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SingleStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SlimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SoffsetClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SpecialLimitStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.StringLiteralContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.SuffixPathContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TagClauseContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TimeIntervalContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOffContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.TracingOnContext;
+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.UpdateStatementContext;
+import org.apache.iotdb.db.qp.sql.SqlBaseParser.WhereClauseContext;
+import org.apache.iotdb.db.query.executor.fill.IFill;
+import org.apache.iotdb.db.query.executor.fill.LinearFill;
+import org.apache.iotdb.db.query.executor.fill.PreviousFill;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.utils.StringContainer;
+
+public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> {
+  private static final String DELETE_RANGE_ERROR_MSG =
+      "For delete statement, where clause can only contain atomic expressions like : " +
+          "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'";
+  private ZoneId zoneId;
+  QueryOperator queryOp;
+
+  public void setZoneId(ZoneId zoneId) {
+    this.zoneId = zoneId;
+  }
+
+  @Override
+  public Operator visitSingleStatement(SingleStatementContext ctx) {
+    return visit(ctx.statement());
+  }
+
+  @Override
+  public Operator visitCreateTimeseries(CreateTimeseriesContext ctx) {
+    CreateTimeSeriesOperator createTimeSeriesOperator = new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE);
+    createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    if(ctx.alias() != null) {
+      createTimeSeriesOperator.setAlias(ctx.alias().ID().getText());
+    }
+    if(ctx.attributeClauses() != null) {
+      parseAttributeClauses(ctx.attributeClauses(), createTimeSeriesOperator);
+    }
+    return createTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitDeleteTimeseries(DeleteTimeseriesContext ctx) {
+    List<PartialPath> deletePaths = new ArrayList<>();
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      deletePaths.add(parsePrefixPath(prefixPath));
+    }
+    DeleteTimeSeriesOperator deleteTimeSeriesOperator = new DeleteTimeSeriesOperator(
+        SQLConstant.TOK_METADATA_DELETE);
+    deleteTimeSeriesOperator.setDeletePathList(deletePaths);
+    return deleteTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitAlterTimeseries(AlterTimeseriesContext ctx) {
+    AlterTimeSeriesOperator alterTimeSeriesOperator = new AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER);
+    alterTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath()));
+    parseAlterClause(ctx.alterClause(), alterTimeSeriesOperator);
+    return alterTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitInsertStatement(InsertStatementContext ctx) {
+    InsertOperator insertOp = new InsertOperator(SQLConstant.TOK_INSERT);
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    selectOp.addSelectPath(parsePrefixPath(ctx.prefixPath()));
+    insertOp.setSelectOperator(selectOp);
+    parseInsertColumnSpec(ctx.insertColumnSpec(), insertOp);
+    parseInsertValuesSpec(ctx.insertValuesSpec(), insertOp);
+    return insertOp;
+  }
+
+  @Override
+  public Operator visitUpdateStatement(UpdateStatementContext ctx) {
+    UpdateOperator updateOp = new UpdateOperator(SQLConstant.TOK_UPDATE);
+    FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
+    fromOp.addPrefixTablePath(parsePrefixPath(ctx.prefixPath()));
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_QUERY);
+    for(SetColContext colContext : ctx.setClause().setCol()) {
+      parseSetCol(colContext, selectOp, updateOp);
+    }
+    FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
+    updateOp.setFilterOperator(whereOp.getChildren().get(0));
+    updateOp.setSelectOperator(selectOp);
+    return updateOp;
+  }
+
+  @Override
+  public Operator visitDeleteStatement(DeleteStatementContext ctx) {
+    DeleteDataOperator deleteDataOp = new DeleteDataOperator(SQLConstant.TOK_DELETE);
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      PartialPath path = parsePrefixPath(prefixPath);
+      selectOp.addSelectPath(path);
+    }
+    deleteDataOp.setSelectOperator(selectOp);
+    if(ctx.whereClause() != null) {
+      FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
+      deleteDataOp.setFilterOperator(whereOp.getChildren().get(0));
+      Pair<Long, Long> timeInterval = parseDeleteTimeInterval(deleteDataOp);
+      deleteDataOp.setStartTime(timeInterval.left);
+      deleteDataOp.setEndTime(timeInterval.right);
+    }
+    return deleteDataOp;
+  }
+
+  @Override
+  public Operator visitSetStorageGroup(SetStorageGroupContext ctx) {
+    SetStorageGroupOperator setStorageGroupOperator = new SetStorageGroupOperator(
+        SQLConstant.TOK_METADATA_SET_FILE_LEVEL);
+    PartialPath path = parsePrefixPath(ctx.prefixPath());
+    setStorageGroupOperator.setPath(path);
+    return setStorageGroupOperator;
+  }
+
+  @Override
+  public Operator visitDeleteStorageGroup(DeleteStorageGroupContext ctx) {
+    List<PartialPath> deletePaths = new ArrayList<>();
+    List<PrefixPathContext> prefixPaths = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPaths) {
+      deletePaths.add(parsePrefixPath(prefixPath));
+    }
+    DeleteStorageGroupOperator deleteStorageGroupOperator = new DeleteStorageGroupOperator(
+        SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL);
+    deleteStorageGroupOperator.setDeletePathList(deletePaths);
+    return deleteStorageGroupOperator;
+  }
+
+  @Override
+  public Operator visitMerge(MergeContext ctx) {
+    return new MergeOperator(SQLConstant.TOK_MERGE);
+  }
+
+  @Override
+  public Operator visitFlush(FlushContext ctx) {
+    FlushOperator flushOperator = new FlushOperator(SQLConstant.TOK_FLUSH);
+    if (ctx.booleanClause() != null) {
+      flushOperator.setSeq(Boolean.parseBoolean(ctx.booleanClause().getText()));
+    }
+    if (ctx.prefixPath(0) != null) {
+      List<PartialPath> storageGroups = new ArrayList<>();
+      for (PrefixPathContext prefixPathContext : ctx.prefixPath()) {
+        storageGroups.add(parsePrefixPath(prefixPathContext));
+      }
+      flushOperator.setStorageGroupList(storageGroups);
+    }
+    return flushOperator;
+  }
+
+  @Override
+  public Operator visitFullMerge(FullMergeContext ctx) {
+    return new MergeOperator(SQLConstant.TOK_FULL_MERGE);
+  }
+
+  @Override
+  public Operator visitClearcache(ClearcacheContext ctx) {
+    return new ClearCacheOperator(SQLConstant.TOK_CLEAR_CACHE);
+  }
+
+  @Override
+  public Operator visitCreateUser(CreateUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE,
+        AuthorOperator.AuthorType.CREATE_USER);
+    authorOperator.setUserName(ctx.ID().getText());
+    authorOperator.setPassWord(removeStringQuote(ctx.password.getText()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitAlterUser(AlterUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_UPDATE_USER,
+        AuthorOperator.AuthorType.UPDATE_USER);
+    if (ctx.ID() != null) {
+      authorOperator.setUserName(ctx.ID().getText());
+    } else {
+      authorOperator.setUserName(ctx.ROOT().getText());
+    }
+    authorOperator.setNewPassword(removeStringQuote(ctx.password.getText()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitDropUser(DropUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP,
+        AuthorOperator.AuthorType.DROP_USER);
+    authorOperator.setUserName(ctx.ID().getText());
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitCreateRole(CreateRoleContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE,
+        AuthorOperator.AuthorType.CREATE_ROLE);
+    authorOperator.setRoleName(ctx.ID().getText());
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitDropRole(DropRoleContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP,
+        AuthorOperator.AuthorType.DROP_ROLE);
+    authorOperator.setRoleName(ctx.ID().getText());
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitGrantUser(GrantUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorOperator.AuthorType.GRANT_USER);
+    authorOperator.setUserName(ctx.ID().getText());
+    authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+    authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitGrantRole(GrantRoleContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorType.GRANT_ROLE);
+    authorOperator.setRoleName(ctx.ID().getText());
+    authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+    authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitRevokeUser(RevokeUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorType.REVOKE_USER);
+    authorOperator.setUserName(ctx.ID().getText());
+    authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+    authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitRevokeRole(RevokeRoleContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorType.REVOKE_ROLE);
+    authorOperator.setRoleName(ctx.ID().getText());
+    authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+    authorOperator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitGrantRoleToUser(GrantRoleToUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorOperator.AuthorType.GRANT_ROLE_TO_USER);
+    authorOperator.setRoleName(ctx.roleName.getText());
+    authorOperator.setUserName(ctx.userName.getText());
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitRevokeRoleFromUser(RevokeRoleFromUserContext ctx) {
+    AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT,
+        AuthorType.REVOKE_ROLE_FROM_USER);
+    authorOperator.setRoleName(ctx.roleName.getText());
+    authorOperator.setUserName(ctx.userName.getText());
+    return authorOperator;
+  }
+
+  @Override
+  public Operator visitLoadStatement(LoadStatementContext ctx) {
+    if (ctx.prefixPath().nodeName().size() < 3) {
+      throw new SQLParserException("data load command: child count < 3\n");
+    }
+
+    String csvPath = ctx.stringLiteral().getText();
+    StringContainer sc = new StringContainer(TsFileConstant.PATH_SEPARATOR);
+    List<NodeNameContext> nodeNames = ctx.prefixPath().nodeName();
+    sc.addTail(ctx.prefixPath().ROOT().getText());
+    for (NodeNameContext nodeName : nodeNames) {
+      sc.addTail(nodeName.getText());
+    }
+    return new LoadDataOperator(SQLConstant.TOK_DATALOAD,
+        removeStringQuote(csvPath),
+        sc.toString());
+  }
+
+  @Override
+  public Operator visitGrantWatermarkEmbedding(GrantWatermarkEmbeddingContext ctx) {
+    List<RootOrIdContext> rootOrIdList = ctx.rootOrId();
+    List<String> users = new ArrayList<>();
+    for (RootOrIdContext rootOrId : rootOrIdList) {
+      users.add(rootOrId.getText());
+    }
+    return new DataAuthOperator(SQLConstant.TOK_GRANT_WATERMARK_EMBEDDING, users);
+  }
+
+  @Override
+  public Operator visitRevokeWatermarkEmbedding(RevokeWatermarkEmbeddingContext ctx) {
+    List<RootOrIdContext> rootOrIdList = ctx.rootOrId();
+    List<String> users = new ArrayList<>();
+    for (RootOrIdContext rootOrId : rootOrIdList) {
+      users.add(rootOrId.getText());
+    }
+    return new DataAuthOperator(SQLConstant.TOK_REVOKE_WATERMARK_EMBEDDING, users);
+  }
+
+  @Override
+  public Operator visitListUser(ListUserContext ctx) {
+    return new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_USER);
+  }
+
+  @Override
+  public Operator visitListRole(ListRoleContext ctx) {
+    return new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_ROLE);
+  }
+
+  @Override
+  public Operator visitListPrivilegesUser(ListPrivilegesUserContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
+    operator.setUserName(ctx.rootOrId().getText());
+    operator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return operator;
+  }
+
+  @Override
+  public Operator visitListPrivilegesRole(ListPrivilegesRoleContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
+    operator.setRoleName((ctx.ID().getText()));
+    operator.setNodeNameList(parsePrefixPath(ctx.prefixPath()));
+    return operator;
+  }
+
+  @Override
+  public Operator visitListUserPrivileges(ListUserPrivilegesContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_USER_PRIVILEGE);
+    operator.setUserName(ctx.rootOrId().getText());
+    return operator;
+  }
+
+  @Override
+  public Operator visitListRolePrivileges(ListRolePrivilegesContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE);
+    operator.setRoleName(ctx.ID().getText());
+    return operator;
+  }
+
+  @Override
+  public Operator visitListAllRoleOfUser(ListAllRoleOfUserContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_USER_ROLES);
+    operator.setUserName(ctx.rootOrId().getText());
+    return operator;
+  }
+
+  @Override
+  public Operator visitListAllUserOfRole(ListAllUserOfRoleContext ctx) {
+    AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST,
+        AuthorOperator.AuthorType.LIST_ROLE_USERS);
+    operator.setRoleName((ctx.ID().getText()));
+    return operator;
+  }
+
+  @Override
+  public Operator visitSetTTLStatement(SetTTLStatementContext ctx) {
+    SetTTLOperator operator = new SetTTLOperator(SQLConstant.TOK_SET);
+    operator.setStorageGroup(parsePrefixPath(ctx.prefixPath()));
+    operator.setDataTTL(Long.parseLong(ctx.INT().getText()));
+    return operator;
+  }
+
+  @Override
+  public Operator visitUnsetTTLStatement(UnsetTTLStatementContext ctx) {
+    SetTTLOperator operator = new SetTTLOperator(SQLConstant.TOK_UNSET);
+    operator.setStorageGroup(parsePrefixPath(ctx.prefixPath()));
+    return operator;
+  }
+
+  @Override
+  public Operator visitShowTTLStatement(ShowTTLStatementContext ctx) {
+    List<PartialPath> storageGroups = new ArrayList<>();
+    List<PrefixPathContext> prefixPathList = ctx.prefixPath();
+    for (PrefixPathContext prefixPath : prefixPathList) {
+      storageGroups.add(parsePrefixPath(prefixPath));
+    }
+    return new ShowTTLOperator(storageGroups);
+  }
+
+  @Override
+  public Operator visitShowAllTTLStatement(ShowAllTTLStatementContext ctx) {
+    List<PartialPath> storageGroups = new ArrayList<>();
+    return new ShowTTLOperator(storageGroups);
+  }
+
+  @Override
+  public Operator visitShowFlushTaskInfo(ShowFlushTaskInfoContext ctx) {
+    return new ShowOperator(SQLConstant.TOK_FLUSH_TASK_INFO);
+  }
+
+  @Override
+  public Operator visitShowVersion(ShowVersionContext ctx) {
+    return new ShowOperator(SQLConstant.TOK_VERSION);
+  }
+
+  @Override
+  public Operator visitShowTimeseries(ShowTimeseriesContext ctx) {
+    boolean orderByHeat = ctx.LATEST() != null;
+    ShowTimeSeriesOperator showTimeSeriesOperator;
+    if (ctx.prefixPath() != null) {
+      showTimeSeriesOperator = new ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES,
+          parsePrefixPath(ctx.prefixPath()), orderByHeat);
+    } else {
+      showTimeSeriesOperator = new ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES, new PartialPath(SQLConstant.getSingleRootArray()),
+          orderByHeat);
+    }
+    if(ctx.showWhereClause() != null) {
+      parseShowWhereClause(ctx.showWhereClause(), showTimeSeriesOperator);
+    }
+    if(ctx.limitClause() != null) {
+      parseLimitClause(ctx.limitClause(), showTimeSeriesOperator);
+    }
+    return showTimeSeriesOperator;
+  }
+
+  @Override
+  public Operator visitShowStorageGroup(ShowStorageGroupContext ctx) {
+    if (ctx.prefixPath() != null) {
+      return new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP,
+          parsePrefixPath(ctx.prefixPath()));
+    } else {
+      return new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP,
+          new PartialPath(SQLConstant.getSingleRootArray()));
+    }
+  }
+
+  @Override
+  public Operator visitShowChildPaths(ShowChildPathsContext ctx) {
+    if (ctx.prefixPath() != null) {
+      return new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS,
+          parsePrefixPath(ctx.prefixPath()));
+    } else {
+      return new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS,
+          new PartialPath(SQLConstant.getSingleRootArray()));
+    }
+  }
+
+  @Override
+  public Operator visitShowDevices(ShowDevicesContext ctx) {
+    if (ctx.prefixPath() != null) {
+      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
+          parsePrefixPath(ctx.prefixPath()));
+    } else {
+      return new ShowDevicesOperator(SQLConstant.TOK_DEVICES,
+          new PartialPath(SQLConstant.getSingleRootArray()));
+    }
+  }
+
+  @Override
+  public Operator visitShowMergeStatus(ShowMergeStatusContext ctx) {
+    return new ShowMergeStatusOperator(SQLConstant.TOK_SHOW_MERGE_STATUS);
+  }
+
+  @Override
+  public Operator visitTracingOn(TracingOnContext ctx) {
+    return new TracingOperator(SQLConstant.TOK_TRACING, true);
+  }
+
+  @Override
+  public Operator visitTracingOff(TracingOffContext ctx) {
+    return new TracingOperator(SQLConstant.TOK_TRACING, false);
+  }
+
+  @Override
+  public Operator visitCountTimeseries(CountTimeseriesContext ctx) {
+    PrefixPathContext pathContext = ctx.prefixPath();
+    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray()));
+    if (ctx.INT() != null) {
+      return new CountOperator(SQLConstant.TOK_COUNT_NODE_TIMESERIES,
+          path, Integer.parseInt(ctx.INT().getText()));
+    } else {
+      return new CountOperator(SQLConstant.TOK_COUNT_TIMESERIES,
+          path);
+    }
+  }
+
+  @Override
+  public Operator visitCountDevices(CountDevicesContext ctx) {
+    PrefixPathContext pathContext = ctx.prefixPath();
+    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray()));
+    return new CountOperator(SQLConstant.TOK_COUNT_DEVICES, path);
+  }
+
+  @Override
+  public Operator visitCountStorageGroup(CountStorageGroupContext ctx) {
+    PrefixPathContext pathContext = ctx.prefixPath();
+    PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray()));
+    return new CountOperator(SQLConstant.TOK_COUNT_STORAGE_GROUP, path);
+  }
+
+  @Override
+  public Operator visitCountNodes(CountNodesContext ctx) {
+    return new CountOperator(SQLConstant.TOK_COUNT_NODES,
+        parsePrefixPath(ctx.prefixPath()), Integer.parseInt(ctx.INT().getText()));
+  }
+
+  @Override
+  public Operator visitLoadConfigurationStatement(LoadConfigurationStatementContext ctx) {
+    if (ctx.GLOBAL() != null) {
+      return new LoadConfigurationOperator(LoadConfigurationOperatorType.GLOBAL);
+    } else {
+      return new LoadConfigurationOperator(LoadConfigurationOperatorType.LOCAL);
+    }
+  }
+
+  @Override
+  public Operator visitLoadFiles(LoadFilesContext ctx) {
+    if (ctx.autoCreateSchema() != null) {
+      if (ctx.autoCreateSchema().INT() != null) {
+        return new LoadFilesOperator(
+            new File(removeStringQuote(ctx.stringLiteral().getText())),
+            Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
+            Integer.parseInt(ctx.autoCreateSchema().INT().getText())
+        );
+      } else {
+        return new LoadFilesOperator(
+            new File(removeStringQuote(ctx.stringLiteral().getText())),
+            Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
+            IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
+        );
+      }
+    } else {
+      return new LoadFilesOperator(
+          new File(removeStringQuote(ctx.stringLiteral().getText())),
+          true,
+          IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
+      );
+    }
+  }
+
+  @Override
+  public Operator visitRemoveFile(RemoveFileContext ctx) {
+    return new RemoveFileOperator(new File(removeStringQuote(ctx.stringLiteral().getText())));
+  }
+
+  @Override
+  public Operator visitMoveFile(MoveFileContext ctx) {
+    return new MoveFileOperator(
+        new File(removeStringQuote(ctx.stringLiteral(0).getText())),
+        new File(removeStringQuote(ctx.stringLiteral(1).getText())));
+  }
+
+  @Override
+  public Operator visitDeletePartition(DeletePartitionContext ctx) {
+    DeletePartitionOperator deletePartitionOperator = new DeletePartitionOperator(
+        SQLConstant.TOK_DELETE_PARTITION);
+    deletePartitionOperator.setStorageGroupName(parsePrefixPath(ctx.prefixPath()));
+    Set<Long> idSet = new HashSet<>();
+    for (TerminalNode terminalNode : ctx.INT()) {
+      idSet.add(Long.parseLong(terminalNode.getText()));
+    }
+    deletePartitionOperator.setPartitionIds(idSet);
+    return deletePartitionOperator;
+  }
+
+  @Override
+  public Operator visitCreateSnapshot(CreateSnapshotContext ctx) {
+    return new CreateSnapshotOperator(SQLConstant.TOK_CREATE_SCHEMA_SNAPSHOT);
+  }
+
+  @Override
+  public Operator visitSelectStatement(SelectStatementContext ctx) {
+    queryOp  = new QueryOperator(SQLConstant.TOK_QUERY);
+    SelectOperator selectOp = (SelectOperator) visit(ctx.selectElements());
+    queryOp.setSelectOperator(selectOp);
+    FromOperator fromOp = (FromOperator) visit(ctx.fromClause());
+    queryOp.setFromOperator(fromOp);
+    if(ctx.whereClause() != null) {
+      FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause());
+      queryOp.setFilterOperator(whereOp.getChildren().get(0));
+    }
+    if(ctx.specialClause() != null) {
+      visit(ctx.specialClause());
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitFunctionElement(FunctionElementContext ctx) {
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    List<FunctionCallContext> functionCallContextList = ctx.functionCall();
+    for (FunctionCallContext functionCallContext : functionCallContextList) {
+      PartialPath path = parseSuffixPath(functionCallContext.suffixPath());
+      selectOp.addClusterPath(path, functionCallContext.functionName().getText());
+    }
+    return selectOp;
+  }
+
+  @Override
+  public Operator visitLastElement(LastElementContext ctx) {
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    selectOp.setLastQuery();
+    LastClauseContext lastClauseContext = ctx.lastClause();
+    if (lastClauseContext.asClause().size() != 0) {
+      parseAsClause(lastClauseContext.asClause(), selectOp);
+    } else {
+      List<SuffixPathContext> suffixPaths = lastClauseContext.suffixPath();
+      for (SuffixPathContext suffixPath : suffixPaths) {
+        PartialPath path = parseSuffixPath(suffixPath);
+        selectOp.addSelectPath(path);
+      }
+    }
+    return selectOp;
+  }
+
+  @Override
+  public Operator visitAsElement(AsElementContext ctx) {
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    parseAsClause(ctx.asClause(), selectOp);
+    return selectOp;
+  }
+
+  @Override
+  public Operator visitFunctionAsElement(FunctionAsElementContext ctx) {
+    SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT);
+    List<FunctionAsClauseContext> functionAsClauseContexts = ctx.functionAsClause();
+    for (FunctionAsClauseContext functionAsClauseContext : functionAsClauseContexts) {
+      FunctionCallContext functionCallContext = functionAsClauseContext.functionCall();
+      PartialPath path = parseSuffixPath(functionCallContext.suffixPath());
+      if (functionAsClauseContext.ID() != null) {
+        path.setTsAlias(functionAsClauseContext.ID().toString());
+      }
+      selectOp.addClusterPath(path, functionCallContext.functionName().getText());
+    }
+    return selectOp;
+  }
+
+  public void parseAsClause(List<AsClauseContext> asClauseContexts, SelectOperator selectOp) {
+    for (AsClauseContext asClauseContext : asClauseContexts) {
+      PartialPath path = parseSuffixPath(asClauseContext.suffixPath());
+      if (asClauseContext.ID() != null) {
+        path.setTsAlias(asClauseContext.ID().toString());
+      }
+      selectOp.addSelectPath(path);
+    }
+  }
+
+  @Override
+  public Operator visitSpecialLimitStatement(SpecialLimitStatementContext ctx) {
+    return visit(ctx.specialLimit());
+  }
+
+  @Override
+  public Operator visitLimitStatement(LimitStatementContext ctx) {
+    parseLimitClause(ctx.limitClause(), queryOp);
+    if(ctx.slimitClause() != null) {
+      parseSlimitClause(ctx.slimitClause(), queryOp);
+    }
+    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) {
+        parseAlignByDeviceClause(queryOp);
+      } else {
+        parseDisableAlign(queryOp);
+      }
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitSlimitStatement(SlimitStatementContext ctx) {
+    parseSlimitClause(ctx.slimitClause(), queryOp);
+    if(ctx.limitClause() != null) {
+      parseLimitClause(ctx.limitClause(), queryOp);
+    }
+    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) {
+        parseAlignByDeviceClause(queryOp);
+      } else {
+        parseDisableAlign(queryOp);
+      }
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitAlignByDeviceClauseOrDisableAlignInSpecialLimit(
+      AlignByDeviceClauseOrDisableAlignInSpecialLimitContext ctx) {
+    if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) {
+      parseAlignByDeviceClause(queryOp);
+    } else {
+      parseDisableAlign(queryOp);
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitOrderByTimeStatement(OrderByTimeStatementContext ctx) {
+    parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+    if(ctx.specialLimit() != null) {
+      return visit(ctx.specialLimit());
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitGroupByTimeStatement(GroupByTimeStatementContext ctx) {
+    parseGroupByTimeClause(ctx.groupByTimeClause(), queryOp);
+    if(ctx.orderByTimeClause() != null) {
+      parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+    }
+    if(ctx.specialLimit() != null) {
+      return visit(ctx.specialLimit());
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitGroupByFillStatement(GroupByFillStatementContext ctx) {
+    parseGroupByFillClause(ctx.groupByFillClause(), queryOp);
+    if(ctx.orderByTimeClause() != null) {
+      parseOrderByTimeClause(ctx.orderByTimeClause(), queryOp);
+    }
+    if(ctx.specialLimit() != null) {
+      return visit(ctx.specialLimit());
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitFillStatement(FillStatementContext ctx) {
+    parseFillClause(ctx.fillClause(), queryOp);
+    if(ctx.slimitClause() != null) {
+      queryOp = (QueryOperator) visit(ctx.slimitClause());
+    }
+    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {
+      if(ctx.alignByDeviceClauseOrDisableAlign().alignByDeviceClause() != null) {
+        parseAlignByDeviceClause(queryOp);
+      } else {
+        parseDisableAlign(queryOp);
+      }
+    }
+    return queryOp;
+  }
+
+  @Override
+  public Operator visitAlignByDeviceStatementOrDisableAlignInSpecialClause(
+      AlignByDeviceStatementOrDisableAlignInSpecialClauseContext ctx) {
+    if(ctx.alignByDeviceClauseOrDisableAlign() != null) {

Review comment:
       Why is this necessary?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org