This is an automated email from the ASF dual-hosted git repository. geniuspig pushed a commit to branch change_listener_to_visitor_0.11 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit e7f93c46831be80aeabdf1b6a11addf23b2b3244 Author: Boris <[email protected]> AuthorDate: Wed Nov 11 17:55:20 2020 +0800 change listener to visitor --- antlr/pom.xml | 4 + .../iotdb/db/qp/{strategy => sql}/SqlBase.g4 | 0 .../apache/iotdb/db/qp/constant/SQLConstant.java | 2 +- .../IoTDBSqlVisitor.java} | 1926 ++++++++------------ .../apache/iotdb/db/qp/strategy/ParseDriver.java | 19 +- ...gicalGeneratorError.java => SQLParseError.java} | 4 +- .../sql/DatetimeQueryDataSetUtilsTest.java | 2 +- .../iotdb/db/qp/strategy/LogicalGeneratorTest.java | 26 +- 8 files changed, 826 insertions(+), 1157 deletions(-) diff --git a/antlr/pom.xml b/antlr/pom.xml index 6c2beeb..8293218 100644 --- a/antlr/pom.xml +++ b/antlr/pom.xml @@ -44,6 +44,10 @@ <version>${antlr4.version}</version> <executions> <execution> + <configuration> + <listener>false</listener> + <visitor>true</visitor> + </configuration> <goals> <goal>antlr4</goal> </goals> diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4 similarity index 100% rename from antlr/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4 rename to antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlBase.g4 diff --git a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java index 8976733..04b9520 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java @@ -21,7 +21,7 @@ package org.apache.iotdb.db.qp.constant; import java.util.HashMap; import java.util.Map; import org.apache.iotdb.db.metadata.PartialPath; -import org.apache.iotdb.db.qp.strategy.SqlBaseLexer; +import org.apache.iotdb.db.qp.sql.SqlBaseLexer; /** * this class contains several constants used in SQL. 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/sql/IoTDBSqlVisitor.java similarity index 56% rename from server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java rename to server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java index 2826b3b..f315e50 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java @@ -1,22 +1,4 @@ -/* - * 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.strategy; +package org.apache.iotdb.db.qp.sql; import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH; @@ -36,7 +18,7 @@ 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.RootOperator; +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; @@ -76,105 +58,97 @@ 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.strategy.SqlBaseParser.AliasContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AlignByDeviceClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AlterUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AndExpressionContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AsClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AsElementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AttributeClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.AttributeClausesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ConstantContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountDevicesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountNodesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountStorageGroupContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CountTimeseriesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateSnapshotContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateTimeseriesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.CreateUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DateExpressionContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DeletePartitionContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DeleteStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DeleteStorageGroupContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DeleteTimeseriesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DropRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.DropUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FillClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FlushContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FromClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FullMergeContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FullPathContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FunctionAsClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FunctionAsElementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FunctionCallContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.FunctionElementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.GrantRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.GrantRoleToUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.GrantUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.GrantWatermarkEmbeddingContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.GroupByTimeClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.InClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.InsertColumnSpecContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.InsertStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.InsertValuesSpecContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.LastClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.LimitClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListAllRoleOfUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListAllUserOfRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListPrivilegesRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListPrivilegesUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListRolePrivilegesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ListUserPrivilegesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.LoadConfigurationStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.LoadFilesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.LoadStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.MergeContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.MoveFileContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.NodeNameContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.NodeNameWithoutStarContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.OffsetClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.OrExpressionContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.OrderByTimeClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.PredicateContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.PrefixPathContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.PrivilegesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.PropertyContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.PropertyValueContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RemoveFileContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RevokeRoleContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RevokeRoleFromUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RevokeUserContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RevokeWatermarkEmbeddingContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.RootOrIdContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SelectElementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SelectStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SetColContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SetStorageGroupContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SetTTLStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowAllTTLStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowChildPathsContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowDevicesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowMergeStatusContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowStorageGroupContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowTTLStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowTimeseriesContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowVersionContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.ShowWhereClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SlimitClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SoffsetClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.StringLiteralContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.SuffixPathContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.TagClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.TimeIntervalContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.TracingOffContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.TracingOnContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.TypeClauseContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.UnsetTTLStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.UpdateStatementContext; -import org.apache.iotdb.db.qp.strategy.SqlBaseParser.WhereClauseContext; +import org.apache.iotdb.db.qp.sql.SqlBaseParser.AlignByDeviceClauseContext; +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.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.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.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.GroupByTimeClauseContext; +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.LimitClauseContext; +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.OrExpressionContext; +import org.apache.iotdb.db.qp.sql.SqlBaseParser.OrderByTimeClauseContext; +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.SlimitClauseContext; +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.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; @@ -186,327 +160,156 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; import org.apache.iotdb.tsfile.utils.Pair; import org.apache.iotdb.tsfile.utils.StringContainer; -/** - * This class is a listener and you can get an operator which is a logical plan. - */ -public class LogicalGenerator extends SqlBaseBaseListener { - - private RootOperator initializedOperator = null; - private ZoneId zoneId; - private int operatorType; - private CreateTimeSeriesOperator createTimeSeriesOperator; - private AlterTimeSeriesOperator alterTimeSeriesOperator; - private InsertOperator insertOp; - private SelectOperator selectOp; - private UpdateOperator updateOp; - private QueryOperator queryOp; - private DeleteDataOperator deleteDataOp; +public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> { private static final String DELETE_RANGE_ERROR_MSG = - "For delete statement, where clause can only contain atomic expressions like : " + - "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'"; - + "For delete statement, where clause can only contain atomic expressions like : " + + "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'"; + private ZoneId zoneId; - LogicalGenerator(ZoneId zoneId) { + public void setZoneId(ZoneId zoneId) { this.zoneId = zoneId; } - RootOperator getLogicalPlan() { - return initializedOperator; - } - - @Override - public void enterCountTimeseries(CountTimeseriesContext ctx) { - super.enterCountTimeseries(ctx); - PrefixPathContext pathContext = ctx.prefixPath(); - PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray())); - if (ctx.INT() != null) { - initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_NODE_TIMESERIES, - path, Integer.parseInt(ctx.INT().getText())); - } else { - initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_TIMESERIES, - path); - } - } - @Override - public void enterCountDevices(CountDevicesContext ctx) { - super.enterCountDevices(ctx); - PrefixPathContext pathContext = ctx.prefixPath(); - PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray())); - initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_DEVICES, path); - } - - @Override - public void enterCountStorageGroup(CountStorageGroupContext ctx) { - super.enterCountStorageGroup(ctx); - PrefixPathContext pathContext = ctx.prefixPath(); - PartialPath path = (pathContext != null ? parsePrefixPath(pathContext) : new PartialPath(SQLConstant.getSingleRootArray())); - initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_STORAGE_GROUP, path); + public Operator visitCreateTimeseries(CreateTimeseriesContext ctx) { + CreateTimeSeriesOperator createTimeSeriesOperator = new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE); + createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath())); + createTimeSeriesOperator.setAlias(ctx.alias().ID().getText()); + parseAttributeClauses(ctx.attributeClauses(), createTimeSeriesOperator); + return createTimeSeriesOperator; } @Override - public void enterFlush(FlushContext ctx) { - super.enterFlush(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); + public Operator visitDeleteTimeseries(DeleteTimeseriesContext ctx) { + List<PartialPath> deletePaths = new ArrayList<>(); + List<PrefixPathContext> prefixPaths = ctx.prefixPath(); + for (PrefixPathContext prefixPath : prefixPaths) { + deletePaths.add(parsePrefixPath(prefixPath)); } - - initializedOperator = flushOperator; - } - - @Override - public void enterTracingOn(TracingOnContext ctx) { - super.enterTracingOn(ctx); - initializedOperator = new TracingOperator(SQLConstant.TOK_TRACING, true); - } - - @Override - public void enterTracingOff(TracingOffContext ctx) { - super.enterTracingOff(ctx); - initializedOperator = new TracingOperator(SQLConstant.TOK_TRACING, false); - } - - @Override - public void enterMerge(MergeContext ctx) { - super.enterMerge(ctx); - initializedOperator = new MergeOperator(SQLConstant.TOK_MERGE); - } - - @Override - public void enterFullMerge(FullMergeContext ctx) { - super.enterFullMerge(ctx); - initializedOperator = new MergeOperator(SQLConstant.TOK_FULL_MERGE); - } - - @Override - public void enterClearcache(SqlBaseParser.ClearcacheContext ctx) { - super.enterClearcache(ctx); - initializedOperator = new ClearCacheOperator(SQLConstant.TOK_CLEAR_CACHE); + DeleteTimeSeriesOperator deleteTimeSeriesOperator = new DeleteTimeSeriesOperator( + SQLConstant.TOK_METADATA_DELETE); + deleteTimeSeriesOperator.setDeletePathList(deletePaths); + return deleteTimeSeriesOperator; } @Override - public void enterCountNodes(CountNodesContext ctx) { - super.enterCountNodes(ctx); - initializedOperator = new CountOperator(SQLConstant.TOK_COUNT_NODES, - parsePrefixPath(ctx.prefixPath()), Integer.parseInt(ctx.INT().getText())); + 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 void enterShowDevices(ShowDevicesContext ctx) { - super.enterShowDevices(ctx); - if (ctx.prefixPath() != null) { - initializedOperator = new ShowDevicesOperator(SQLConstant.TOK_DEVICES, - parsePrefixPath(ctx.prefixPath())); - } else { - initializedOperator = new ShowDevicesOperator(SQLConstant.TOK_DEVICES, - new PartialPath(SQLConstant.getSingleRootArray())); - } + 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 void enterShowChildPaths(ShowChildPathsContext ctx) { - super.enterShowChildPaths(ctx); - if (ctx.prefixPath() != null) { - initializedOperator = new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS, - parsePrefixPath(ctx.prefixPath())); - } else { - initializedOperator = new ShowChildPathsOperator(SQLConstant.TOK_CHILD_PATHS, - new PartialPath(SQLConstant.getSingleRootArray())); + 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 void enterShowStorageGroup(ShowStorageGroupContext ctx) { - super.enterShowStorageGroup(ctx); - if (ctx.prefixPath() != null) { - initializedOperator = new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP, - parsePrefixPath(ctx.prefixPath())); - } else { - initializedOperator = new ShowStorageGroupOperator(SQLConstant.TOK_STORAGE_GROUP, - new PartialPath(SQLConstant.getSingleRootArray())); + 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); } - } - - @Override - public void enterLoadFiles(LoadFilesContext ctx) { - super.enterLoadFiles(ctx); - if (ctx.autoCreateSchema() != null) { - if (ctx.autoCreateSchema().INT() != null) { - initializedOperator = new LoadFilesOperator( - new File(removeStringQuote(ctx.stringLiteral().getText())), - Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()), - Integer.parseInt(ctx.autoCreateSchema().INT().getText()) - ); - } else { - initializedOperator = new LoadFilesOperator( - new File(removeStringQuote(ctx.stringLiteral().getText())), - Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()), - IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel() - ); - } - } else { - initializedOperator = new LoadFilesOperator( - new File(removeStringQuote(ctx.stringLiteral().getText())), - true, - IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel() - ); + 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 void enterMoveFile(MoveFileContext ctx) { - super.enterMoveFile(ctx); - initializedOperator = new MoveFileOperator( - new File(removeStringQuote(ctx.stringLiteral(0).getText())), - new File(removeStringQuote(ctx.stringLiteral(1).getText()))); - } - - @Override - public void enterRemoveFile(RemoveFileContext ctx) { - super.enterRemoveFile(ctx); - initializedOperator = new RemoveFileOperator( - new File(removeStringQuote(ctx.stringLiteral().getText()))); + 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 void enterLoadConfigurationStatement(LoadConfigurationStatementContext ctx) { - super.enterLoadConfigurationStatement(ctx); - if (ctx.GLOBAL() != null) { - initializedOperator = new LoadConfigurationOperator(LoadConfigurationOperatorType.GLOBAL); - } else { - initializedOperator = new LoadConfigurationOperator(LoadConfigurationOperatorType.LOCAL); + public Operator visitDeleteStorageGroup(DeleteStorageGroupContext ctx) { + List<PartialPath> deletePaths = new ArrayList<>(); + List<PrefixPathContext> prefixPaths = ctx.prefixPath(); + for (PrefixPathContext prefixPath : prefixPaths) { + deletePaths.add(parsePrefixPath(prefixPath)); } - - } - - @Override - public void enterShowVersion(ShowVersionContext ctx) { - super.enterShowVersion(ctx); - initializedOperator = new ShowOperator(SQLConstant.TOK_VERSION); + DeleteStorageGroupOperator deleteStorageGroupOperator = new DeleteStorageGroupOperator( + SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL); + deleteStorageGroupOperator.setDeletePathList(deletePaths); + return deleteStorageGroupOperator; } @Override - public void enterShowFlushTaskInfo(SqlBaseParser.ShowFlushTaskInfoContext ctx) { - super.enterShowFlushTaskInfo(ctx); - initializedOperator = new ShowOperator(SQLConstant.TOK_FLUSH_TASK_INFO); + public Operator visitMerge(MergeContext ctx) { + return new MergeOperator(SQLConstant.TOK_MERGE); } @Override - public void enterShowTimeseries(ShowTimeseriesContext ctx) { - super.enterShowTimeseries(ctx); - boolean orderByHeat = ctx.LATEST() != null; - if (ctx.prefixPath() != null) { - initializedOperator = new ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES, - parsePrefixPath(ctx.prefixPath()), orderByHeat); - } else { - initializedOperator = new ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES, new PartialPath(SQLConstant.getSingleRootArray()), - orderByHeat); + public Operator visitFlush(FlushContext ctx) { + FlushOperator flushOperator = new FlushOperator(SQLConstant.TOK_FLUSH); + if (ctx.booleanClause() != null) { + flushOperator.setSeq(Boolean.parseBoolean(ctx.booleanClause().getText())); } - } - - @Override - public void enterCreateTimeseries(CreateTimeseriesContext ctx) { - super.enterCreateTimeseries(ctx); - createTimeSeriesOperator = new CreateTimeSeriesOperator(SQLConstant.TOK_METADATA_CREATE); - operatorType = SQLConstant.TOK_METADATA_CREATE; - createTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath())); - } - - @Override - public void enterAlterTimeseries(SqlBaseParser.AlterTimeseriesContext ctx) { - super.enterAlterTimeseries(ctx); - alterTimeSeriesOperator = new AlterTimeSeriesOperator(SQLConstant.TOK_METADATA_ALTER); - operatorType = SQLConstant.TOK_METADATA_ALTER; - alterTimeSeriesOperator.setPath(parseFullPath(ctx.fullPath())); - } - - @Override - public void enterAlterClause(SqlBaseParser.AlterClauseContext ctx) { - super.enterAlterClause(ctx); - Map<String, String> alterMap = new HashMap<>(); - // rename - if (ctx.RENAME() != null) { - alterTimeSeriesOperator.setAlterType(AlterType.RENAME); - alterMap.put(ctx.beforeName.getText(), ctx.currentName.getText()); - } else if (ctx.SET() != null) { - // set - alterTimeSeriesOperator.setAlterType(AlterType.SET); - setMap(ctx, alterMap); - } else if (ctx.DROP() != null) { - // drop - alterTimeSeriesOperator.setAlterType(AlterType.DROP); - for (TerminalNode dropId : ctx.ID()) { - alterMap.put(dropId.getText(), null); + if (ctx.prefixPath(0) != null) { + List<PartialPath> storageGroups = new ArrayList<>(); + for (PrefixPathContext prefixPathContext : ctx.prefixPath()) { + storageGroups.add(parsePrefixPath(prefixPathContext)); } - } else if (ctx.TAGS() != null) { - // add tag - alterTimeSeriesOperator.setAlterType(AlterType.ADD_TAGS); - setMap(ctx, alterMap); - } else if (ctx.ATTRIBUTES() != null) { - // add attribute - alterTimeSeriesOperator.setAlterType(AlterType.ADD_ATTRIBUTES); - setMap(ctx, alterMap); - } else { - // upsert - alterTimeSeriesOperator.setAlterType(AlterType.UPSERT); + flushOperator.setStorageGroupList(storageGroups); } - alterTimeSeriesOperator.setAlterMap(alterMap); - initializedOperator = alterTimeSeriesOperator; + return flushOperator; } - private void setMap(SqlBaseParser.AlterClauseContext ctx, Map<String, String> alterMap) { - List<PropertyContext> tagsList = ctx.property(); - if (ctx.property(0) != null) { - for (PropertyContext property : tagsList) { - String value; - if (property.propertyValue().stringLiteral() != null) { - value = removeStringQuote(property.propertyValue().getText()); - } else { - value = property.propertyValue().getText(); - } - alterMap.put(property.ID().getText(), value); - } - } + @Override + public Operator visitFullMerge(FullMergeContext ctx) { + return new MergeOperator(SQLConstant.TOK_FULL_MERGE); } @Override - public void enterAlias(AliasContext ctx) { - super.enterAlias(ctx); - createTimeSeriesOperator.setAlias(ctx.ID().getText()); + public Operator visitClearcache(ClearcacheContext ctx) { + return new ClearCacheOperator(SQLConstant.TOK_CLEAR_CACHE); } @Override - public void enterCreateUser(CreateUserContext ctx) { - super.enterCreateUser(ctx); + 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())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_CREATE; - } - - @Override - public void enterCreateRole(CreateRoleContext ctx) { - super.enterCreateRole(ctx); - AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_CREATE, - AuthorOperator.AuthorType.CREATE_ROLE); - authorOperator.setRoleName(ctx.ID().getText()); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_CREATE; + return authorOperator; } @Override - public void enterAlterUser(AlterUserContext ctx) { - super.enterAlterUser(ctx); + public Operator visitAlterUser(AlterUserContext ctx) { AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_UPDATE_USER, AuthorOperator.AuthorType.UPDATE_USER); if (ctx.ID() != null) { @@ -515,103 +318,93 @@ public class LogicalGenerator extends SqlBaseBaseListener { authorOperator.setUserName(ctx.ROOT().getText()); } authorOperator.setNewPassword(removeStringQuote(ctx.password.getText())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_UPDATE_USER; + return authorOperator; } @Override - public void enterDropUser(DropUserContext ctx) { - super.enterDropUser(ctx); + public Operator visitDropUser(DropUserContext ctx) { AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP, AuthorOperator.AuthorType.DROP_USER); authorOperator.setUserName(ctx.ID().getText()); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_DROP; + 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 void enterDropRole(DropRoleContext ctx) { - super.enterDropRole(ctx); + public Operator visitDropRole(DropRoleContext ctx) { AuthorOperator authorOperator = new AuthorOperator(SQLConstant.TOK_AUTHOR_DROP, AuthorOperator.AuthorType.DROP_ROLE); authorOperator.setRoleName(ctx.ID().getText()); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_DROP; + return authorOperator; } @Override - public void enterGrantUser(GrantUserContext ctx) { - super.enterGrantUser(ctx); + 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())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterGrantRole(GrantRoleContext ctx) { - super.enterGrantRole(ctx); + 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())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterRevokeUser(RevokeUserContext ctx) { - super.enterRevokeUser(ctx); + 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())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterRevokeRole(RevokeRoleContext ctx) { - super.enterRevokeRole(ctx); + 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())); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterGrantRoleToUser(GrantRoleToUserContext ctx) { - super.enterGrantRoleToUser(ctx); + 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()); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterRevokeRoleFromUser(RevokeRoleFromUserContext ctx) { - super.enterRevokeRoleFromUser(ctx); + 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()); - initializedOperator = authorOperator; - operatorType = SQLConstant.TOK_AUTHOR_GRANT; + return authorOperator; } @Override - public void enterLoadStatement(LoadStatementContext ctx) { - super.enterLoadStatement(ctx); + public Operator visitLoadStatement(LoadStatementContext ctx) { if (ctx.prefixPath().nodeName().size() < 3) { throw new SQLParserException("data load command: child count < 3\n"); } @@ -623,235 +416,384 @@ public class LogicalGenerator extends SqlBaseBaseListener { for (NodeNameContext nodeName : nodeNames) { sc.addTail(nodeName.getText()); } - initializedOperator = new LoadDataOperator(SQLConstant.TOK_DATALOAD, + return new LoadDataOperator(SQLConstant.TOK_DATALOAD, removeStringQuote(csvPath), sc.toString()); - operatorType = SQLConstant.TOK_DATALOAD; } @Override - public void enterGrantWatermarkEmbedding(GrantWatermarkEmbeddingContext ctx) { - super.enterGrantWatermarkEmbedding(ctx); + public Operator visitGrantWatermarkEmbedding(GrantWatermarkEmbeddingContext ctx) { List<RootOrIdContext> rootOrIdList = ctx.rootOrId(); List<String> users = new ArrayList<>(); for (RootOrIdContext rootOrId : rootOrIdList) { users.add(rootOrId.getText()); } - initializedOperator = new DataAuthOperator(SQLConstant.TOK_GRANT_WATERMARK_EMBEDDING, users); + return new DataAuthOperator(SQLConstant.TOK_GRANT_WATERMARK_EMBEDDING, users); } @Override - public void enterRevokeWatermarkEmbedding(RevokeWatermarkEmbeddingContext ctx) { - super.enterRevokeWatermarkEmbedding(ctx); + public Operator visitRevokeWatermarkEmbedding(RevokeWatermarkEmbeddingContext ctx) { List<RootOrIdContext> rootOrIdList = ctx.rootOrId(); List<String> users = new ArrayList<>(); for (RootOrIdContext rootOrId : rootOrIdList) { users.add(rootOrId.getText()); } - initializedOperator = new DataAuthOperator(SQLConstant.TOK_REVOKE_WATERMARK_EMBEDDING, users); - operatorType = SQLConstant.TOK_REVOKE_WATERMARK_EMBEDDING; + return new DataAuthOperator(SQLConstant.TOK_REVOKE_WATERMARK_EMBEDDING, users); } @Override - public void enterListUser(ListUserContext ctx) { - super.enterListUser(ctx); - initializedOperator = new AuthorOperator(SQLConstant.TOK_LIST, - AuthorOperator.AuthorType.LIST_USER); - operatorType = SQLConstant.TOK_LIST; + public Operator visitListUser(ListUserContext ctx) { + return new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_USER); } @Override - public void enterListRole(ListRoleContext ctx) { - super.enterListRole(ctx); - initializedOperator = new AuthorOperator(SQLConstant.TOK_LIST, - AuthorOperator.AuthorType.LIST_ROLE); - operatorType = SQLConstant.TOK_LIST; + public Operator visitListRole(ListRoleContext ctx) { + return new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_ROLE); } @Override - public void enterListPrivilegesUser(ListPrivilegesUserContext ctx) { - super.enterListPrivilegesUser(ctx); + 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())); - initializedOperator = operator; - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterListPrivilegesRole(ListPrivilegesRoleContext ctx) { - super.enterListPrivilegesRole(ctx); + 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())); - initializedOperator = operator; - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterListUserPrivileges(ListUserPrivilegesContext ctx) { - super.enterListUserPrivileges(ctx); + public Operator visitListUserPrivileges(ListUserPrivilegesContext ctx) { AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_USER_PRIVILEGE); operator.setUserName(ctx.rootOrId().getText()); - initializedOperator = operator; - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterListRolePrivileges(ListRolePrivilegesContext ctx) { - super.enterListRolePrivileges(ctx); + public Operator visitListRolePrivileges(ListRolePrivilegesContext ctx) { AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_ROLE_PRIVILEGE); operator.setRoleName(ctx.ID().getText()); - initializedOperator = operator; - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterListAllRoleOfUser(ListAllRoleOfUserContext ctx) { - super.enterListAllRoleOfUser(ctx); + public Operator visitListAllRoleOfUser(ListAllRoleOfUserContext ctx) { AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_USER_ROLES); - initializedOperator = operator; operator.setUserName(ctx.rootOrId().getText()); - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterListAllUserOfRole(ListAllUserOfRoleContext ctx) { - super.enterListAllUserOfRole(ctx); + public Operator visitListAllUserOfRole(ListAllUserOfRoleContext ctx) { AuthorOperator operator = new AuthorOperator(SQLConstant.TOK_LIST, AuthorOperator.AuthorType.LIST_ROLE_USERS); - initializedOperator = operator; operator.setRoleName((ctx.ID().getText())); - operatorType = SQLConstant.TOK_LIST; + return operator; } @Override - public void enterSetTTLStatement(SetTTLStatementContext ctx) { - super.enterSetTTLStatement(ctx); + public Operator visitSetTTLStatement(SetTTLStatementContext ctx) { SetTTLOperator operator = new SetTTLOperator(SQLConstant.TOK_SET); operator.setStorageGroup(parsePrefixPath(ctx.prefixPath())); operator.setDataTTL(Long.parseLong(ctx.INT().getText())); - initializedOperator = operator; - operatorType = SQLConstant.TOK_SET; + return operator; } @Override - public void enterUnsetTTLStatement(UnsetTTLStatementContext ctx) { - super.enterUnsetTTLStatement(ctx); + public Operator visitUnsetTTLStatement(UnsetTTLStatementContext ctx) { SetTTLOperator operator = new SetTTLOperator(SQLConstant.TOK_UNSET); operator.setStorageGroup(parsePrefixPath(ctx.prefixPath())); - initializedOperator = operator; - operatorType = SQLConstant.TOK_UNSET; + return operator; } @Override - public void enterShowTTLStatement(ShowTTLStatementContext ctx) { - super.enterShowTTLStatement(ctx); + public Operator visitShowTTLStatement(ShowTTLStatementContext ctx) { List<PartialPath> storageGroups = new ArrayList<>(); List<PrefixPathContext> prefixPathList = ctx.prefixPath(); for (PrefixPathContext prefixPath : prefixPathList) { storageGroups.add(parsePrefixPath(prefixPath)); } - initializedOperator = new ShowTTLOperator(storageGroups); + return new ShowTTLOperator(storageGroups); } @Override - public void enterShowAllTTLStatement(ShowAllTTLStatementContext ctx) { - super.enterShowAllTTLStatement(ctx); + public Operator visitShowAllTTLStatement(ShowAllTTLStatementContext ctx) { List<PartialPath> storageGroups = new ArrayList<>(); - initializedOperator = new ShowTTLOperator(storageGroups); + return new ShowTTLOperator(storageGroups); } - private String[] parsePrivilege(PrivilegesContext ctx) { - List<StringLiteralContext> privilegeList = ctx.stringLiteral(); - List<String> privileges = new ArrayList<>(); - for (StringLiteralContext privilege : privilegeList) { - privileges.add(removeStringQuote(privilege.getText())); - } - return privileges.toArray(new String[0]); + @Override + public Operator visitShowFlushTaskInfo(ShowFlushTaskInfoContext ctx) { + return new ShowOperator(SQLConstant.TOK_FLUSH_TASK_INFO); } - private String removeStringQuote(String src) { - if (src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'') { - return src.substring(1, src.length() - 1); - } else if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') { - return src.substring(1, src.length() - 1); + @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 { - throw new SQLParserException("error format for string with quote:" + src); + showTimeSeriesOperator = new ShowTimeSeriesOperator(SQLConstant.TOK_TIMESERIES, new PartialPath(SQLConstant.getSingleRootArray()), + orderByHeat); } + if(ctx.showWhereClause() != null) { + parseShowWhereClause(ctx.showWhereClause(), showTimeSeriesOperator); + } + showTimeSeriesOperator.setLimit(parseLimitClause(ctx.limitClause())); + return showTimeSeriesOperator; } @Override - public void enterDeleteTimeseries(DeleteTimeseriesContext ctx) { - super.enterDeleteTimeseries(ctx); - List<PartialPath> deletePaths = new ArrayList<>(); - List<PrefixPathContext> prefixPaths = ctx.prefixPath(); - for (PrefixPathContext prefixPath : prefixPaths) { - deletePaths.add(parsePrefixPath(prefixPath)); + 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())); } - DeleteTimeSeriesOperator deleteTimeSeriesOperator = new DeleteTimeSeriesOperator( - SQLConstant.TOK_METADATA_DELETE); - deleteTimeSeriesOperator.setDeletePathList(deletePaths); - initializedOperator = deleteTimeSeriesOperator; - operatorType = SQLConstant.TOK_METADATA_DELETE; } @Override - public void enterSetStorageGroup(SetStorageGroupContext ctx) { - super.enterSetStorageGroup(ctx); - SetStorageGroupOperator setStorageGroupOperator = new SetStorageGroupOperator( - SQLConstant.TOK_METADATA_SET_FILE_LEVEL); - PartialPath path = parsePrefixPath(ctx.prefixPath()); - setStorageGroupOperator.setPath(path); - initializedOperator = setStorageGroupOperator; - operatorType = SQLConstant.TOK_METADATA_SET_FILE_LEVEL; + 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 void enterDeleteStorageGroup(DeleteStorageGroupContext ctx) { - super.enterDeleteStorageGroup(ctx); - List<PartialPath> deletePaths = new ArrayList<>(); - List<PrefixPathContext> prefixPaths = ctx.prefixPath(); - for (PrefixPathContext prefixPath : prefixPaths) { - deletePaths.add(parsePrefixPath(prefixPath)); + 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())); } - DeleteStorageGroupOperator deleteStorageGroupOperator = new DeleteStorageGroupOperator( - SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL); - deleteStorageGroupOperator.setDeletePathList(deletePaths); - initializedOperator = deleteStorageGroupOperator; - operatorType = SQLConstant.TOK_METADATA_DELETE_FILE_LEVEL; } @Override - public void enterDeleteStatement(DeleteStatementContext ctx) { - super.enterDeleteStatement(ctx); - operatorType = SQLConstant.TOK_DELETE; - deleteDataOp = new DeleteDataOperator(SQLConstant.TOK_DELETE); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - List<PrefixPathContext> prefixPaths = ctx.prefixPath(); - for (PrefixPathContext prefixPath : prefixPaths) { - PartialPath path = parsePrefixPath(prefixPath); - selectOp.addSelectPath(path); + 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); } - deleteDataOp.setSelectOperator(selectOp); - initializedOperator = deleteDataOp; } @Override - public void enterDisableAlign(SqlBaseParser.DisableAlignContext ctx) { - super.enterDisableAlign(ctx); - queryOp.setAlignByTime(false); + 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) { + QueryOperator queryOp = new QueryOperator(SQLConstant.TOK_QUERY); + SelectOperator selectOp = (SelectOperator) visit(ctx.selectElements()); + FromOperator fromOp = (FromOperator) visit(ctx.fromClause()); + FilterOperator whereOp = (FilterOperator) visit(ctx.whereClause()); + queryOp.setFromOperator(fromOp); + queryOp.setFilterOperator(whereOp.getChildren().get(0)); + queryOp.setSelectOperator(selectOp); + return queryOp; + } + + @Override + public Operator visitSelectElement(SelectElementContext ctx) { + SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT); + List<SqlBaseParser.SuffixPathOrConstantContext> suffixPathOrConstants = ctx.suffixPathOrConstant(); + for (SqlBaseParser.SuffixPathOrConstantContext suffixPathOrConstant : suffixPathOrConstants) { + if (suffixPathOrConstant.suffixPath() != null) { + PartialPath path = parseSuffixPath(suffixPathOrConstant.suffixPath()); + selectOp.addSelectPath(path); + } else { + PartialPath path = new PartialPath(new String[]{suffixPathOrConstant.SINGLE_QUOTE_STRING_LITERAL().getText()}); + selectOp.addSelectPath(path); + } + } + return selectOp; } - @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning @Override - public void enterGroupByFillClause(SqlBaseParser.GroupByFillClauseContext ctx) { - super.enterGroupByFillClause(ctx); + public Operator visitFromClause(FromClauseContext ctx) { + FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM); + List<PrefixPathContext> prefixFromPaths = ctx.prefixPath(); + for (PrefixPathContext prefixFromPath : prefixFromPaths) { + PartialPath path = parsePrefixPath(prefixFromPath); + fromOp.addPrefixTablePath(path); + } + return fromOp; + } + + private int parseLimitClause(LimitClauseContext ctx) { + int limit; + try { + limit = Integer.parseInt(ctx.INT().getText()); + } catch (NumberFormatException e) { + throw new SQLParserException("Out of range. LIMIT <N>: N should be Int32."); + } + if (limit <= 0) { + throw new SQLParserException("LIMIT <N>: N should be greater than 0."); + } + return limit; + } + + private int parseSlimitClause(SlimitClauseContext ctx) { + int slimit; + try { + slimit = Integer.parseInt(ctx.INT().getText()); + } catch (NumberFormatException e) { + throw new SQLParserException( + "Out of range. SLIMIT <SN>: SN should be Int32."); + } + if (slimit <= 0) { + throw new SQLParserException("SLIMIT <SN>: SN should be greater than 0."); + } + return slimit; + } + + private void parseGroupByTimeClause(GroupByTimeClauseContext ctx, QueryOperator queryOp) { + queryOp.setGroupByTime(true); + queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null); + // parse timeUnit + queryOp.setUnit(parseDuration(ctx.DURATION(0).getText())); + queryOp.setSlidingStep(queryOp.getUnit()); + // parse sliding step + if (ctx.DURATION().size() == 2) { + queryOp.setSlidingStep(parseDuration(ctx.DURATION(1).getText())); + if (queryOp.getSlidingStep() < queryOp.getUnit()) { + throw new SQLParserException( + "The third parameter sliding step shouldn't be smaller than the second parameter time interval."); + } + } + + parseTimeInterval(ctx.timeInterval(), queryOp); + + if (ctx.INT() != null) { + queryOp.setLevel(Integer.parseInt(ctx.INT().getText())); + } + } + + private void parseGroupByFillClause(GroupByFillClauseContext ctx, QueryOperator queryOp) { queryOp.setGroupByTime(true); queryOp.setFill(true); queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null); @@ -860,7 +802,7 @@ public class LogicalGenerator extends SqlBaseBaseListener { queryOp.setUnit(parseDuration(ctx.DURATION().getText())); queryOp.setSlidingStep(queryOp.getUnit()); - parseTimeInterval(ctx.timeInterval()); + parseTimeInterval(ctx.timeInterval(), queryOp); List<TypeClauseContext> list = ctx.typeClause(); Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class); @@ -901,80 +843,6 @@ public class LogicalGenerator extends SqlBaseBaseListener { queryOp.setFillTypes(fillTypes); } - private void parseTimeInterval(TimeIntervalContext timeInterval) { - long startTime; - long endTime; - if (timeInterval.timeValue(0).INT() != null) { - startTime = Long.parseLong(timeInterval.timeValue(0).INT().getText()); - } else if (timeInterval.timeValue(0).dateExpression() != null) { - startTime = parseDateExpression(timeInterval.timeValue(0).dateExpression()); - } else { - startTime = parseTimeFormat(timeInterval.timeValue(0).dateFormat().getText()); - } - if (timeInterval.timeValue(1).INT() != null) { - endTime = Long.parseLong(timeInterval.timeValue(1).INT().getText()); - } else if (timeInterval.timeValue(1).dateExpression() != null) { - endTime = parseDateExpression(timeInterval.timeValue(1).dateExpression()); - } else { - endTime = parseTimeFormat(timeInterval.timeValue(1).dateFormat().getText()); - } - - queryOp.setStartTime(startTime); - queryOp.setEndTime(endTime); - if (startTime >= endTime) { - throw new SQLParserException("start time should be smaller than endTime in GroupBy"); - } - } - - @Override - public void enterGroupByTimeClause(GroupByTimeClauseContext ctx) { - super.enterGroupByTimeClause(ctx); - - queryOp.setGroupByTime(true); - queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null); - // parse timeUnit - queryOp.setUnit(parseDuration(ctx.DURATION(0).getText())); - queryOp.setSlidingStep(queryOp.getUnit()); - // parse sliding step - if (ctx.DURATION().size() == 2) { - queryOp.setSlidingStep(parseDuration(ctx.DURATION(1).getText())); - if (queryOp.getSlidingStep() < queryOp.getUnit()) { - throw new SQLParserException( - "The third parameter sliding step shouldn't be smaller than the second parameter time interval."); - } - } - - parseTimeInterval(ctx.timeInterval()); - - if (ctx.INT() != null) { - queryOp.setLevel(Integer.parseInt(ctx.INT().getText())); - } - } - - @Override - public void enterGroupByLevelClause(SqlBaseParser.GroupByLevelClauseContext ctx) { - super.enterGroupByLevelClause(ctx); - queryOp.setGroupByLevel(true); - - queryOp.setLevel(Integer.parseInt(ctx.INT().getText())); - } - - @Override - public void enterFillClause(FillClauseContext ctx) { - super.enterFillClause(ctx); - FilterOperator filterOperator = queryOp.getFilterOperator(); - if (!filterOperator.isLeaf() || filterOperator.getTokenIntType() != SQLConstant.EQUAL) { - throw new SQLParserException("Only \"=\" can be used in fill function"); - } - 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); - } - private void parseTypeClause(TypeClauseContext ctx, Map<TSDataType, IFill> fillTypes) { TSDataType dataType = parseType(ctx.dataType().getText()); if (ctx.linearClause() != null && dataType == TSDataType.TEXT) { @@ -1009,12 +877,6 @@ public class LogicalGenerator extends SqlBaseBaseListener { } } - @Override - public void enterAlignByDeviceClause(AlignByDeviceClauseContext ctx) { - super.enterAlignByDeviceClause(ctx); - queryOp.setAlignByDevice(true); - } - /** * parse datatype node. */ @@ -1038,356 +900,264 @@ public class LogicalGenerator extends SqlBaseBaseListener { } } - @Override - public void enterLimitClause(LimitClauseContext ctx) { - super.enterLimitClause(ctx); - int limit; - try { - limit = Integer.parseInt(ctx.INT().getText()); - } catch (NumberFormatException e) { - throw new SQLParserException("Out of range. LIMIT <N>: N should be Int32."); - } - if (limit <= 0) { - throw new SQLParserException("LIMIT <N>: N should be greater than 0."); - } - if (initializedOperator instanceof ShowTimeSeriesOperator) { - ((ShowTimeSeriesOperator) initializedOperator).setLimit(limit); - } else { - queryOp.setRowLimit(limit); - } - } - - @Override - public void enterOffsetClause(OffsetClauseContext ctx) { - super.enterOffsetClause(ctx); - int offset; - try { - offset = Integer.parseInt(ctx.INT().getText()); - } catch (NumberFormatException e) { - throw new SQLParserException( - "Out of range. OFFSET <OFFSETValue>: OFFSETValue should be Int32."); - } - if (offset < 0) { - throw new SQLParserException("OFFSET <OFFSETValue>: OFFSETValue should >= 0."); - } - if (initializedOperator instanceof ShowTimeSeriesOperator) { - ((ShowTimeSeriesOperator) initializedOperator).setOffset(offset); - } else { - queryOp.setRowOffset(offset); - } - } - - @Override - public void enterOrderByTimeClause(OrderByTimeClauseContext ctx) { - super.enterOrderByTimeClause(ctx); + private void parseOrderByTimeClause(OrderByTimeClauseContext ctx, QueryOperator queryOp) { queryOp.setColumn(ctx.TIME().getText()); if (ctx.DESC() != null) { queryOp.setAscending(false); } } - @Override - public void enterSlimitClause(SlimitClauseContext ctx) { - super.enterSlimitClause(ctx); - int slimit; - try { - slimit = Integer.parseInt(ctx.INT().getText()); - } catch (NumberFormatException e) { - throw new SQLParserException( - "Out of range. SLIMIT <SN>: SN should be Int32."); - } - if (slimit <= 0) { - throw new SQLParserException("SLIMIT <SN>: SN should be greater than 0."); - } - queryOp.setSeriesLimit(slimit); + private void parseAlignByDeviceClause(QueryOperator queryOp) { + queryOp.setAlignByDevice(true); } - @Override - public void enterSoffsetClause(SoffsetClauseContext ctx) { - super.enterSoffsetClause(ctx); - int soffset; - try { - soffset = Integer.parseInt(ctx.INT().getText()); - } catch (NumberFormatException e) { - throw new SQLParserException( - "Out of range. SOFFSET <SOFFSETValue>: SOFFSETValue should be Int32."); - } - if (soffset < 0) { - throw new SQLParserException( - "SOFFSET <SOFFSETValue>: SOFFSETValue should >= 0."); - } - queryOp.setSeriesOffset(soffset); - } - - @Override - public void enterInsertColumnSpec(InsertColumnSpecContext ctx) { - super.enterInsertColumnSpec(ctx); - List<NodeNameWithoutStarContext> nodeNamesWithoutStar = ctx.nodeNameWithoutStar(); - List<String> measurementList = new ArrayList<>(); - for (NodeNameWithoutStarContext nodeNameWithoutStar : nodeNamesWithoutStar) { - String measurement = nodeNameWithoutStar.getText(); - measurementList.add(measurement); - } - insertOp.setMeasurementList(measurementList.toArray(new String[0])); + private void parseDisableAlign(QueryOperator queryOp) { + queryOp.setAlignByTime(false); } - @Override - public void enterInsertValuesSpec(InsertValuesSpecContext ctx) { - super.enterInsertValuesSpec(ctx); - long timestamp; - if (ctx.dateFormat() != null) { - timestamp = parseTimeFormat(ctx.dateFormat().getText()); + private void parseTimeInterval(TimeIntervalContext timeInterval, QueryOperator queryOp) { + long startTime; + long endTime; + if (timeInterval.timeValue(0).INT() != null) { + startTime = Long.parseLong(timeInterval.timeValue(0).INT().getText()); + } else if (timeInterval.timeValue(0).dateExpression() != null) { + startTime = parseDateExpression(timeInterval.timeValue(0).dateExpression()); } else { - timestamp = Long.parseLong(ctx.INT().getText()); + startTime = parseTimeFormat(timeInterval.timeValue(0).dateFormat().getText()); } - insertOp.setTime(timestamp); - List<String> valueList = new ArrayList<>(); - List<ConstantContext> values = ctx.constant(); - for (ConstantContext value : values) { - valueList.add(value.getText()); + if (timeInterval.timeValue(1).INT() != null) { + endTime = Long.parseLong(timeInterval.timeValue(1).INT().getText()); + } else if (timeInterval.timeValue(1).dateExpression() != null) { + endTime = parseDateExpression(timeInterval.timeValue(1).dateExpression()); + } else { + endTime = parseTimeFormat(timeInterval.timeValue(1).dateFormat().getText()); } - insertOp.setValueList(valueList.toArray(new String[0])); - initializedOperator = insertOp; - } - private PartialPath parseFullPath(FullPathContext ctx) { - List<NodeNameWithoutStarContext> nodeNamesWithoutStar = ctx.nodeNameWithoutStar(); - String[] path = new String[nodeNamesWithoutStar.size() + 1]; - int i = 0; - if (ctx.ROOT() != null) { - path[0] = ctx.ROOT().getText(); - } - for (NodeNameWithoutStarContext nodeNameWithoutStar : nodeNamesWithoutStar) { - i++; - path[i] = nodeNameWithoutStar.getText(); + queryOp.setStartTime(startTime); + queryOp.setEndTime(endTime); + if (startTime >= endTime) { + throw new SQLParserException("start time should be smaller than endTime in GroupBy"); } - return new PartialPath(path); } - @Override - public void enterAttributeClauses(AttributeClausesContext ctx) { - super.enterAttributeClauses(ctx); - final String dataType = ctx.dataType().getChild(0).getText().toUpperCase(); - final TSDataType tsDataType = TSDataType.valueOf(dataType); - createTimeSeriesOperator.setDataType(tsDataType); - - final IoTDBDescriptor ioTDBDescriptor = IoTDBDescriptor.getInstance(); - TSEncoding encoding = ioTDBDescriptor.getDefualtEncodingByType(tsDataType); - if (Objects.nonNull(ctx.encoding())) { - String encodingString = ctx.encoding().getChild(0).getText().toUpperCase(); - encoding = TSEncoding.valueOf(encodingString); - } - createTimeSeriesOperator.setEncoding(encoding); - - CompressionType compressor; - List<PropertyContext> properties = ctx.property(); - if (ctx.compressor() != null) { - compressor = CompressionType.valueOf(ctx.compressor().getText().toUpperCase()); + private void parseShowWhereClause(ShowWhereClauseContext ctx, ShowTimeSeriesOperator operator) { + PropertyValueContext propertyValueContext; + if (ctx.containsExpression() != null) { + operator.setContains(true); + propertyValueContext = ctx.containsExpression().propertyValue(); + operator.setKey(ctx.containsExpression().ID().getText()); } else { - compressor = TSFileDescriptor.getInstance().getConfig().getCompressor(); + operator.setContains(false); + propertyValueContext = ctx.property().propertyValue(); + operator.setKey(ctx.property().ID().getText()); } - Map<String, String> props = null; - if (ctx.property(0) != null) { - props = new HashMap<>(properties.size()); - for (PropertyContext property : properties) { - props.put(property.ID().getText().toLowerCase(), - property.propertyValue().getText().toLowerCase()); - } + String value; + if (propertyValueContext.stringLiteral() != null) { + value = removeStringQuote(propertyValueContext.getText()); + } else { + value = propertyValueContext.getText(); } - createTimeSeriesOperator.setCompressor(compressor); - createTimeSeriesOperator.setProps(props); - initializedOperator = createTimeSeriesOperator; + operator.setValue(value); } - @Override - public void enterAliasClause(SqlBaseParser.AliasClauseContext ctx) { - super.enterAliasClause(ctx); - if (alterTimeSeriesOperator != null && ctx.ID() != null) { - alterTimeSeriesOperator.setAlias(ctx.ID().getText()); + private String[] parsePrivilege(PrivilegesContext ctx) { + List<StringLiteralContext> privilegeList = ctx.stringLiteral(); + List<String> privileges = new ArrayList<>(); + for (StringLiteralContext privilege : privilegeList) { + privileges.add(removeStringQuote(privilege.getText())); } + return privileges.toArray(new String[0]); } + /** + * for delete command, time should only have an end time. + * + * @param operator delete logical plan + */ + private Pair<Long, Long> parseDeleteTimeInterval(DeleteDataOperator operator) { + FilterOperator filterOperator = operator.getFilterOperator(); + if (!filterOperator.isLeaf() && filterOperator.getTokenIntType() != SQLConstant.KW_AND) { + throw new SQLParserException( + DELETE_RANGE_ERROR_MSG); + } - @Override - public void enterAttributeClause(AttributeClauseContext ctx) { - super.enterAttributeClause(ctx); - Map<String, String> attributes = extractMap(ctx.property(), ctx.property(0)); - if (createTimeSeriesOperator != null) { - createTimeSeriesOperator.setAttributes(attributes); - } else if (alterTimeSeriesOperator != null) { - alterTimeSeriesOperator.setAttributesMap(attributes); + if (filterOperator.isLeaf()) { + return calcOperatorInterval(filterOperator); } - } - @Override - public void enterTagClause(TagClauseContext ctx) { - super.enterTagClause(ctx); - Map<String, String> tags = extractMap(ctx.property(), ctx.property(0)); - if (createTimeSeriesOperator != null) { - createTimeSeriesOperator.setTags(tags); - } else if (alterTimeSeriesOperator != null) { - alterTimeSeriesOperator.setTagsMap(tags); + List<FilterOperator> children = filterOperator.getChildren(); + FilterOperator lOperator = children.get(0); + FilterOperator rOperator = children.get(1); + if (!lOperator.isLeaf() || !rOperator.isLeaf()) { + throw new SQLParserException( + DELETE_RANGE_ERROR_MSG); } - } - private Map<String, String> extractMap(List<PropertyContext> property2, - PropertyContext property3) { - String value; - Map<String, String> tags = new HashMap<>(property2.size()); - if (property3 != null) { - for (PropertyContext property : property2) { - if (property.propertyValue().stringLiteral() != null) { - value = removeStringQuote(property.propertyValue().getText()); - } else { - value = property.propertyValue().getText(); - } - tags.put(property.ID().getText(), value); - } + Pair<Long, Long> leftOpInterval = calcOperatorInterval(lOperator); + Pair<Long, Long> rightOpInterval = calcOperatorInterval(rOperator); + Pair<Long, Long> parsedInterval = new Pair<>( + Math.max(leftOpInterval.left, rightOpInterval.left), + Math.min(leftOpInterval.right, rightOpInterval.right)); + if (parsedInterval.left > parsedInterval.right) { + throw new SQLParserException( + "Invalid delete range: [" + parsedInterval.left + ", " + parsedInterval.right + "]"); } - return tags; + return parsedInterval; } - @Override - public void enterInsertStatement(InsertStatementContext ctx) { - super.enterInsertStatement(ctx); - insertOp = new InsertOperator(SQLConstant.TOK_INSERT); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - operatorType = SQLConstant.TOK_INSERT; - selectOp.addSelectPath(parsePrefixPath(ctx.prefixPath())); - insertOp.setSelectOperator(selectOp); + private Pair<Long, Long> calcOperatorInterval(FilterOperator filterOperator) { + long time = Long.parseLong(((BasicFunctionOperator) filterOperator).getValue()); + switch (filterOperator.getTokenIntType()) { + case SQLConstant.LESSTHAN: + return new Pair<>(Long.MIN_VALUE, time - 1); + case SQLConstant.LESSTHANOREQUALTO: + return new Pair<>(Long.MIN_VALUE, time); + case SQLConstant.GREATERTHAN: + return new Pair<>(time + 1, Long.MAX_VALUE); + case SQLConstant.GREATERTHANOREQUALTO: + return new Pair<>(time, Long.MAX_VALUE); + case SQLConstant.EQUAL: + return new Pair<>(time, time); + default: + throw new SQLParserException( + DELETE_RANGE_ERROR_MSG); + } } - @Override - public void enterUpdateStatement(UpdateStatementContext ctx) { - super.enterUpdateStatement(ctx); - updateOp = new UpdateOperator(SQLConstant.TOK_UPDATE); - FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM); - fromOp.addPrefixTablePath(parsePrefixPath(ctx.prefixPath())); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - operatorType = SQLConstant.TOK_UPDATE; - initializedOperator = updateOp; - } - @Override - public void enterSelectStatement(SelectStatementContext ctx) { - super.enterSelectStatement(ctx); - operatorType = SQLConstant.TOK_QUERY; - queryOp = new QueryOperator(SQLConstant.TOK_QUERY); - initializedOperator = queryOp; - } - @Override - public void enterFromClause(FromClauseContext ctx) { - super.enterFromClause(ctx); - FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM); - List<PrefixPathContext> prefixFromPaths = ctx.prefixPath(); - for (PrefixPathContext prefixFromPath : prefixFromPaths) { - PartialPath path = parsePrefixPath(prefixFromPath); - fromOp.addPrefixTablePath(path); - } - queryOp.setFromOperator(fromOp); - } @Override - public void enterFunctionElement(FunctionElementContext ctx) { - super.enterFunctionElement(ctx); - 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()); - } - queryOp.setSelectOperator(selectOp); + public Operator visitWhereClause(WhereClauseContext ctx) { + FilterOperator whereOp = new FilterOperator(SQLConstant.TOK_WHERE); + whereOp.addChildOperator(parseOrExpression(ctx.orExpression())); + return whereOp; } - @Override - public void enterSelectElement(SelectElementContext ctx) { - super.enterSelectElement(ctx); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - List<SqlBaseParser.SuffixPathOrConstantContext> suffixPathOrConstants = ctx.suffixPathOrConstant(); - for (SqlBaseParser.SuffixPathOrConstantContext suffixPathOrConstant : suffixPathOrConstants) { - if (suffixPathOrConstant.suffixPath() != null) { - PartialPath path = parseSuffixPath(suffixPathOrConstant.suffixPath()); - selectOp.addSelectPath(path); - } else { - PartialPath path = new PartialPath(new String[]{suffixPathOrConstant.SINGLE_QUOTE_STRING_LITERAL().getText()}); - selectOp.addSelectPath(path); + private FilterOperator parseOrExpression(OrExpressionContext ctx) { + if (ctx.andExpression().size() == 1) { + return parseAndExpression(ctx.andExpression(0)); + } + FilterOperator binaryOp = new FilterOperator(SQLConstant.KW_OR); + if (ctx.andExpression().size() > 2) { + binaryOp.addChildOperator(parseAndExpression(ctx.andExpression(0))); + binaryOp.addChildOperator(parseAndExpression(ctx.andExpression(1))); + for (int i = 2; i < ctx.andExpression().size(); i++) { + FilterOperator op = new FilterOperator(SQLConstant.KW_OR); + op.addChildOperator(binaryOp); + op.addChildOperator(parseAndExpression(ctx.andExpression(i))); + binaryOp = op; + } + } else { + for (AndExpressionContext andExpressionContext : ctx.andExpression()) { + binaryOp.addChildOperator(parseAndExpression(andExpressionContext)); } } - queryOp.setSelectOperator(selectOp); + return binaryOp; } - @Override - public void enterLastElement(SqlBaseParser.LastElementContext ctx) { - super.enterLastElement(ctx); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - selectOp.setLastQuery(); - LastClauseContext lastClauseContext = ctx.lastClause(); - if (lastClauseContext.asClause().size() != 0) { - parseAsClause(lastClauseContext.asClause()); + private FilterOperator parseAndExpression(AndExpressionContext ctx) { + if (ctx.predicate().size() == 1) { + return parsePredicate(ctx.predicate(0)); + } + FilterOperator binaryOp = new FilterOperator(SQLConstant.KW_AND); + int size = ctx.predicate().size(); + if (size > 2) { + binaryOp.addChildOperator(parsePredicate(ctx.predicate(0))); + binaryOp.addChildOperator(parsePredicate(ctx.predicate(1))); + for (int i = 2; i < size; i++) { + FilterOperator op = new FilterOperator(SQLConstant.KW_AND); + op.addChildOperator(binaryOp); + op.addChildOperator(parsePredicate(ctx.predicate(i))); + binaryOp = op; + } } else { - List<SuffixPathContext> suffixPaths = lastClauseContext.suffixPath(); - for (SuffixPathContext suffixPath : suffixPaths) { - PartialPath path = parseSuffixPath(suffixPath); - selectOp.addSelectPath(path); + for (PredicateContext predicateContext : ctx.predicate()) { + binaryOp.addChildOperator(parsePredicate(predicateContext)); } } - queryOp.setSelectOperator(selectOp); - } - - @Override - public void enterAsElement(AsElementContext ctx) { - super.enterAsElement(ctx); - selectOp = new SelectOperator(SQLConstant.TOK_SELECT); - parseAsClause(ctx.asClause()); - queryOp.setSelectOperator(selectOp); + return binaryOp; } - public void parseAsClause(List<AsClauseContext> asClauseContexts) { - for (AsClauseContext asClauseContext : asClauseContexts) { - PartialPath path = parseSuffixPath(asClauseContext.suffixPath()); - if (asClauseContext.ID() != null) { - path.setTsAlias(asClauseContext.ID().toString()); + @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning + private FilterOperator parsePredicate(PredicateContext ctx) { + if (ctx.OPERATOR_NOT() != null) { + FilterOperator notOp = new FilterOperator(SQLConstant.KW_NOT); + notOp.addChildOperator(parseOrExpression(ctx.orExpression())); + return notOp; + } else if (ctx.LR_BRACKET() != null && ctx.OPERATOR_NOT() == null) { + return parseOrExpression(ctx.orExpression()); + } else { + PartialPath path = null; + if (ctx.TIME() != null || ctx.TIMESTAMP() != null) { + path = new PartialPath(SQLConstant.getSingleTimeArray()); + } + if (ctx.fullPath() != null) { + path = parseFullPath(ctx.fullPath()); + } + if (ctx.suffixPath() != null) { + path = parseSuffixPath(ctx.suffixPath()); + } + if (path == null) { + throw new SQLParserException("Path is null, please check the sql."); + } + if (ctx.inClause() != null) { + return parseInOperator(ctx.inClause(), path); + } else { + return parseBasicFunctionOperator(ctx, path); } - selectOp.addSelectPath(path); } } - @Override - public void enterFunctionAsElement(FunctionAsElementContext ctx) { - super.enterFunctionAsElement(ctx); - 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()); + private FilterOperator parseInOperator(InClauseContext ctx, PartialPath path) { + Set<String> values = new HashSet<>(); + boolean not = ctx.OPERATOR_NOT() != null; + for (ConstantContext constant : ctx.constant()) { + if (constant.dateExpression() != null) { + if (!path.equals(TIME_PATH)) { + throw new SQLParserException(path.getFullPath(), "Date can only be used to time"); + } + values.add(Long.toString(parseDateExpression(constant.dateExpression()))); + } else { + values.add(constant.getText()); } - selectOp.addClusterPath(path, functionCallContext.functionName().getText()); } - queryOp.setSelectOperator(selectOp); + return new InOperator(ctx.OPERATOR_IN().getSymbol().getType(), path, not, values); } - @Override - public void enterSetCol(SetColContext ctx) { - super.enterSetCol(ctx); - selectOp.addSelectPath(parseSuffixPath(ctx.suffixPath())); - updateOp.setSelectOperator(selectOp); - updateOp.setValue(ctx.constant().getText()); + private FilterOperator parseBasicFunctionOperator(PredicateContext ctx, PartialPath path) { + BasicFunctionOperator basic; + if (ctx.constant().dateExpression() != null) { + if (!path.equals(TIME_PATH)) { + throw new SQLParserException(path.getFullPath(), "Date can only be used to time"); + } + basic = new BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path, + Long.toString(parseDateExpression(ctx.constant().dateExpression()))); + } else { + basic = new BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path, + ctx.constant().getText()); + } + return basic; } - - private PartialPath parsePrefixPath(PrefixPathContext ctx) { - List<NodeNameContext> nodeNames = ctx.nodeName(); - String[] path = new String[nodeNames.size() + 1]; - path[0] = ctx.ROOT().getText(); - for (int i = 0; i < nodeNames.size(); i++) { - path[i + 1] = nodeNames.get(i).getText(); + /** + * parse time expression, which is addition and subtraction expression of duration time, now() or + * DataTimeFormat time. <p> eg. now() + 1d - 2h </p> + */ + private Long parseDateExpression(DateExpressionContext ctx) { + long time; + time = parseTimeFormat(ctx.getChild(0).getText()); + for (int i = 1; i < ctx.getChildCount(); i = i + 2) { + if (ctx.getChild(i).getText().equals("+")) { + time += parseDuration(ctx.getChild(i + 1).getText()); + } else { + time -= parseDuration(ctx.getChild(i + 1).getText()); + } } - return new PartialPath(path); + return time; } + /** * parse duration to time value. * @@ -1422,189 +1192,164 @@ public class LogicalGenerator extends SqlBaseBaseListener { return total; } - @Override - public void enterWhereClause(WhereClauseContext ctx) { - super.enterWhereClause(ctx); - FilterOperator whereOp = new FilterOperator(SQLConstant.TOK_WHERE); - whereOp.addChildOperator(parseOrExpression(ctx.orExpression())); - switch (operatorType) { - case SQLConstant.TOK_DELETE: - deleteDataOp.setFilterOperator(whereOp.getChildren().get(0)); - Pair<Long, Long> timeInterval = parseDeleteTimeInterval(deleteDataOp); - deleteDataOp.setStartTime(timeInterval.left); - deleteDataOp.setEndTime(timeInterval.right); - break; - case SQLConstant.TOK_QUERY: - queryOp.setFilterOperator(whereOp.getChildren().get(0)); - break; - case SQLConstant.TOK_UPDATE: - updateOp.setFilterOperator(whereOp.getChildren().get(0)); - break; - default: - throw new SQLParserException("Where only support select, delete, update."); - } + private void parseSetCol(SetColContext ctx, SelectOperator selectOp, UpdateOperator updateOp) { + selectOp.addSelectPath(parseSuffixPath(ctx.suffixPath())); + updateOp.setValue(ctx.constant().getText()); } - @Override - public void enterShowWhereClause(ShowWhereClauseContext ctx) { - super.enterShowWhereClause(ctx); - - ShowTimeSeriesOperator operator = (ShowTimeSeriesOperator) initializedOperator; - PropertyValueContext propertyValueContext; - if (ctx.containsExpression() != null) { - operator.setContains(true); - propertyValueContext = ctx.containsExpression().propertyValue(); - operator.setKey(ctx.containsExpression().ID().getText()); - } else { - operator.setContains(false); - propertyValueContext = ctx.property().propertyValue(); - operator.setKey(ctx.property().ID().getText()); - } - String value; - if (propertyValueContext.stringLiteral() != null) { - value = removeStringQuote(propertyValueContext.getText()); - } else { - value = propertyValueContext.getText(); + private PartialPath parseSuffixPath(SuffixPathContext ctx) { + List<NodeNameContext> nodeNames = ctx.nodeName(); + String[] path = new String[nodeNames.size()]; + for (int i = 0; i < nodeNames.size(); i++) { + path[i] = nodeNames.get(i).getText(); } - operator.setValue(value); + return new PartialPath(path); } - private FilterOperator parseOrExpression(OrExpressionContext ctx) { - if (ctx.andExpression().size() == 1) { - return parseAndExpression(ctx.andExpression(0)); - } - FilterOperator binaryOp = new FilterOperator(SQLConstant.KW_OR); - if (ctx.andExpression().size() > 2) { - binaryOp.addChildOperator(parseAndExpression(ctx.andExpression(0))); - binaryOp.addChildOperator(parseAndExpression(ctx.andExpression(1))); - for (int i = 2; i < ctx.andExpression().size(); i++) { - FilterOperator op = new FilterOperator(SQLConstant.KW_OR); - op.addChildOperator(binaryOp); - op.addChildOperator(parseAndExpression(ctx.andExpression(i))); - binaryOp = op; - } - } else { - for (AndExpressionContext andExpressionContext : ctx.andExpression()) { - binaryOp.addChildOperator(parseAndExpression(andExpressionContext)); - } + private void parseInsertColumnSpec(InsertColumnSpecContext ctx, InsertOperator insertOp) { + List<NodeNameWithoutStarContext> nodeNamesWithoutStar = ctx.nodeNameWithoutStar(); + List<String> measurementList = new ArrayList<>(); + for (NodeNameWithoutStarContext nodeNameWithoutStar : nodeNamesWithoutStar) { + String measurement = nodeNameWithoutStar.getText(); + measurementList.add(measurement); } - return binaryOp; + insertOp.setMeasurementList(measurementList.toArray(new String[0])); } - private FilterOperator parseAndExpression(AndExpressionContext ctx) { - if (ctx.predicate().size() == 1) { - return parsePredicate(ctx.predicate(0)); - } - FilterOperator binaryOp = new FilterOperator(SQLConstant.KW_AND); - int size = ctx.predicate().size(); - if (size > 2) { - binaryOp.addChildOperator(parsePredicate(ctx.predicate(0))); - binaryOp.addChildOperator(parsePredicate(ctx.predicate(1))); - for (int i = 2; i < size; i++) { - FilterOperator op = new FilterOperator(SQLConstant.KW_AND); - op.addChildOperator(binaryOp); - op.addChildOperator(parsePredicate(ctx.predicate(i))); - binaryOp = op; - } + private void parseInsertValuesSpec(InsertValuesSpecContext ctx, InsertOperator insertOp) { + long timestamp; + if (ctx.dateFormat() != null) { + timestamp = parseTimeFormat(ctx.dateFormat().getText()); } else { - for (PredicateContext predicateContext : ctx.predicate()) { - binaryOp.addChildOperator(parsePredicate(predicateContext)); - } + timestamp = Long.parseLong(ctx.INT().getText()); } - return binaryOp; + insertOp.setTime(timestamp); + List<String> valueList = new ArrayList<>(); + List<ConstantContext> values = ctx.constant(); + for (ConstantContext value : values) { + valueList.add(value.getText()); + } + insertOp.setValueList(valueList.toArray(new String[0])); } - @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning - private FilterOperator parsePredicate(PredicateContext ctx) { - if (ctx.OPERATOR_NOT() != null) { - FilterOperator notOp = new FilterOperator(SQLConstant.KW_NOT); - notOp.addChildOperator(parseOrExpression(ctx.orExpression())); - return notOp; - } else if (ctx.LR_BRACKET() != null && ctx.OPERATOR_NOT() == null) { - return parseOrExpression(ctx.orExpression()); - } else { - PartialPath path = null; - if (ctx.TIME() != null || ctx.TIMESTAMP() != null) { - path = new PartialPath(SQLConstant.getSingleTimeArray()); - } - if (ctx.fullPath() != null) { - path = parseFullPath(ctx.fullPath()); - } - if (ctx.suffixPath() != null) { - path = parseSuffixPath(ctx.suffixPath()); - } - if (path == null) { - throw new SQLParserException("Path is null, please check the sql."); - } - if (ctx.inClause() != null) { - return parseInOperator(ctx.inClause(), path); - } else { - return parseBasicFunctionOperator(ctx, path); + + + private void parseAlterClause(AlterClauseContext ctx, AlterTimeSeriesOperator alterTimeSeriesOperator) { + Map<String, String> alterMap = new HashMap<>(); + // rename + if (ctx.RENAME() != null) { + alterTimeSeriesOperator.setAlterType(AlterType.RENAME); + alterMap.put(ctx.beforeName.getText(), ctx.currentName.getText()); + } else if (ctx.SET() != null) { + // set + alterTimeSeriesOperator.setAlterType(AlterType.SET); + setMap(ctx, alterMap); + } else if (ctx.DROP() != null) { + // drop + alterTimeSeriesOperator.setAlterType(AlterType.DROP); + for (TerminalNode dropId : ctx.ID()) { + alterMap.put(dropId.getText(), null); } + } else if (ctx.TAGS() != null) { + // add tag + alterTimeSeriesOperator.setAlterType(AlterType.ADD_TAGS); + setMap(ctx, alterMap); + } else if (ctx.ATTRIBUTES() != null) { + // add attribute + alterTimeSeriesOperator.setAlterType(AlterType.ADD_ATTRIBUTES); + setMap(ctx, alterMap); + } else { + // upsert + alterTimeSeriesOperator.setAlterType(AlterType.UPSERT); } + alterTimeSeriesOperator.setAlterMap(alterMap); } - private FilterOperator parseInOperator(InClauseContext ctx, PartialPath path) { - Set<String> values = new HashSet<>(); - boolean not = ctx.OPERATOR_NOT() != null; - for (ConstantContext constant : ctx.constant()) { - if (constant.dateExpression() != null) { - if (!path.equals(TIME_PATH)) { - throw new SQLParserException(path.getFullPath(), "Date can only be used to time"); + private void setMap(SqlBaseParser.AlterClauseContext ctx, Map<String, String> alterMap) { + List<PropertyContext> tagsList = ctx.property(); + if (ctx.property(0) != null) { + for (PropertyContext property : tagsList) { + String value; + if (property.propertyValue().stringLiteral() != null) { + value = removeStringQuote(property.propertyValue().getText()); + } else { + value = property.propertyValue().getText(); } - values.add(Long.toString(parseDateExpression(constant.dateExpression()))); - } else { - values.add(constant.getText()); + alterMap.put(property.ID().getText(), value); } } - return new InOperator(ctx.OPERATOR_IN().getSymbol().getType(), path, not, values); } - private FilterOperator parseBasicFunctionOperator(PredicateContext ctx, PartialPath path) { - BasicFunctionOperator basic; - if (ctx.constant().dateExpression() != null) { - if (!path.equals(TIME_PATH)) { - throw new SQLParserException(path.getFullPath(), "Date can only be used to time"); - } - basic = new BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path, - Long.toString(parseDateExpression(ctx.constant().dateExpression()))); + private String removeStringQuote(String src) { + if (src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'') { + return src.substring(1, src.length() - 1); + } else if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') { + return src.substring(1, src.length() - 1); } else { - basic = new BasicFunctionOperator(ctx.comparisonOperator().type.getType(), path, - ctx.constant().getText()); + throw new SQLParserException("error format for string with quote:" + src); } - return basic; } - private PartialPath parseSuffixPath(SuffixPathContext ctx) { + private PartialPath parsePrefixPath(PrefixPathContext ctx) { List<NodeNameContext> nodeNames = ctx.nodeName(); - String[] path = new String[nodeNames.size()]; + String[] path = new String[nodeNames.size() + 1]; + path[0] = ctx.ROOT().getText(); for (int i = 0; i < nodeNames.size(); i++) { - path[i] = nodeNames.get(i).getText(); + path[i + 1] = nodeNames.get(i).getText(); } return new PartialPath(path); } - /** - * parse time expression, which is addition and subtraction expression of duration time, now() or - * DataTimeFormat time. <p> eg. now() + 1d - 2h </p> - */ - private Long parseDateExpression(DateExpressionContext ctx) { - long time; - time = parseTimeFormat(ctx.getChild(0).getText()); - for (int i = 1; i < ctx.getChildCount(); i = i + 2) { - if (ctx.getChild(i).getText().equals("+")) { - time += parseDuration(ctx.getChild(i + 1).getText()); - } else { - time -= parseDuration(ctx.getChild(i + 1).getText()); + public void parseAttributeClauses(AttributeClausesContext ctx, CreateTimeSeriesOperator createTimeSeriesOperator) { + final String dataType = ctx.dataType().getChild(0).getText().toUpperCase(); + final TSDataType tsDataType = TSDataType.valueOf(dataType); + createTimeSeriesOperator.setDataType(tsDataType); + + final IoTDBDescriptor ioTDBDescriptor = IoTDBDescriptor.getInstance(); + TSEncoding encoding = ioTDBDescriptor.getDefualtEncodingByType(tsDataType); + if (Objects.nonNull(ctx.encoding())) { + String encodingString = ctx.encoding().getChild(0).getText().toUpperCase(); + encoding = TSEncoding.valueOf(encodingString); + } + createTimeSeriesOperator.setEncoding(encoding); + + CompressionType compressor; + List<PropertyContext> properties = ctx.property(); + if (ctx.compressor() != null) { + compressor = CompressionType.valueOf(ctx.compressor().getText().toUpperCase()); + } else { + compressor = TSFileDescriptor.getInstance().getConfig().getCompressor(); + } + Map<String, String> props = null; + if (ctx.property(0) != null) { + props = new HashMap<>(properties.size()); + for (PropertyContext property : properties) { + props.put(property.ID().getText().toLowerCase(), + property.propertyValue().getText().toLowerCase()); } } - return time; + createTimeSeriesOperator.setCompressor(compressor); + createTimeSeriesOperator.setProps(props); + } + + private PartialPath parseFullPath(FullPathContext ctx) { + List<NodeNameWithoutStarContext> nodeNamesWithoutStar = ctx.nodeNameWithoutStar(); + String[] path = new String[nodeNamesWithoutStar.size() + 1]; + int i = 0; + if (ctx.ROOT() != null) { + path[0] = ctx.ROOT().getText(); + } + for (NodeNameWithoutStarContext nodeNameWithoutStar : nodeNamesWithoutStar) { + i++; + path[i] = nodeNameWithoutStar.getText(); + } + return new PartialPath(path); } /** * function for parsing time format. */ - long parseTimeFormat(String timestampStr) throws SQLParserException { + public long parseTimeFormat(String timestampStr) throws SQLParserException { if (timestampStr == null || timestampStr.trim().equals("")) { throw new SQLParserException("input timestamp cannot be empty"); } @@ -1631,85 +1376,4 @@ public class LogicalGenerator extends SqlBaseBaseListener { + "refer to user document for more info.", timestampStr)); } } - - /** - * for delete command, time should only have an end time. - * - * @param operator delete logical plan - */ - private Pair<Long, Long> parseDeleteTimeInterval(DeleteDataOperator operator) { - FilterOperator filterOperator = operator.getFilterOperator(); - if (!filterOperator.isLeaf() && filterOperator.getTokenIntType() != SQLConstant.KW_AND) { - throw new SQLParserException( - DELETE_RANGE_ERROR_MSG); - } - - if (filterOperator.isLeaf()) { - return calcOperatorInterval(filterOperator); - } - - List<FilterOperator> children = filterOperator.getChildren(); - FilterOperator lOperator = children.get(0); - FilterOperator rOperator = children.get(1); - if (!lOperator.isLeaf() || !rOperator.isLeaf()) { - throw new SQLParserException( - DELETE_RANGE_ERROR_MSG); - } - - Pair<Long, Long> leftOpInterval = calcOperatorInterval(lOperator); - Pair<Long, Long> rightOpInterval = calcOperatorInterval(rOperator); - Pair<Long, Long> parsedInterval = new Pair<>( - Math.max(leftOpInterval.left, rightOpInterval.left), - Math.min(leftOpInterval.right, rightOpInterval.right)); - if (parsedInterval.left > parsedInterval.right) { - throw new SQLParserException( - "Invalid delete range: [" + parsedInterval.left + ", " + parsedInterval.right + "]"); - } - return parsedInterval; - } - - private Pair<Long, Long> calcOperatorInterval(FilterOperator filterOperator) { - long time = Long.parseLong(((BasicFunctionOperator) filterOperator).getValue()); - switch (filterOperator.getTokenIntType()) { - case SQLConstant.LESSTHAN: - return new Pair<>(Long.MIN_VALUE, time - 1); - case SQLConstant.LESSTHANOREQUALTO: - return new Pair<>(Long.MIN_VALUE, time); - case SQLConstant.GREATERTHAN: - return new Pair<>(time + 1, Long.MAX_VALUE); - case SQLConstant.GREATERTHANOREQUALTO: - return new Pair<>(time, Long.MAX_VALUE); - case SQLConstant.EQUAL: - return new Pair<>(time, time); - default: - throw new SQLParserException( - DELETE_RANGE_ERROR_MSG); - } - } - - @Override - public void enterShowMergeStatus(ShowMergeStatusContext ctx) { - super.enterShowMergeStatus(ctx); - initializedOperator = new ShowMergeStatusOperator(SQLConstant.TOK_SHOW_MERGE_STATUS); - } - - @Override - public void enterDeletePartition(DeletePartitionContext ctx) { - super.enterDeletePartition(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); - initializedOperator = deletePartitionOperator; - } - - @Override - public void enterCreateSnapshot(CreateSnapshotContext ctx) { - super.enterCreateSnapshot(ctx); - initializedOperator = new CreateSnapshotOperator(SQLConstant.TOK_CREATE_SCHEMA_SNAPSHOT); - } } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/ParseDriver.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/ParseDriver.java index 89b05e6..37b9467 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/ParseDriver.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/ParseDriver.java @@ -25,29 +25,29 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.misc.ParseCancellationException; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.apache.iotdb.db.qp.logical.Operator; +import org.apache.iotdb.db.qp.sql.IoTDBSqlVisitor; +import org.apache.iotdb.db.qp.sql.SqlBaseLexer; +import org.apache.iotdb.db.qp.sql.SqlBaseParser; /** * ParseDriver. * */ public class ParseDriver { - private ParseTreeWalker walker; - public ParseDriver() { - walker = new ParseTreeWalker(); - } + public ParseDriver() { } public Operator parse(String sql, ZoneId zoneId) throws ParseCancellationException { - LogicalGenerator logicalGenerator = new LogicalGenerator(zoneId); + IoTDBSqlVisitor ioTDBSqlVisitor = new IoTDBSqlVisitor(); + ioTDBSqlVisitor.setZoneId(zoneId); CharStream charStream1 = CharStreams.fromString(sql); SqlBaseLexer lexer1 = new SqlBaseLexer(charStream1); CommonTokenStream tokens1 = new CommonTokenStream(lexer1); SqlBaseParser parser1 = new SqlBaseParser(tokens1); parser1.getInterpreter().setPredictionMode(PredictionMode.SLL); parser1.removeErrorListeners(); - parser1.addErrorListener(LogicalGeneratorError.INSTANCE); + parser1.addErrorListener(SQLParseError.INSTANCE); ParseTree tree; try { tree = parser1.singleStatement(); // STAGE 1 @@ -59,11 +59,10 @@ public class ParseDriver { SqlBaseParser parser2 = new SqlBaseParser(tokens2); parser2.getInterpreter().setPredictionMode(PredictionMode.LL); parser2.removeErrorListeners(); - parser2.addErrorListener(LogicalGeneratorError.INSTANCE); + parser2.addErrorListener(SQLParseError.INSTANCE); tree = parser2.singleStatement(); // STAGE 2 // if we parse ok, it's LL not SLL } - walker.walk(logicalGenerator, tree); - return logicalGenerator.getLogicalPlan(); + return ioTDBSqlVisitor.visit(tree); } } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorError.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/SQLParseError.java similarity index 89% rename from server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorError.java rename to server/src/main/java/org/apache/iotdb/db/qp/strategy/SQLParseError.java index 69cd382..85c0e78 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorError.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/SQLParseError.java @@ -23,9 +23,9 @@ import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.misc.ParseCancellationException; -public class LogicalGeneratorError extends BaseErrorListener { +public class SQLParseError extends BaseErrorListener { - public static final LogicalGeneratorError INSTANCE = new LogicalGeneratorError(); + public static final SQLParseError INSTANCE = new SQLParseError(); @Override public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { diff --git a/server/src/test/java/org/apache/iotdb/db/sql/DatetimeQueryDataSetUtilsTest.java b/server/src/test/java/org/apache/iotdb/db/qp/sql/DatetimeQueryDataSetUtilsTest.java similarity index 99% rename from server/src/test/java/org/apache/iotdb/db/sql/DatetimeQueryDataSetUtilsTest.java rename to server/src/test/java/org/apache/iotdb/db/qp/sql/DatetimeQueryDataSetUtilsTest.java index c3043e3..1052f45 100644 --- a/server/src/test/java/org/apache/iotdb/db/sql/DatetimeQueryDataSetUtilsTest.java +++ b/server/src/test/java/org/apache/iotdb/db/qp/sql/DatetimeQueryDataSetUtilsTest.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.sql; +package org.apache.iotdb.db.qp.sql; import static org.junit.Assert.assertEquals; diff --git a/server/src/test/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorTest.java b/server/src/test/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorTest.java index c19a69c..cbf11e2 100644 --- a/server/src/test/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorTest.java +++ b/server/src/test/java/org/apache/iotdb/db/qp/strategy/LogicalGeneratorTest.java @@ -28,17 +28,19 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.exception.query.LogicalOperatorException; import org.apache.iotdb.db.exception.runtime.SQLParserException; import org.apache.iotdb.db.qp.constant.SQLConstant; +import org.apache.iotdb.db.qp.sql.IoTDBSqlVisitor; import org.junit.After; import org.junit.Before; import org.junit.Test; public class LogicalGeneratorTest { - LogicalGenerator generator; + IoTDBSqlVisitor visitor; @Before public void setUp() throws Exception { - generator = new LogicalGenerator(ZonedDateTime.now().getOffset()); + visitor = new IoTDBSqlVisitor(); + visitor.setZoneId(ZonedDateTime.now().getOffset()); } @After @@ -46,8 +48,8 @@ public class LogicalGeneratorTest { } @Test - public void testParseTimeFormatNow() throws LogicalOperatorException { - long now = generator.parseTimeFormat(SQLConstant.NOW_FUNC); + public void testParseTimeFormatNow() { + long now = visitor.parseTimeFormat(SQLConstant.NOW_FUNC); for (int i = 0; i <= 12; i++) { ZoneOffset offset1, offset2; if (i < 10) { @@ -68,18 +70,18 @@ public class LogicalGeneratorTest { } @Test - public void testParseTimeFormatNowPrecision() throws LogicalOperatorException { + public void testParseTimeFormatNowPrecision() { String timePrecision = IoTDBDescriptor.getInstance().getConfig().getTimestampPrecision(); IoTDBDescriptor.getInstance().getConfig().setTimestampPrecision("ms"); - long now_ms = generator.parseTimeFormat(SQLConstant.NOW_FUNC); + long now_ms = visitor.parseTimeFormat(SQLConstant.NOW_FUNC); String ms_str = String.valueOf(now_ms); IoTDBDescriptor.getInstance().getConfig().setTimestampPrecision("us"); - long now_us = generator.parseTimeFormat(SQLConstant.NOW_FUNC); + long now_us = visitor.parseTimeFormat(SQLConstant.NOW_FUNC); String us_str = String.valueOf(now_us); IoTDBDescriptor.getInstance().getConfig().setTimestampPrecision("ns"); - long now_ns = generator.parseTimeFormat(SQLConstant.NOW_FUNC); + long now_ns = visitor.parseTimeFormat(SQLConstant.NOW_FUNC); String ns_str = String.valueOf(now_ns); assertEquals(ms_str.length() + 3, (us_str).length()); @@ -88,12 +90,12 @@ public class LogicalGeneratorTest { } @Test(expected = SQLParserException.class) - public void testParseTimeFormatFail1() throws LogicalOperatorException { - generator.parseTimeFormat(null); + public void testParseTimeFormatFail1() { + visitor.parseTimeFormat(null); } @Test(expected = SQLParserException.class) - public void testParseTimeFormatFail2() throws LogicalOperatorException { - generator.parseTimeFormat(""); + public void testParseTimeFormatFail2() { + visitor.parseTimeFormat(""); } }
