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

jackietien pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/ty/TableModelGrammar by this 
push:
     new 625269b8a5b Support for group by time sql paser
625269b8a5b is described below

commit 625269b8a5bb3e3f3d5cdb82fcb642a7c3c4e9a2
Author: Jackie Tien <[email protected]>
AuthorDate: Tue Jun 18 19:37:24 2024 +0800

    Support for group by time sql paser
---
 .../relational/it/schema/IoTDBDatabaseIT.java      |  37 ++---
 .../protocol/thrift/impl/ClientRPCServiceImpl.java |   2 +-
 .../db/queryengine/plan/parser/ASTVisitor.java     |   8 +-
 .../plan/relational/metadata/MetadataUtil.java     |   2 +-
 .../plan/relational/sql/ast/AstVisitor.java        |   4 +
 .../plan/relational/sql/ast/GroupByTime.java       | 145 ++++++++++++++++
 .../plan/relational/sql/ast/SimpleGroupBy.java     |   2 +-
 .../sql/ast/{SimpleGroupBy.java => TimeRange.java} |  74 +++++----
 .../plan/relational/sql/parser/AstBuilder.java     | 182 ++++++++++++++-------
 .../plan/relational/sql/parser/SqlParser.java      |  52 +++---
 .../relational/sql/util/ReservedIdentifiers.java   |   3 +-
 .../org/apache/iotdb/db/utils/DateTimeUtils.java   |  79 ++++++---
 .../plan/relational/analyzer/AnalyzerTest.java     |   2 +-
 .../db/relational/grammar/sql/RelationalSql.g4     |  13 +-
 14 files changed, 432 insertions(+), 173 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
