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

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


The following commit(s) were added to refs/heads/master by this push:
     new 608fa6c4fb1 delay monthly interval check to analyzer phase
608fa6c4fb1 is described below

commit 608fa6c4fb1a64a01c669eb9ddf2ca71f7919be7
Author: shizy <[email protected]>
AuthorDate: Thu Apr 16 17:41:59 2026 +0800

    delay monthly interval check to analyzer phase
---
 .../relational/analyzer/StatementAnalyzer.java     |   7 ++
 .../plan/relational/planner/IrTypeAnalyzer.java    |  13 +++
 .../relational/planner/LiteralInterpreter.java     |   7 ++
 .../plan/relational/sql/ast/AstVisitor.java        |   4 +
 .../relational/sql/ast/TableExpressionType.java    |   3 +-
 .../relational/sql/ast/TimeDurationLiteral.java    | 109 +++++++++++++++++++++
 .../plan/relational/sql/parser/AstBuilder.java     |  13 +--
 .../relational/sql/util/ExpressionFormatter.java   |   6 ++
 8 files changed, 151 insertions(+), 11 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index a438ef165ba..dade85d20b1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -176,6 +176,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionArgu
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionInvocation;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionTableArgument;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableSubquery;
+import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeDurationLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Trim;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Union;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Update;
@@ -5260,6 +5261,12 @@ public class StatementAnalyzer {
 
     private ArgumentAnalysis analyzeScalarArgument(
         Expression expression, ScalarParameterSpecification 
argumentSpecification) {
+      if (expression instanceof TimeDurationLiteral) {
+        if (((TimeDurationLiteral) expression).getValue().monthDuration != 0) {
+          throw new SemanticException("Setting monthly intervals is not 
supported.");
+        }
+      }
+
       // currently, only constant arguments are supported
       Object constantValue =
           evaluateConstantExpression(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java
index 442124b9b8d..aa03381659e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java
@@ -61,6 +61,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SearchedCaseExpre
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SimpleCaseExpression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StringLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SymbolReference;
+import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeDurationLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.WhenClause;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeCoercionUtils;
 
@@ -89,6 +90,7 @@ import static 
com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.ImmutableList.toImmutableList;
 import static java.util.Objects.requireNonNull;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignatureTranslator.toTypeSignature;
+import static org.apache.iotdb.db.utils.TimestampPrecisionUtils.currPrecision;
 import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN;
 import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
 import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
@@ -402,6 +404,17 @@ public class IrTypeAnalyzer {
       return setExpressionType(node, UNKNOWN);
     }
 
+    @Override
+    protected Type visitTimeDurationLiteral(TimeDurationLiteral node, Context 
context) {
+      long value = node.getValue().getTotalDuration(currPrecision);
+
+      if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
+        return setExpressionType(node, INT32);
+      }
+      // keep the original type
+      return setExpressionType(node, INT64);
+    }
+
     @Override
     protected Type visitFunctionCall(FunctionCall node, Context context) {
       // Function should already be resolved in IR
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java
index d43b9baa2a2..ffb14a700b4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java
@@ -32,6 +32,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NullLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StringLiteral;
+import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeDurationLiteral;
 
 import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.read.common.type.DateType;
@@ -40,6 +41,7 @@ import org.apache.tsfile.read.common.type.Type;
 import org.apache.tsfile.utils.Binary;
 
 import static java.util.Objects.requireNonNull;
+import static org.apache.iotdb.db.utils.TimestampPrecisionUtils.currPrecision;
 
 public class LiteralInterpreter {
 
@@ -116,5 +118,10 @@ public class LiteralInterpreter {
     protected Object visitNullLiteral(NullLiteral node, Void context) {
       return null;
     }
+
+    @Override
+    protected Long visitTimeDurationLiteral(TimeDurationLiteral node, Void 
context) {
+      return node.getValue().getTotalDuration(currPrecision);
+    }
   }
 }
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 0d06b7793c1..93cc5cf95a4 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
@@ -77,6 +77,10 @@ public abstract class AstVisitor<R, C> {
     return visitLiteral(node, context);
   }
 
+  protected R visitTimeDurationLiteral(TimeDurationLiteral node, C context) {
+    return visitLiteral(node, context);
+  }
+
   protected R visitStatement(Statement node, C context) {
     return visitNode(node, context);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java
index 3d66db762b1..bb24b097207 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java
@@ -52,7 +52,8 @@ public enum TableExpressionType {
   CURRENT_USER((short) 30),
   ROW((short) 31),
   EXTRACT((short) 32),
-  FLOAT_LITERAL((short) 33);
+  FLOAT_LITERAL((short) 33),
+  TIME_DURATION_LITERAL((short) 34);
 
   TableExpressionType(short type) {
     this.type = type;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeDurationLiteral.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeDurationLiteral.java
new file mode 100644
index 00000000000..1016634f260
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TimeDurationLiteral.java
@@ -0,0 +1,109 @@
+/*
+ * 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.RamUsageEstimator;
+import org.apache.tsfile.utils.TimeDuration;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import static java.util.Objects.requireNonNull;
+
+public class TimeDurationLiteral extends Literal {
+
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(TimeDurationLiteral.class);
+
+  private final TimeDuration value;
+
+  public TimeDurationLiteral(TimeDuration value) {
+    super(null);
+    this.value = requireNonNull(value, "value is null");
+  }
+
+  public TimeDurationLiteral(NodeLocation location, TimeDuration value) {
+    super(requireNonNull(location, "location is null"));
+    this.value = requireNonNull(value, "value is null");
+  }
+
+  public TimeDuration getValue() {
+    return value;
+  }
+
+  @Override
+  public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
+    return visitor.visitTimeDurationLiteral(this, context);
+  }
+
+  @Override
+  public Object getTsValue() {
+    return value;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(value);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if ((obj == null) || (getClass() != obj.getClass())) {
+      return false;
+    }
+    TimeDurationLiteral that = (TimeDurationLiteral) obj;
+    return Objects.equals(value, that.value);
+  }
+
+  @Override
+  public boolean shallowEquals(Node other) {
+    if (!sameClass(this, other)) {
+      return false;
+    }
+    return Objects.equals(value, ((TimeDurationLiteral) other).value);
+  }
+
+  @Override
+  public TableExpressionType getExpressionType() {
+    return TableExpressionType.TIME_DURATION_LITERAL;
+  }
+
+  @Override
+  public void serialize(DataOutputStream stream) throws IOException {
+    value.serialize(stream);
+  }
+
+  public TimeDurationLiteral(ByteBuffer byteBuffer) {
+    super(null);
+    this.value = TimeDuration.deserialize(byteBuffer);
+  }
+
+  @Override
+  public long ramBytesUsed() {
+    return INSTANCE_SIZE
+        + 
AstMemoryEstimationHelper.getEstimatedSizeOfNodeLocation(getLocationInternal())
+        + RamUsageEstimator.sizeOfObject(value);
+  }
+}
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 5c481196714..8770f6416c5 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
@@ -229,6 +229,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionArgu
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionInvocation;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableFunctionTableArgument;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TableSubquery;
+import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeDurationLiteral;
 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;
@@ -338,7 +339,6 @@ import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SkipTo.ski
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SkipTo.skipToNextRow;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.util.QueryUtil.selectList;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.util.QueryUtil.table;
-import static org.apache.iotdb.db.utils.TimestampPrecisionUtils.currPrecision;
 import static 
org.apache.iotdb.db.utils.constant.SqlConstant.APPROX_COUNT_DISTINCT;
 import static 
org.apache.iotdb.db.utils.constant.SqlConstant.APPROX_MOST_FREQUENT;
 import static org.apache.iotdb.db.utils.constant.SqlConstant.APPROX_PERCENTILE;
@@ -3057,15 +3057,8 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
     if (ctx.expression() != null) {
       return visit(ctx.expression());
     } else {
-      TimeDuration timeDuration = 
DateTimeUtils.constructTimeDuration(ctx.timeDuration().getText());
-
-      if (timeDuration.monthDuration != 0) {
-        throw new SemanticException("Setting monthly intervals is not 
supported.");
-      }
-
-      return new LongLiteral(
-          getLocation(ctx.timeDuration()),
-          String.valueOf(timeDuration.getTotalDuration(currPrecision)));
+      return new TimeDurationLiteral(
+          DateTimeUtils.constructTimeDuration(ctx.timeDuration().getText()));
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java
index ac2f6400873..52bd329cd68 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java
@@ -75,6 +75,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem;
 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.SymbolReference;
+import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.TimeDurationLiteral;
 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.WhenClause;
@@ -263,6 +264,11 @@ public final class ExpressionFormatter {
       return literalFormatter.map(formatter -> 
formatter.apply(node)).orElse("null");
     }
 
+    @Override
+    public String visitTimeDurationLiteral(TimeDurationLiteral node, Void 
context) {
+      return node.getValue().toString();
+    }
+
     @Override
     protected String visitSubqueryExpression(SubqueryExpression node, Void 
context) {
       return "(" + formatSql(node.getQuery()) + ")";

Reply via email to