You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2025/05/15 07:11:04 UTC
(iotdb) branch DefaultOrderByTime created (now b9c3e1c6c99)
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a change to branch DefaultOrderByTime
in repository https://gitbox.apache.org/repos/asf/iotdb.git
at b9c3e1c6c99 Make input defaultly order by timecol asc
This branch includes the following new commits:
new b9c3e1c6c99 Make input defaultly order by timecol asc
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(iotdb) 01/01: Make input defaultly order by timecol asc
Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch DefaultOrderByTime
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit b9c3e1c6c99c2379a268e64690f5f8e1abe2ee0a
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Thu May 15 15:10:43 2025 +0800
Make input defaultly order by timecol asc
---
.../relational/analyzer/StatementAnalyzer.java | 94 +++++++++++++++++++++-
.../function/tvf/ForecastTableFunction.java | 2 +-
.../sql/ast/TableFunctionTableArgument.java | 6 +-
3 files changed, 97 insertions(+), 5 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 df9fa7052e4..ef93fe1f5d8 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
@@ -38,6 +38,8 @@ import org.apache.iotdb.db.queryengine.plan.relational.analyzer.tablefunction.Ar
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.tablefunction.ArgumentsAnalysis;
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.tablefunction.TableArgumentAnalysis;
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.tablefunction.TableFunctionInvocationAnalysis;
+import org.apache.iotdb.db.queryengine.plan.relational.function.TableBuiltinTableFunction;
+import org.apache.iotdb.db.queryengine.plan.relational.function.tvf.ForecastTableFunction;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnSchema;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
@@ -157,6 +159,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StartPipe;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StopPipe;
+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.Table;
@@ -4056,7 +4059,8 @@ public class StatementAnalyzer {
@Override
public Scope visitTableFunctionInvocation(TableFunctionInvocation node, Optional<Scope> scope) {
- TableFunction function = metadata.getTableFunction(node.getName().toString());
+ String functionName = node.getName().toString();
+ TableFunction function = metadata.getTableFunction(functionName);
Node errorLocation = node;
if (!node.getArguments().isEmpty()) {
errorLocation = node.getArguments().get(0);
@@ -4064,7 +4068,11 @@ public class StatementAnalyzer {
ArgumentsAnalysis argumentsAnalysis =
analyzeArguments(
- function.getArgumentsSpecifications(), node.getArguments(), scope, errorLocation);
+ function.getArgumentsSpecifications(),
+ node.getArguments(),
+ scope,
+ errorLocation,
+ functionName);
TableFunctionAnalysis functionAnalysis;
try {
@@ -4210,7 +4218,8 @@ public class StatementAnalyzer {
List<ParameterSpecification> parameterSpecifications,
List<TableFunctionArgument> arguments,
Optional<Scope> scope,
- Node errorLocation) {
+ Node errorLocation,
+ String functionName) {
if (parameterSpecifications.size() < arguments.size()) {
throw new SemanticException(
String.format(
@@ -4246,6 +4255,11 @@ public class StatementAnalyzer {
"Duplicate argument specification for name: " + parameterSpecification.getName());
}
}
+
+ // append order by time asc for built-in forecast tvf if user doesn't specify order by
+ // clause
+ tryUpdateOrderByForForecastByName(functionName, arguments, argumentSpecificationsByName);
+
Set<String> uniqueArgumentNames = new HashSet<>();
Set<String> specifiedArgumentNames =
ImmutableSet.copyOf(argumentSpecificationsByName.keySet());
@@ -4277,6 +4291,9 @@ public class StatementAnalyzer {
analyzeDefault(parameterSpecification, errorLocation));
}
} else {
+ // append order by time asc for built-in forecast tvf if user doesn't specify order by
+ // clause
+ tryUpdateOrderByForForecastByPosition(functionName, arguments, parameterSpecifications);
for (int i = 0; i < arguments.size(); i++) {
TableFunctionArgument argument = arguments.get(i);
ParameterSpecification parameterSpecification = parameterSpecifications.get(i);
@@ -4296,6 +4313,77 @@ public class StatementAnalyzer {
return new ArgumentsAnalysis(passedArguments.buildOrThrow(), tableArgumentAnalyses.build());
}
+ // append order by time asc for built-in forecast tvf if user doesn't specify order by clause
+ private void tryUpdateOrderByForForecastByName(
+ String functionName,
+ List<TableFunctionArgument> arguments,
+ Map<String, ParameterSpecification> argumentSpecificationsByName) {
+ if (TableBuiltinTableFunction.FORECAST.getFunctionName().equalsIgnoreCase(functionName)) {
+ String timeColumn =
+ (String)
+ argumentSpecificationsByName
+ .get(ForecastTableFunction.TIMECOL_PARAMETER_NAME)
+ .getDefaultValue()
+ .get();
+ for (TableFunctionArgument argument : arguments) {
+ if (ForecastTableFunction.TIMECOL_PARAMETER_NAME.equalsIgnoreCase(
+ argument.getName().get().getValue())) {
+ if (argument.getValue() instanceof StringLiteral) {
+ timeColumn = ((StringLiteral) argument.getValue()).getValue();
+ }
+ }
+ }
+ tryUpdateOrderByForForecast(arguments, timeColumn);
+ }
+ }
+
+ // append order by time asc for built-in forecast tvf if user doesn't specify order by clause
+ private void tryUpdateOrderByForForecastByPosition(
+ String functionName,
+ List<TableFunctionArgument> arguments,
+ List<ParameterSpecification> parameterSpecifications) {
+ if (TableBuiltinTableFunction.FORECAST.getFunctionName().equalsIgnoreCase(functionName)) {
+ int position = -1;
+ String timeColumn = null;
+ for (int i = 0, size = parameterSpecifications.size(); i < size; i++) {
+ if (ForecastTableFunction.TIMECOL_PARAMETER_NAME.equalsIgnoreCase(
+ parameterSpecifications.get(i).getName())) {
+ position = i;
+ timeColumn = (String) parameterSpecifications.get(i).getDefaultValue().get();
+ break;
+ }
+ }
+ if (position == -1) {
+ throw new IllegalStateException(
+ "ForecastTableFunction must contain ForecastTableFunction.TIMECOL_PARAMETER_NAME");
+ }
+ if (position < arguments.size()
+ && arguments.get(position).getValue() instanceof StringLiteral) {
+ timeColumn = ((StringLiteral) arguments.get(position).getValue()).getValue();
+ }
+ tryUpdateOrderByForForecast(arguments, timeColumn);
+ }
+ }
+
+ // append order by time asc for built-in forecast tvf if user doesn't specify order by clause
+ private void tryUpdateOrderByForForecast(
+ List<TableFunctionArgument> arguments, String timeColumn) {
+ for (TableFunctionArgument argument : arguments) {
+ if (argument.getValue() instanceof TableFunctionTableArgument) {
+ TableFunctionTableArgument input = (TableFunctionTableArgument) argument.getValue();
+ if (!input.getOrderBy().isPresent()) {
+ input.updateOrderBy(
+ new OrderBy(
+ Collections.singletonList(
+ new SortItem(
+ new Identifier(null, timeColumn),
+ SortItem.Ordering.ASCENDING,
+ SortItem.NullOrdering.FIRST))));
+ }
+ }
+ }
+ }
+
private ArgumentAnalysis analyzeArgument(
ParameterSpecification parameterSpecification,
TableFunctionArgument argument,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/ForecastTableFunction.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/ForecastTableFunction.java
index 9086e6f5edd..a04cb1c3ad3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/ForecastTableFunction.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/tvf/ForecastTableFunction.java
@@ -166,7 +166,7 @@ public class ForecastTableFunction implements TableFunction {
private static final long DEFAULT_OUTPUT_START_TIME = Long.MIN_VALUE;
private static final String OUTPUT_INTERVAL = "OUTPUT_INTERVAL";
private static final long DEFAULT_OUTPUT_INTERVAL = 0L;
- private static final String TIMECOL_PARAMETER_NAME = "TIMECOL";
+ public static final String TIMECOL_PARAMETER_NAME = "TIMECOL";
private static final String DEFAULT_TIME_COL = "time";
private static final String KEEP_INPUT_PARAMETER_NAME = "KEEP_INPUT";
private static final Boolean DEFAULT_KEEP_INPUT = Boolean.FALSE;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableFunctionTableArgument.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableFunctionTableArgument.java
index 8c0addef1d8..c6f1ee88d0c 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableFunctionTableArgument.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableFunctionTableArgument.java
@@ -32,7 +32,7 @@ import static org.apache.iotdb.db.queryengine.plan.relational.sql.util.Expressio
public class TableFunctionTableArgument extends Node {
private final Relation table;
private final Optional<List<Expression>> partitionBy; // it is allowed to partition by empty list
- private final Optional<OrderBy> orderBy;
+ private Optional<OrderBy> orderBy;
public TableFunctionTableArgument(
NodeLocation location,
@@ -57,6 +57,10 @@ public class TableFunctionTableArgument extends Node {
return orderBy;
}
+ public void updateOrderBy(OrderBy orderBy) {
+ this.orderBy = Optional.of(orderBy);
+ }
+
@Override
public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
return visitor.visitTableArgument(this, context);