index cb02608e424..d2450039a70 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
@@ -117,42 +117,39 @@ public class IoTDBDatabaseIT {
       // create with strange name
       try {
         statement.execute("create database 1test");
-        fail("create database 1test shouldn't succeed because test1 doesn't 
exist");
+        fail(
+            "create database 1test shouldn't succeed because 1test is not a 
legal identifier; identifiers must not start with a digit; surround the 
identifier with double quotes");
       } catch (SQLException e) {
-        assertTrue(
-            e.getMessage(),
-            e.getMessage()
-                .endsWith(
-                    "identifiers must not start with a digit; surround the 
identifier with double quotes"));
+        assertTrue(e.getMessage(), e.getMessage().contains("mismatched input 
'1'"));
       }
 
       statement.execute("create database \"1test\"");
       statement.execute("use \"1test\"");
       statement.execute("drop database \"1test\"");
 
-      //      try {
-      //        statement.execute("create database 1");
-      //        fail("create database 1test shouldn't succeed because test1 
doesn't exist");
-      //      } catch (SQLException e) {
-      //        // TODO add error msg assert
-      //      }
+      try {
+        statement.execute("create database 1");
+        fail("create database 1 shouldn't succeed because 1 is not a legal 
identifier");
+      } catch (SQLException e) {
+        assertTrue(e.getMessage(), e.getMessage().contains("mismatched input 
'1'"));
+      }
       //
       //      // TODO fix it, should succeed
       //      statement.execute("create database \"1\"");
       //      statement.execute("use \"1\"");
       //      statement.execute("drop database \"1\"");
       //
-      //      try {
-      //        statement.execute("create database a.b");
-      //        fail("create database 1test shouldn't succeed because test1 
doesn't exist");
-      //      } catch (SQLException e) {
-      //        // TODO add error msg assert
-      //      }
+      try {
+        statement.execute("create database a.b");
+        fail("create database a.b shouldn't succeed because a.b is not a legal 
identifier");
+      } catch (SQLException e) {
+        assertTrue(e.getMessage(), e.getMessage().contains("mismatched input 
'.'"));
+      }
       //
       //      // TODO fix it, should succeed
-      //      statement.execute("create database \"a.b\"");
+      statement.execute("create database \"a.b\"");
       //      statement.execute("use \"a.b\"");
-      //      statement.execute("drop database \"a.b\"");
+      statement.execute("drop database \"a.b\"");
 
     } catch (SQLException e) {
       e.printStackTrace();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
index 77bb797ba50..136ba340e44 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
@@ -337,7 +337,7 @@ public class ClientRPCServiceImpl implements 
IClientRPCServiceWithHandler {
                 req.getTimeout());
       } else {
         org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement s =
-            relationSqlParser.createStatement(statement);
+            relationSqlParser.createStatement(statement, 
clientSession.getZoneId());
 
         if (s == null) {
           return RpcUtils.getTSExecuteStatementResp(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
index db6ae15eed8..34fb4814fdc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
@@ -2158,8 +2158,8 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
     }
   }
 
-  public long parseDateTimeFormat(String timestampStr, long currentTime) {
-    if (timestampStr == null || "".equals(timestampStr.trim())) {
+  public static long parseDateTimeFormat(String timestampStr, long 
currentTime, ZoneId zoneId) {
+    if (timestampStr == null || timestampStr.trim().isEmpty()) {
       throw new SemanticException("input timestamp cannot be empty");
     }
     if (timestampStr.equalsIgnoreCase(SqlConstant.NOW_FUNC)) {
@@ -3138,7 +3138,7 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
 
   private Long parseDateExpression(IoTDBSqlParser.DateExpressionContext ctx, 
long currentTime) {
     long time;
-    time = parseDateTimeFormat(ctx.getChild(0).getText(), currentTime);
+    time = parseDateTimeFormat(ctx.getChild(0).getText(), currentTime, zoneId);
     for (int i = 1; i < ctx.getChildCount(); i = i + 2) {
       if ("+".equals(ctx.getChild(i).getText())) {
         time += DateTimeUtils.convertDurationStrToLong(time, ctx.getChild(i + 
1).getText(), false);
@@ -3163,7 +3163,7 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
     } else if (ctx.dateExpression() != null) {
       return parseDateExpression(ctx.dateExpression(), currentTime);
     } else {
-      return parseDateTimeFormat(ctx.datetimeLiteral().getText(), currentTime);
+      return parseDateTimeFormat(ctx.datetimeLiteral().getText(), currentTime, 
zoneId);
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
index d625807b57e..b97141817b0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
@@ -84,7 +84,7 @@ public class MetadataUtil {
                 .orElseThrow(
                     () ->
                         new SemanticException(
-                            "Catalog must be specified when session catalog is 
not set"));
+                            "Database must be specified when session database 
is not set"));
 
     return new QualifiedObjectName(databaseName, objectName);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
index 26cbe300c2a..98b9f92f341 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
@@ -391,6 +391,10 @@ public abstract class AstVisitor<R, C> {
     return visitNode(node, context);
   }
 
+  protected R visitGroupByTime(GroupByTime node, C context) {
+    return visitGroupingElement(node, context);
+  }
+
   protected R visitGroupingSets(GroupingSets node, C context) {
     return visitGroupingElement(node, context);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/GroupByTime.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/GroupByTime.java
new file mode 100644
index 00000000000..2d4068e6c27
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/GroupByTime.java
@@ -0,0 +1,145 @@
+/*
+ * 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.queryengine.plan.relational.sql.ast;
+
+import org.apache.tsfile.utils.TimeDuration;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+public class GroupByTime extends GroupingElement {
+
+  // [startTime, endTime)
+  private final long startTime;
+  private final long endTime;
+  // time interval
+  private final TimeDuration interval;
+  // sliding step
+  private final TimeDuration slidingStep;
+  // if it is left close and right open interval
+  private final boolean leftCRightO;
+
+  public GroupByTime(
+      long startTime,
+      long endTime,
+      TimeDuration interval,
+      TimeDuration slidingStep,
+      boolean leftCRightO) {
+    super(null);
+    this.startTime = startTime;
+    this.endTime = endTime;
+    this.interval = interval;
+    this.slidingStep = slidingStep;
+    this.leftCRightO = leftCRightO;
+  }
+
+  public GroupByTime(
+      NodeLocation location,
+      long startTime,
+      long endTime,
+      TimeDuration interval,
+      TimeDuration slidingStep,
+      boolean leftCRightO) {
+    super(location);
+    this.startTime = startTime;
+    this.endTime = endTime;
+    this.interval = interval;
+    this.slidingStep = slidingStep;
+    this.leftCRightO = leftCRightO;
+  }
+
+  @Override
+  public List<Expression> getExpressions() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  protected <R, C> R accept(AstVisitor<R, C> visitor, C context) {
+    return visitor.visitGroupByTime(this, context);
+  }
+
+  @Override
+  public List<? extends Node> getChildren() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    GroupByTime that = (GroupByTime) o;
+    return startTime == that.startTime
+        && endTime == that.endTime
+        && leftCRightO == that.leftCRightO
+        && Objects.equals(interval, that.interval)
+        && Objects.equals(slidingStep, that.slidingStep);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(startTime, endTime, interval, slidingStep, 
leftCRightO);
+  }
+
+  @Override
+  public String toString() {
+    return "GroupByTime{"
+        + "startTime="
+        + startTime
+        + ", endTime="
+        + endTime
+        + ", interval="
+        + interval
+        + ", slidingStep="
+        + slidingStep
+        + ", leftCRightO="
+        + leftCRightO
+        + '}';
+  }
+
+  @Override
+  public boolean shallowEquals(Node other) {
+    return sameClass(this, other);
+  }
+
+  public long getStartTime() {
+    return startTime;
+  }
+
+  public long getEndTime() {
+    return endTime;
+  }
+
+  public TimeDuration getInterval() {
+    return interval;
+  }
+
+  public TimeDuration getSlidingStep() {
+    return slidingStep;
+  }
+
+  public boolean isLeftCRightO() {
+    return leftCRightO;
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
index 88193960f7d..88b80a6072b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
@@ -57,7 +57,7 @@ public final class SimpleGroupBy extends GroupingElement {
 
   @Override
   public List<? extends Node> getChildren() {
-    return columns;
+    return getExpressions();
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeRange.java
similarity index 50%
copy from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
copy to 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeRange.java
index 88193960f7d..c1fe213ff14 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/SimpleGroupBy.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeRange.java
@@ -19,45 +19,35 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.sql.ast;
 
-import com.google.common.collect.ImmutableList;
-
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static java.util.Objects.requireNonNull;
-
-public final class SimpleGroupBy extends GroupingElement {
+public class TimeRange extends Node {
 
-  private final List<Expression> columns;
+  // [startTime, endTime)
+  private final long startTime;
+  private final long endTime;
+  // if it is left close and right open interval
+  private final boolean leftCRightO;
 
-  public SimpleGroupBy(List<Expression> simpleGroupByExpressions) {
+  public TimeRange(long startTime, long endTime, boolean leftCRightO) {
     super(null);
-    this.columns =
-        ImmutableList.copyOf(
-            requireNonNull(simpleGroupByExpressions, "simpleGroupByExpressions 
is null"));
+    this.startTime = startTime;
+    this.endTime = endTime;
+    this.leftCRightO = leftCRightO;
   }
 
-  public SimpleGroupBy(NodeLocation location, List<Expression> 
simpleGroupByExpressions) {
-    super(requireNonNull(location, "location is null"));
-    this.columns =
-        ImmutableList.copyOf(
-            requireNonNull(simpleGroupByExpressions, "simpleGroupByExpressions 
is null"));
-  }
-
-  @Override
-  public List<Expression> getExpressions() {
-    return columns;
-  }
-
-  @Override
-  protected <R, C> R accept(AstVisitor<R, C> visitor, C context) {
-    return visitor.visitSimpleGroupBy(this, context);
+  public TimeRange(NodeLocation location, long startTime, long endTime, 
boolean leftCRightO) {
+    super(location);
+    this.startTime = startTime;
+    this.endTime = endTime;
+    this.leftCRightO = leftCRightO;
   }
 
   @Override
   public List<? extends Node> getChildren() {
-    return columns;
+    return Collections.emptyList();
   }
 
   @Override
@@ -68,22 +58,38 @@ public final class SimpleGroupBy extends GroupingElement {
     if (o == null || getClass() != o.getClass()) {
       return false;
     }
-    SimpleGroupBy that = (SimpleGroupBy) o;
-    return Objects.equals(columns, that.columns);
+    TimeRange timeRange = (TimeRange) o;
+    return startTime == timeRange.startTime
+        && endTime == timeRange.endTime
+        && leftCRightO == timeRange.leftCRightO;
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(columns);
+    return Objects.hash(startTime, endTime, leftCRightO);
   }
 
   @Override
   public String toString() {
-    return toStringHelper(this).add("columns", columns).toString();
+    return "TimeRange{"
+        + "startTime="
+        + startTime
+        + ", endTime="
+        + endTime
+        + ", leftCRightO="
+        + leftCRightO
+        + '}';
   }
 
-  @Override
-  public boolean shallowEquals(Node other) {
-    return sameClass(this, other);
+  public long getStartTime() {
+    return startTime;
+  }
+
+  public long getEndTime() {
+    return endTime;
+  }
+
+  public boolean isLeftCRightO() {
+    return leftCRightO;
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 52fa55f87be..ef2a3dfe5e8 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -20,6 +20,8 @@
 package org.apache.iotdb.db.queryengine.plan.relational.sql.parser;
 
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
+import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AliasedRelation;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns;
@@ -56,6 +58,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericDataType;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupBy;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupByTime;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingElement;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Identifier;
@@ -110,6 +113,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StringLiteral;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SubqueryExpression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Table;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableSubquery;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeRange;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Trim;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TypeParameter;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Union;
@@ -123,15 +127,18 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.WithQuery;
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlBaseVisitor;
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlLexer;
 import org.apache.iotdb.db.relational.grammar.sql.RelationalSqlParser;
+import org.apache.iotdb.db.utils.DateTimeUtils;
 
 import com.google.common.collect.ImmutableList;
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.Token;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
+import org.apache.tsfile.utils.TimeDuration;
 
 import javax.annotation.Nullable;
 
+import java.time.ZoneId;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Deque;
@@ -147,6 +154,7 @@ import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.ID;
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.MEASUREMENT;
 import static 
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory.TIME;
+import static 
org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor.parseDateTimeFormat;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets.Type.CUBE;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets.Type.EXPLICIT;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GroupingSets.Type.ROLLUP;
@@ -157,8 +165,11 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
 
   @Nullable private final NodeLocation baseLocation;
 
-  AstBuilder(@Nullable NodeLocation baseLocation) {
+  private final ZoneId zoneId;
+
+  AstBuilder(@Nullable NodeLocation baseLocation, ZoneId zoneId) {
     this.baseLocation = baseLocation;
+    this.zoneId = zoneId;
   }
 
   @Override
@@ -685,6 +696,115 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
         visit(ctx.groupingElement(), GroupingElement.class));
   }
 
+  @Override
+  public Node visitTimenGrouping(RelationalSqlParser.TimenGroupingContext ctx) 
{
+    long startTime = 0;
+    long endTime = 0;
+    boolean leftCRightO = true;
+    if (ctx.timeRange() != null) {
+      TimeRange timeRange = (TimeRange) visit(ctx.timeRange());
+      startTime = timeRange.getStartTime();
+      endTime = timeRange.getEndTime();
+      leftCRightO = timeRange.isLeftCRightO();
+    }
+    // Parse time interval
+    TimeDuration interval = 
DateTimeUtils.constructTimeDuration(ctx.windowInterval.getText());
+    TimeDuration slidingStep = interval;
+    if (ctx.windowStep != null) {
+      slidingStep = 
DateTimeUtils.constructTimeDuration(ctx.windowStep.getText());
+    }
+
+    if (interval.monthDuration <= 0 && interval.nonMonthDuration <= 0) {
+      throw new SemanticException(
+          "The second parameter time interval should be a positive integer.");
+    }
+
+    if (slidingStep.monthDuration <= 0 && slidingStep.nonMonthDuration <= 0) {
+      throw new SemanticException(
+          "The third parameter time slidingStep should be a positive 
integer.");
+    }
+    return new GroupByTime(
+        getLocation(ctx), startTime, endTime, interval, slidingStep, 
leftCRightO);
+  }
+
+  @Override
+  public Node 
visitLeftClosedRightOpen(RelationalSqlParser.LeftClosedRightOpenContext ctx) {
+    return getTimeRange(ctx.timeValue(0), ctx.timeValue(1), true);
+  }
+
+  @Override
+  public Node 
visitLeftOpenRightClosed(RelationalSqlParser.LeftOpenRightClosedContext ctx) {
+    return getTimeRange(ctx.timeValue(0), ctx.timeValue(1), false);
+  }
+
+  private TimeRange getTimeRange(
+      RelationalSqlParser.TimeValueContext left,
+      RelationalSqlParser.TimeValueContext right,
+      boolean leftCRightO) {
+    long currentTime = CommonDateTimeUtils.currentTime();
+    long startTime = parseTimeValue(left, currentTime);
+    long endTime = parseTimeValue(right, currentTime);
+    if (startTime >= endTime) {
+      throw new SemanticException("Start time should be smaller than endTime 
in GroupBy");
+    }
+    return new TimeRange(startTime, endTime, leftCRightO);
+  }
+
+  private long parseTimeValue(RelationalSqlParser.TimeValueContext ctx, long 
currentTime) {
+    if (ctx.INTEGER_VALUE() != null) {
+      try {
+        if (ctx.MINUS() != null) {
+          return -Long.parseLong(ctx.INTEGER_VALUE().getText());
+        }
+        return Long.parseLong(ctx.INTEGER_VALUE().getText());
+      } catch (NumberFormatException e) {
+        throw new SemanticException(
+            String.format("Can not parse %s to long value", 
ctx.INTEGER_VALUE().getText()));
+      }
+    } else {
+      return parseDateExpression(ctx.dateExpression(), currentTime);
+    }
+  }
+
+  private Long parseDateExpression(
+      RelationalSqlParser.DateExpressionContext ctx, long currentTime) {
+    long time;
+    time = parseDateTimeFormat(ctx.getChild(0).getText(), currentTime, zoneId);
+    for (int i = 1; i < ctx.getChildCount(); i = i + 2) {
+      if ("+".equals(ctx.getChild(i).getText())) {
+        time += DateTimeUtils.convertDurationStrToLong(time, ctx.getChild(i + 
1).getText(), false);
+      } else {
+        time -= DateTimeUtils.convertDurationStrToLong(time, ctx.getChild(i + 
1).getText(), false);
+      }
+    }
+    return time;
+  }
+
+  @Override
+  public Node 
visitVariationGrouping(RelationalSqlParser.VariationGroupingContext ctx) {
+    return super.visitVariationGrouping(ctx);
+  }
+
+  @Override
+  public Node 
visitConditionGrouping(RelationalSqlParser.ConditionGroupingContext ctx) {
+    return super.visitConditionGrouping(ctx);
+  }
+
+  @Override
+  public Node visitSessionGrouping(RelationalSqlParser.SessionGroupingContext 
ctx) {
+    return super.visitSessionGrouping(ctx);
+  }
+
+  @Override
+  public Node visitCountGrouping(RelationalSqlParser.CountGroupingContext ctx) 
{
+    return super.visitCountGrouping(ctx);
+  }
+
+  @Override
+  public Node visitKeepExpression(RelationalSqlParser.KeepExpressionContext 
ctx) {
+    return super.visitKeepExpression(ctx);
+  }
+
   @Override
   public Node 
visitSingleGroupingSet(RelationalSqlParser.SingleGroupingSetContext ctx) {
     return new SimpleGroupBy(
@@ -795,61 +915,6 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     return new Identifier(getLocation(ctx), identifier, true);
   }
 
-  @Override
-  public Node visitTimenGrouping(RelationalSqlParser.TimenGroupingContext ctx) 
{
-    return super.visitTimenGrouping(ctx);
-  }
-
-  @Override
-  public Node 
visitVariationGrouping(RelationalSqlParser.VariationGroupingContext ctx) {
-    return super.visitVariationGrouping(ctx);
-  }
-
-  @Override
-  public Node 
visitConditionGrouping(RelationalSqlParser.ConditionGroupingContext ctx) {
-    return super.visitConditionGrouping(ctx);
-  }
-
-  @Override
-  public Node visitSessionGrouping(RelationalSqlParser.SessionGroupingContext 
ctx) {
-    return super.visitSessionGrouping(ctx);
-  }
-
-  @Override
-  public Node visitCountGrouping(RelationalSqlParser.CountGroupingContext ctx) 
{
-    return super.visitCountGrouping(ctx);
-  }
-
-  @Override
-  public Node 
visitLeftClosedRightOpen(RelationalSqlParser.LeftClosedRightOpenContext ctx) {
-    return super.visitLeftClosedRightOpen(ctx);
-  }
-
-  @Override
-  public Node 
visitLeftOpenRightClosed(RelationalSqlParser.LeftOpenRightClosedContext ctx) {
-    return super.visitLeftOpenRightClosed(ctx);
-  }
-
-  @Override
-  public Node visitTimeValue(RelationalSqlParser.TimeValueContext ctx) {
-    return super.visitTimeValue(ctx);
-  }
-
-  @Override
-  public Node visitDateExpression(RelationalSqlParser.DateExpressionContext 
ctx) {
-    return super.visitDateExpression(ctx);
-  }
-
-  @Override
-  public Node visitDatetimeLiteral(RelationalSqlParser.DatetimeLiteralContext 
ctx) {
-    return super.visitDatetimeLiteral(ctx);
-  }
-
-  @Override
-  public Node visitKeepExpression(RelationalSqlParser.KeepExpressionContext 
ctx) {
-    return super.visitKeepExpression(ctx);
-  }
-
   // ***************** boolean expressions ******************
   @Override
   public Node visitLogicalNot(RelationalSqlParser.LogicalNotContext ctx) {
@@ -1403,11 +1468,6 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     return super.visitIntervalField(ctx);
   }
 
-  @Override
-  public Node visitTimeDuration(RelationalSqlParser.TimeDurationContext ctx) {
-    return super.visitTimeDuration(ctx);
-  }
-
   // ***************** arguments *****************
   @Override
   public Node visitGenericType(RelationalSqlParser.GenericTypeContext ctx) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
index c82e1f8a56f..b20fb829326 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/SqlParser.java
@@ -44,6 +44,7 @@ import org.antlr.v4.runtime.atn.PredictionMode;
 import org.antlr.v4.runtime.misc.Pair;
 import org.antlr.v4.runtime.tree.TerminalNode;
 
+import java.time.ZoneId;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
@@ -93,35 +94,43 @@ public class SqlParser {
     this.initializer = requireNonNull(initializer, "initializer is null");
   }
 
-  public Statement createStatement(String sql) {
-    return (Statement) invokeParser("statement", sql, 
RelationalSqlParser::singleStatement);
+  public Statement createStatement(String sql, ZoneId zoneId) {
+    return (Statement) invokeParser("statement", sql, 
RelationalSqlParser::singleStatement, zoneId);
   }
 
-  public Statement createStatement(String sql, NodeLocation location) {
+  public Statement createStatement(String sql, NodeLocation location, ZoneId 
zoneId) {
     return (Statement)
         invokeParser(
-            "statement", sql, Optional.ofNullable(location), 
RelationalSqlParser::singleStatement);
+            "statement",
+            sql,
+            Optional.ofNullable(location),
+            RelationalSqlParser::singleStatement,
+            zoneId);
   }
 
-  public Expression createExpression(String expression) {
+  public Expression createExpression(String expression, ZoneId zoneId) {
     return (Expression)
-        invokeParser("expression", expression, 
RelationalSqlParser::standaloneExpression);
+        invokeParser("expression", expression, 
RelationalSqlParser::standaloneExpression, zoneId);
   }
 
-  public DataType createType(String expression) {
-    return (DataType) invokeParser("type", expression, 
RelationalSqlParser::standaloneType);
+  public DataType createType(String expression, ZoneId zoneId) {
+    return (DataType) invokeParser("type", expression, 
RelationalSqlParser::standaloneType, zoneId);
   }
 
   private Node invokeParser(
-      String name, String sql, Function<RelationalSqlParser, 
ParserRuleContext> parseFunction) {
-    return invokeParser(name, sql, Optional.empty(), parseFunction);
+      String name,
+      String sql,
+      Function<RelationalSqlParser, ParserRuleContext> parseFunction,
+      ZoneId zoneId) {
+    return invokeParser(name, sql, Optional.empty(), parseFunction, zoneId);
   }
 
   private Node invokeParser(
       String name,
       String sql,
       Optional<NodeLocation> location,
-      Function<RelationalSqlParser, ParserRuleContext> parseFunction) {
+      Function<RelationalSqlParser, ParserRuleContext> parseFunction,
+      ZoneId zoneId) {
     try {
       RelationalSqlLexer lexer =
           new RelationalSqlLexer(new 
CaseInsensitiveStream(CharStreams.fromString(sql)));
@@ -178,7 +187,7 @@ public class SqlParser {
         throw e;
       }
 
-      return new AstBuilder(location.orElse(null)).visit(tree);
+      return new AstBuilder(location.orElse(null), zoneId).visit(tree);
     } catch (StackOverflowError e) {
       throw new ParsingException(name + " is too large (stack overflow while 
parsing)");
     }
@@ -215,15 +224,16 @@ public class SqlParser {
           token.getCharPositionInLine() + 1);
     }
 
-    @Override
-    public void exitDigitIdentifier(RelationalSqlParser.DigitIdentifierContext 
context) {
-      Token token = context.DIGIT_IDENTIFIER().getSymbol();
-      throw new ParsingException(
-          "identifiers must not start with a digit; surround the identifier 
with double quotes",
-          null,
-          token.getLine(),
-          token.getCharPositionInLine() + 1);
-    }
+    //    @Override
+    //    public void 
exitDigitIdentifier(RelationalSqlParser.DigitIdentifierContext context) {
+    //      Token token = context.DIGIT_IDENTIFIER().getSymbol();
+    //      throw new ParsingException(
+    //          "identifiers must not start with a digit; surround the 
identifier with double
+    // quotes",
+    //          null,
+    //          token.getLine(),
+    //          token.getCharPositionInLine() + 1);
+    //    }
 
     @Override
     public void exitNonReserved(RelationalSqlParser.NonReservedContext 
context) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ReservedIdentifiers.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ReservedIdentifiers.java
index d40f6880b9b..2fde6ee0d31 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ReservedIdentifiers.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ReservedIdentifiers.java
@@ -23,6 +23,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Identifier;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.parser.ParsingException;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
 
+import java.time.ZoneId;
 import java.util.Set;
 
 import static com.google.common.collect.ImmutableSet.toImmutableSet;
@@ -40,7 +41,7 @@ public final class ReservedIdentifiers {
 
   public static boolean reserved(String name) {
     try {
-      return !(PARSER.createExpression(name) instanceof Identifier);
+      return !(PARSER.createExpression(name, ZoneId.systemDefault()) 
instanceof Identifier);
     } catch (ParsingException ignored) {
       return true;
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DateTimeUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DateTimeUtils.java
index 1a3c394af7d..98e0a6f09aa 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DateTimeUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DateTimeUtils.java
@@ -61,12 +61,15 @@ public class DateTimeUtils {
   static {
     switch 
(CommonDescriptor.getInstance().getConfig().getTimestampPrecision()) {
       case "us":
+      case "microsecond":
         CAST_TIMESTAMP_TO_MS = timestamp -> timestamp / 1000;
         break;
       case "ns":
+      case "nanosecond":
         CAST_TIMESTAMP_TO_MS = timestamp -> timestamp / 1000000;
         break;
       case "ms":
+      case "millisecond":
       default:
         CAST_TIMESTAMP_TO_MS = timestamp -> timestamp;
         break;
@@ -501,7 +504,7 @@ public class DateTimeUtils {
     try {
       ZonedDateTime zonedDateTime = ZonedDateTime.parse(str, formatter);
       Instant instant = zonedDateTime.toInstant();
-      if ("us".equals(timestampPrecision)) {
+      if ("us".equals(timestampPrecision) || 
"microsecond".equals(timestampPrecision)) {
         if (instant.getEpochSecond() < 0 && instant.getNano() > 0) {
           // adjustment can reduce the loss of the division
           long millis = Math.multiplyExact(instant.getEpochSecond() + 1, 
1000_000L);
@@ -511,7 +514,7 @@ public class DateTimeUtils {
           long millis = Math.multiplyExact(instant.getEpochSecond(), 
1000_000L);
           return Math.addExact(millis, instant.getNano() / 1000);
         }
-      } else if ("ns".equals(timestampPrecision)) {
+      } else if ("ns".equals(timestampPrecision) || 
"nanosecond".equals(timestampPrecision)) {
         long millis = Math.multiplyExact(instant.getEpochSecond(), 
1000_000_000L);
         return Math.addExact(millis, instant.getNano());
       }
@@ -629,9 +632,11 @@ public class DateTimeUtils {
     long res = value;
     switch (durationUnit) {
       case y:
+      case year:
         res *= 365 * 86_400_000L;
         break;
       case mo:
+      case month:
         if (currentTime == -1) {
           res *= 30 * 86_400_000L;
         } else {
@@ -643,44 +648,55 @@ public class DateTimeUtils {
         }
         break;
       case w:
+      case week:
         res *= 7 * 86_400_000L;
         break;
       case d:
+      case day:
         res *= 86_400_000L;
         break;
       case h:
+      case hour:
         res *= 3_600_000L;
         break;
       case m:
+      case minute:
         res *= 60_000L;
         break;
       case s:
+      case second:
         res *= 1_000L;
         break;
       default:
         break;
     }
 
-    if ("us".equals(timestampPrecision)) {
-      if (unit.equals(DurationUnit.ns.toString())) {
+    if ("us".equals(timestampPrecision) || 
"microsecond".equals(timestampPrecision)) {
+      if (unit.equals(DurationUnit.ns.toString())
+          || unit.equals(DurationUnit.nanosecond.toString())) {
         return value / 1000;
-      } else if (unit.equals(DurationUnit.us.toString())) {
+      } else if (unit.equals(DurationUnit.us.toString())
+          || unit.equals(DurationUnit.microsecond.toString())) {
         return value;
       } else {
         return res * 1000;
       }
-    } else if ("ns".equals(timestampPrecision)) {
-      if (unit.equals(DurationUnit.ns.toString())) {
+    } else if ("ns".equals(timestampPrecision) || 
"nanosecond".equals(timestampPrecision)) {
+      if (unit.equals(DurationUnit.ns.toString())
+          || unit.equals(DurationUnit.nanosecond.toString())) {
         return value;
-      } else if (unit.equals(DurationUnit.us.toString())) {
+      } else if (unit.equals(DurationUnit.us.toString())
+          || unit.equals(DurationUnit.microsecond.toString())) {
         return value * 1000;
       } else {
         return res * 1000_000;
       }
     } else {
-      if (unit.equals(DurationUnit.ns.toString())) {
+      if (unit.equals(DurationUnit.ns.toString())
+          || unit.equals(DurationUnit.nanosecond.toString())) {
         return value / 1000_000;
-      } else if (unit.equals(DurationUnit.us.toString())) {
+      } else if (unit.equals(DurationUnit.us.toString())
+          || unit.equals(DurationUnit.microsecond.toString())) {
         return value / 1000;
       } else {
         return res;
@@ -689,9 +705,9 @@ public class DateTimeUtils {
   }
 
   public static TimeUnit timestampPrecisionStringToTimeUnit(String 
timestampPrecision) {
-    if ("us".equals(timestampPrecision)) {
+    if ("us".equals(timestampPrecision) || 
"microsecond".equals(timestampPrecision)) {
       return TimeUnit.MICROSECONDS;
-    } else if ("ns".equals(timestampPrecision)) {
+    } else if ("ns".equals(timestampPrecision) || 
"nanosecond".equals(timestampPrecision)) {
       return TimeUnit.NANOSECONDS;
     } else {
       return TimeUnit.MILLISECONDS;
@@ -706,9 +722,11 @@ public class DateTimeUtils {
   public static String convertLongToDate(long timestamp, String 
sourcePrecision) {
     switch (sourcePrecision) {
       case "ns":
+      case "nanosecond":
         timestamp /= 1000_000;
         break;
       case "us":
+      case "microsecond":
         timestamp /= 1000;
         break;
     }
@@ -726,30 +744,46 @@ public class DateTimeUtils {
 
   public enum DurationUnit {
     y,
+    year,
     mo,
+    month,
     w,
+    week,
     d,
+    day,
     h,
+    hour,
     m,
+    minute,
     s,
+    second,
     ms,
+    millisecond,
     us,
-    ns
+    microsecond,
+    ns,
+    nanosecond
   }
 
   public static TimeUnit toTimeUnit(String t) {
     switch (t) {
       case "h":
+      case "hour":
         return TimeUnit.HOURS;
       case "m":
+      case "minute":
         return TimeUnit.MINUTES;
       case "s":
+      case "second":
         return TimeUnit.SECONDS;
       case "ms":
+      case "millisecond":
         return TimeUnit.MILLISECONDS;
       case "u":
+      case "microsecond":
         return TimeUnit.MICROSECONDS;
       case "n":
+      case "nanosecond":
         return TimeUnit.NANOSECONDS;
       default:
         throw new IllegalArgumentException("time precision must be one of: 
h,m,s,ms,u,n");
@@ -781,30 +815,33 @@ public class DateTimeUtils {
     long temp = 0;
     long monthDuration = 0;
     long nonMonthDuration = 0;
-    for (int i = 0; i < duration.length(); i++) {
+    int i = 0;
+    for (; i < duration.length(); i++) {
       char ch = duration.charAt(i);
       if (Character.isDigit(ch)) {
         temp *= 10;
         temp += (ch - '0');
       } else {
-        String unit = String.valueOf(duration.charAt(i));
-        // This is to identify units with two letters.
-        if (i + 1 < duration.length() && !Character.isDigit(duration.charAt(i 
+ 1))) {
+        StringBuilder unit = new 
StringBuilder(String.valueOf(duration.charAt(i)));
+        i++;
+        // This is to identify units.
+        while (i < duration.length() && 
!Character.isDigit(duration.charAt(i))) {
+          unit.append(duration.charAt(i));
           i++;
-          unit += duration.charAt(i);
         }
-        if (unit.equals("y")) {
+        i--;
+        if ("y".contentEquals(unit) || "year".contentEquals(unit)) {
           monthDuration += temp * 12;
           temp = 0;
           continue;
         }
-        if (unit.equals("mo")) {
+        if ("mo".contentEquals(unit) || "month".contentEquals(unit)) {
           monthDuration += temp;
           temp = 0;
           continue;
         }
         nonMonthDuration +=
-            DateTimeUtils.convertDurationStrToLong(-1, temp, unit, 
currTimePrecision);
+            DateTimeUtils.convertDurationStrToLong(-1, temp, unit.toString(), 
currTimePrecision);
         temp = 0;
       }
     }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index 03608978707..335d838587e 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -485,7 +485,7 @@ public class AnalyzerTest {
   public static Analysis analyzeSQL(String sql, Metadata metadata) {
     try {
       SqlParser sqlParser = new SqlParser();
-      Statement statement = sqlParser.createStatement(sql);
+      Statement statement = sqlParser.createStatement(sql, 
ZoneId.systemDefault());
       SessionInfo session =
           new SessionInfo(
               0, "test", ZoneId.systemDefault(), "testdb", 
IClientSession.SqlDialect.TABLE);
diff --git 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 26cd32456e6..4e7d8ebff85 100644
--- 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++ 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -419,7 +419,7 @@ groupBy
     ;
 
 groupingElement
-    : TIME? '(' (timeRange ',')? windowInterval=timeDuration (',' 
windowStep=timeDuration)?')'     #timenGrouping
+    : TIME '(' (timeRange ',')? windowInterval=timeDuration (',' 
windowStep=timeDuration)?')'      #timenGrouping
     | VARIATION '(' expression (',' delta=number)? (',' propertyAssignments)? 
')'                  #variationGrouping
     | CONDITION '(' expression (',' keepExpression)? (',' 
propertyAssignments)? ')'                #conditionGrouping
     | SESSION '(' timeInterval=timeDuration ')'                                
                    #sessionGrouping
@@ -611,7 +611,7 @@ intervalField
     ;
 
 timeDuration
-    : (INTEGER_VALUE+ (intervalField))+
+    : (INTEGER_VALUE intervalField)+
     ;
 
 type
@@ -693,7 +693,6 @@ identifier
     | QUOTED_IDENTIFIER      #quotedIdentifier
     | nonReserved            #unquotedIdentifier
     | BACKQUOTED_IDENTIFIER  #backQuotedIdentifier
-    | DIGIT_IDENTIFIER       #digitIdentifier
     ;
 
 number
@@ -1133,9 +1132,9 @@ IDENTIFIER
     : (LETTER | '_') (LETTER | DIGIT | '_')*
     ;
 
-DIGIT_IDENTIFIER
-    : DIGIT (LETTER | DIGIT | '_')+
-    ;
+//DIGIT_IDENTIFIER
+//    : DIGIT (LETTER | DIGIT | '_')+
+//    ;
 
 QUOTED_IDENTIFIER
     : '"' ( ~'"' | '""' )* '"'
@@ -1204,4 +1203,4 @@ WS
 // when splitting statements with DelimiterLexer
 UNRECOGNIZED
     : .
-    ;
+    ;
\ No newline at end of file


Reply via email to