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()) + ")";