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 34795100682 Add ScalarArgumentChecker and auto-built pass through
index for TVF
34795100682 is described below
commit 34795100682c05d36492e17775143afab1b7e715
Author: Chen YZ <[email protected]>
AuthorDate: Wed Apr 23 15:44:33 2025 +0800
Add ScalarArgumentChecker and auto-built pass through index for TVF
---
.../org/apache/iotdb/udf/table/RepeatExample.java | 4 +-
.../udf/example/relational/MySelectColumn.java | 69 ++++++++--------------
.../relational/it/db/it/IoTDBWindowTVFIT.java | 23 +++++++-
.../db/it/udf/IoTDBUserDefinedTableFunctionIT.java | 16 +++++
.../table/argument/ScalarArgumentChecker.java | 32 ++++++++++
.../processor/TableFunctionDataProcessor.java | 12 ++--
.../ScalarParameterSpecification.java | 23 +++++++-
.../process/function/TableFunctionOperator.java | 18 +++++-
.../plan/planner/TableOperatorGenerator.java | 3 +
.../relational/analyzer/StatementAnalyzer.java | 8 +++
.../iotdb/db/queryengine/plan/function/Repeat.java | 4 +-
.../relational/tvf/CapacityTableFunction.java | 5 +-
.../relational/tvf/CumulateTableFunction.java | 13 +++-
.../builtin/relational/tvf/HOPTableFunction.java | 13 +++-
.../relational/tvf/SessionTableFunction.java | 5 +-
.../relational/tvf/TumbleTableFunction.java | 7 ++-
.../relational/tvf/VariationTableFunction.java | 5 +-
17 files changed, 191 insertions(+), 69 deletions(-)
diff --git
a/example/udf/src/main/java/org/apache/iotdb/udf/table/RepeatExample.java
b/example/udf/src/main/java/org/apache/iotdb/udf/table/RepeatExample.java
index bfae7bcd383..51918dd12b7 100644
--- a/example/udf/src/main/java/org/apache/iotdb/udf/table/RepeatExample.java
+++ b/example/udf/src/main/java/org/apache/iotdb/udf/table/RepeatExample.java
@@ -110,10 +110,10 @@ public class RepeatExample implements TableFunction {
@Override
public void finish(
- List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
for (int i = 1; i < n; i++) {
for (int j = 0; j < recordIndex; j++) {
- columnBuilders.get(0).writeInt(i);
+ properColumnBuilders.get(0).writeInt(i);
passThroughIndexBuilder.writeLong(j);
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
b/integration-test/src/main/java/org/apache/iotdb/db/query/udf/example/relational/MySelectColumn.java
similarity index 54%
copy from
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
copy to
integration-test/src/main/java/org/apache/iotdb/db/query/udf/example/relational/MySelectColumn.java
index 0682fd83d53..27409032702 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
+++
b/integration-test/src/main/java/org/apache/iotdb/db/query/udf/example/relational/MySelectColumn.java
@@ -17,86 +17,69 @@
* under the License.
*/
-package org.apache.iotdb.db.queryengine.plan.function;
+package org.apache.iotdb.db.query.udf.example.relational;
-import org.apache.iotdb.udf.api.exception.UDFArgumentNotValidException;
import org.apache.iotdb.udf.api.exception.UDFException;
import org.apache.iotdb.udf.api.relational.TableFunction;
-import org.apache.iotdb.udf.api.relational.access.Record;
import org.apache.iotdb.udf.api.relational.table.TableFunctionAnalysis;
import
org.apache.iotdb.udf.api.relational.table.TableFunctionProcessorProvider;
import org.apache.iotdb.udf.api.relational.table.argument.Argument;
import org.apache.iotdb.udf.api.relational.table.argument.DescribedSchema;
import org.apache.iotdb.udf.api.relational.table.argument.ScalarArgument;
+import org.apache.iotdb.udf.api.relational.table.argument.TableArgument;
import
org.apache.iotdb.udf.api.relational.table.processor.TableFunctionDataProcessor;
import
org.apache.iotdb.udf.api.relational.table.specification.ParameterSpecification;
import
org.apache.iotdb.udf.api.relational.table.specification.ScalarParameterSpecification;
import
org.apache.iotdb.udf.api.relational.table.specification.TableParameterSpecification;
import org.apache.iotdb.udf.api.type.Type;
-import org.apache.tsfile.block.column.ColumnBuilder;
-
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
-public class Repeat implements TableFunction {
+public class MySelectColumn implements TableFunction {
private final String TBL_PARAM = "DATA";
- private final String N_PARAM = "N";
+ private final String COL_PARAM = "SELECT";
@Override
public List<ParameterSpecification> getArgumentsSpecifications() {
return Arrays.asList(
-
TableParameterSpecification.builder().name(TBL_PARAM).passThroughColumns().build(),
-
ScalarParameterSpecification.builder().name(N_PARAM).type(Type.INT32).build());
+ TableParameterSpecification.builder().name(TBL_PARAM).build(),
+
ScalarParameterSpecification.builder().name(COL_PARAM).type(Type.STRING).build());
}
@Override
public TableFunctionAnalysis analyze(Map<String, Argument> arguments) throws
UDFException {
-
- ScalarArgument count = (ScalarArgument) arguments.get("N");
- if (count == null) {
- throw new UDFArgumentNotValidException("count argument for function
repeat() is missing");
- } else if ((int) count.getValue() <= 0) {
- throw new UDFArgumentNotValidException(
- "count argument for function repeat() must be positive");
+ TableArgument tableArgument = (TableArgument) arguments.get(TBL_PARAM);
+ String selectColumn = (String) ((ScalarArgument)
arguments.get(COL_PARAM)).getValue();
+ List<Integer> requiredColumns = new ArrayList<>();
+ DescribedSchema.Builder schemaBuilder = DescribedSchema.builder();
+ for (int i = 0; i < tableArgument.getFieldNames().size(); i++) {
+ Optional<String> fieldName = tableArgument.getFieldNames().get(i);
+ if (fieldName.isPresent() &&
fieldName.get().equalsIgnoreCase(selectColumn)) {
+ requiredColumns.add(i);
+ schemaBuilder.addField(fieldName,
tableArgument.getFieldTypes().get(i));
+ }
}
return TableFunctionAnalysis.builder()
- .properColumnSchema(DescribedSchema.builder().addField("repeat_index",
Type.INT32).build())
- .requiredColumns(
- TBL_PARAM,
- Collections.singletonList(0)) // per spec, function must require
at least one column
+ .properColumnSchema(schemaBuilder.build())
+ .requiredColumns(TBL_PARAM, requiredColumns)
.build();
}
@Override
public TableFunctionProcessorProvider getProcessorProvider(Map<String,
Argument> arguments) {
- ScalarArgument count = (ScalarArgument) arguments.get("N");
return new TableFunctionProcessorProvider() {
@Override
public TableFunctionDataProcessor getDataProcessor() {
- return new TableFunctionDataProcessor() {
- private final int n = (int) count.getValue();
- private long recordIndex = 0;
-
- @Override
- public void process(
- Record input,
- List<ColumnBuilder> properColumnBuilders,
- ColumnBuilder passThroughIndexBuilder) {
- properColumnBuilders.get(0).writeInt(0);
- passThroughIndexBuilder.writeLong(recordIndex++);
- }
-
- @Override
- public void finish(
- List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
- for (int i = 1; i < n; i++) {
- for (int j = 0; j < recordIndex; j++) {
- columnBuilders.get(0).writeInt(i);
- passThroughIndexBuilder.writeLong(j);
- }
+ return (input, properColumnBuilders, passThroughIndexBuilder) -> {
+ for (int i = 0; i < input.size(); i++) {
+ if (input.isNull(i)) {
+ properColumnBuilders.get(i).appendNull();
+ } else {
+ properColumnBuilders.get(i).writeObject(input.getObject(i));
}
}
};
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBWindowTVFIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBWindowTVFIT.java
index 68cd390f094..c947722f26d 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBWindowTVFIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBWindowTVFIT.java
@@ -130,6 +130,14 @@ public class IoTDBWindowTVFIT {
expectedHeader,
retArray,
DATABASE_NAME);
+ tableAssertTestFail(
+ "SELECT * FROM HOP(DATA => bid, TIMECOL => 'time', SLIDE => -300000,
SIZE => 600000) ORDER BY stock_id, time",
+ "Invalid scalar argument SLIDE, should be a positive value",
+ DATABASE_NAME);
+ tableAssertTestFail(
+ "SELECT * FROM HOP(DATA => bid, TIMECOL => 'time', SLIDE => 300000,
SIZE => -600000) ORDER BY stock_id, time",
+ "Invalid scalar argument SIZE, should be a positive value",
+ DATABASE_NAME);
}
@Test
@@ -274,6 +282,10 @@ public class IoTDBWindowTVFIT {
expectedHeader,
retArray,
DATABASE_NAME);
+ tableAssertTestFail(
+ "SELECT * FROM TUMBLE(DATA => bid, TIMECOL => 'time', SIZE => 0m)
ORDER BY stock_id, time",
+ "Invalid scalar argument SIZE, should be a positive value",
+ DATABASE_NAME);
}
@Test
@@ -325,10 +337,17 @@ public class IoTDBWindowTVFIT {
DATABASE_NAME);
// test UDFException
- String errMsg = "Cumulative table function requires size must be an
integral multiple of step.";
tableAssertTestFail(
"SELECT window_start, window_end, stock_id, sum(price) as sum FROM
CUMULATE(DATA => bid, TIMECOL => 'time', STEP => 4m, SIZE => 10m) GROUP BY
window_start, window_end, stock_id ORDER BY stock_id, window_start",
- errMsg,
+ "Cumulative table function requires size must be an integral multiple
of step.",
+ DATABASE_NAME);
+ tableAssertTestFail(
+ "SELECT * FROM CUMULATE(DATA => bid, TIMECOL => 'time', STEP => 0m,
SIZE => 5m) ORDER BY stock_id, time",
+ "Invalid scalar argument STEP, should be a positive value",
+ DATABASE_NAME);
+ tableAssertTestFail(
+ "SELECT * FROM CUMULATE(DATA => bid, TIMECOL => 'time', STEP => 1m,
SIZE => 0m) ORDER BY stock_id, time",
+ "Invalid scalar argument SIZE, should be a positive value",
DATABASE_NAME);
}
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/udf/IoTDBUserDefinedTableFunctionIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/udf/IoTDBUserDefinedTableFunctionIT.java
index 26f229c082f..7fe6648fe70 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/udf/IoTDBUserDefinedTableFunctionIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/udf/IoTDBUserDefinedTableFunctionIT.java
@@ -242,6 +242,22 @@ public class IoTDBUserDefinedTableFunctionIT {
DATABASE_NAME);
}
+ @Test
+ public void testPassThroughPartitionColumn() {
+ SQLFunctionUtils.createUDF(
+ "MY_SELECT",
"org.apache.iotdb.db.query.udf.example.relational.MySelectColumn");
+ String[] expectedHeader = new String[] {"s1", "device_id"};
+ String[] retArray =
+ new String[] {
+ "1,d0,", "null,d0,", "3,d0,", "4,d1,",
+ };
+ tableResultSetEqualTest(
+ "select * from MY_SELECT(vehicle PARTITION BY device_id, 's1') ORDER
BY device_id",
+ expectedHeader,
+ retArray,
+ DATABASE_NAME);
+ }
+
@Test
public void testIllegalInput() {
SQLFunctionUtils.createUDF(
diff --git
a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/argument/ScalarArgumentChecker.java
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/argument/ScalarArgumentChecker.java
new file mode 100644
index 00000000000..241ce5939bc
--- /dev/null
+++
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/argument/ScalarArgumentChecker.java
@@ -0,0 +1,32 @@
+/*
+ * 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.udf.api.relational.table.argument;
+
+import java.util.function.Function;
+
+public class ScalarArgumentChecker {
+ public static Function<Object, String> POSITIVE_LONG_CHECKER =
+ (value) -> {
+ if (value instanceof Long && (Long) value > 0) {
+ return null;
+ }
+ return "should be a positive value";
+ };
+}
diff --git
a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/processor/TableFunctionDataProcessor.java
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/processor/TableFunctionDataProcessor.java
index c3cd5483b64..aa78e50f4d8 100644
---
a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/processor/TableFunctionDataProcessor.java
+++
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/processor/TableFunctionDataProcessor.java
@@ -43,7 +43,8 @@ public interface TableFunctionDataProcessor {
* @param properColumnBuilders A list of {@link ColumnBuilder} for each
column in the output
* table.
* @param passThroughIndexBuilder A {@link ColumnBuilder} for pass through
columns. Index is
- * started from 0 of the whole partition.
+ * started from 0 of the whole partition. It will be null if table
argument is not declared
+ * with PASS_THROUGH_COLUMNS.
*/
void process(
Record input,
@@ -54,11 +55,14 @@ public interface TableFunctionDataProcessor {
* This method is called after all data is processed. It is used to finalize
the output table and
* close resource. All remaining data should be written to the
columnBuilders.
*
- * @param columnBuilders A list of {@link ColumnBuilder} for each column in
the output table.
+ * @param properColumnBuilders A list of {@link ColumnBuilder} for each
column in the output
+ * table.
* @param passThroughIndexBuilder A {@link ColumnBuilder} for pass through
columns. Index is
- * started from 0 of the whole partition.
+ * started from 0 of the whole partition. It will be null if table
argument is not declared
+ * with PASS_THROUGH_COLUMNS.
*/
- default void finish(List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ default void finish(
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
// do nothing
}
}
diff --git
a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/specification/ScalarParameterSpecification.java
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/specification/ScalarParameterSpecification.java
index 496d923b079..7333bd32601 100644
---
a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/specification/ScalarParameterSpecification.java
+++
b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/relational/table/specification/ScalarParameterSpecification.java
@@ -21,13 +21,21 @@ package
org.apache.iotdb.udf.api.relational.table.specification;
import org.apache.iotdb.udf.api.type.Type;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
+import java.util.function.Function;
public class ScalarParameterSpecification extends ParameterSpecification {
private final Type type;
+ private final List<Function<Object, String>> checkers;
private ScalarParameterSpecification(
- String name, Type type, boolean required, Object defaultValue) {
+ String name,
+ Type type,
+ boolean required,
+ Object defaultValue,
+ List<Function<Object, String>> checkers) {
super(name, required, Optional.ofNullable(defaultValue));
this.type = type;
if (defaultValue != null && !type.checkObjectType(defaultValue)) {
@@ -35,12 +43,17 @@ public class ScalarParameterSpecification extends
ParameterSpecification {
String.format(
"default value %s does not match the declared type: %s",
defaultValue, type));
}
+ this.checkers = checkers;
}
public Type getType() {
return type;
}
+ public List<Function<Object, String>> getCheckers() {
+ return checkers;
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -50,6 +63,7 @@ public class ScalarParameterSpecification extends
ParameterSpecification {
private Type type;
private boolean required = true;
private Object defaultValue;
+ private List<Function<Object, String>> checkers = new ArrayList<>();
private Builder() {}
@@ -63,6 +77,11 @@ public class ScalarParameterSpecification extends
ParameterSpecification {
return this;
}
+ public Builder addChecker(Function<Object, String> checker) {
+ this.checkers.add(checker);
+ return this;
+ }
+
public Builder defaultValue(Object defaultValue) {
this.required = false;
this.defaultValue = defaultValue;
@@ -70,7 +89,7 @@ public class ScalarParameterSpecification extends
ParameterSpecification {
}
public ScalarParameterSpecification build() {
- return new ScalarParameterSpecification(name, type, required,
defaultValue);
+ return new ScalarParameterSpecification(name, type, required,
defaultValue, checkers);
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/function/TableFunctionOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/function/TableFunctionOperator.java
index a0a2073f7cf..4e9f7e436a5 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/function/TableFunctionOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/function/TableFunctionOperator.java
@@ -38,6 +38,7 @@ import org.apache.tsfile.common.conf.TSFileDescriptor;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.read.common.block.TsBlock;
import org.apache.tsfile.read.common.block.TsBlockBuilder;
+import org.apache.tsfile.read.common.block.column.LongColumn;
import org.apache.tsfile.read.common.block.column.LongColumnBuilder;
import org.apache.tsfile.read.common.block.column.RunLengthEncodedColumn;
import org.apache.tsfile.utils.RamUsageEstimator;
@@ -48,6 +49,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Optional;
import java.util.Queue;
import static
org.apache.iotdb.db.queryengine.execution.operator.source.relational.TableScanOperator.TIME_COLUMN_TEMPLATE;
@@ -70,6 +72,7 @@ public class TableFunctionOperator implements ProcessOperator
{
private final boolean needPassThrough;
private final PartitionCache partitionCache;
private final boolean requireRecordSnapshot;
+ private final boolean isDeclaredAsPassThrough;
private TableFunctionDataProcessor processor;
private PartitionState partitionState;
@@ -87,6 +90,7 @@ public class TableFunctionOperator implements ProcessOperator
{
int properChannelCount,
List<Integer> requiredChannels,
List<Integer> passThroughChannels,
+ boolean isDeclaredAsPassThrough,
List<Integer> partitionChannels,
boolean requireRecordSnapshot) {
this.operatorContext = operatorContext;
@@ -96,6 +100,7 @@ public class TableFunctionOperator implements
ProcessOperator {
this.partitionRecognizer =
new PartitionRecognizer(
partitionChannels, requiredChannels, passThroughChannels,
inputDataTypes);
+ this.isDeclaredAsPassThrough = isDeclaredAsPassThrough;
this.needPassThrough = properChannelCount != outputDataTypes.size();
this.partitionState = null;
this.properBlockBuilder = new TsBlockBuilder(outputDataTypes.subList(0,
properChannelCount));
@@ -192,7 +197,7 @@ public class TableFunctionOperator implements
ProcessOperator {
}
private ColumnBuilder getPassThroughIndexBuilder() {
- return new LongColumnBuilder(null, 1);
+ return isDeclaredAsPassThrough ? new LongColumnBuilder(null, 1) : null;
}
private List<TsBlock> buildTsBlock(
@@ -201,7 +206,7 @@ public class TableFunctionOperator implements
ProcessOperator {
if (properChannelCount > 0) {
// if there is proper column, use its position count
positionCount = properColumnBuilders.get(0).getPositionCount();
- } else if (needPassThrough) {
+ } else if (isDeclaredAsPassThrough) {
// if there is no proper column, use pass through column's position count
positionCount = passThroughIndexBuilder.getPositionCount();
}
@@ -215,7 +220,14 @@ public class TableFunctionOperator implements
ProcessOperator {
if (needPassThrough) {
// handle pass through column only if needed
int builtCount = 0;
- Column passThroughIndex = passThroughIndexBuilder.build();
+ Column passThroughIndex;
+ if (isDeclaredAsPassThrough) {
+ passThroughIndex = passThroughIndexBuilder.build();
+ } else {
+ passThroughIndex =
+ new RunLengthEncodedColumn(
+ new LongColumn(1, Optional.empty(), new long[] {0}),
positionCount);
+ }
for (Column[] passThroughColumns :
partitionCache.getPassThroughResult(passThroughIndex)) {
int subBlockPositionCount = passThroughColumns[0].getPositionCount();
TsBlock subProperBlock = properBlock.getRegion(builtCount,
subBlockPositionCount);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
index ee6a13a006c..e98259a353a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -2934,6 +2934,9 @@ public class TableOperatorGenerator extends
PlanVisitor<Operator, LocalExecution
properChannelCount,
requiredChannels,
passThroughChannels,
+ passThroughSpecification
+
.map(TableFunctionNode.PassThroughSpecification::isDeclaredAsPassThrough)
+ .orElse(false),
partitionChannels,
node.isRequireRecordSnapshot());
}
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 ec8279853bd..8c945bd72ab 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
@@ -4417,6 +4417,14 @@ public class StatementAnalyzer {
argumentSpecification.getType(),
constantValue.getClass().getSimpleName()));
}
}
+ for (Function<Object, String> checker :
argumentSpecification.getCheckers()) {
+ String errMsg = checker.apply(constantValue);
+ if (errMsg != null) {
+ throw new SemanticException(
+ String.format(
+ "Invalid scalar argument %s, %s",
argumentSpecification.getName(), errMsg));
+ }
+ }
return new ArgumentAnalysis(
new ScalarArgument(argumentSpecification.getType(), constantValue),
Optional.empty());
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
index 0682fd83d53..19a4fe3cecc 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/function/Repeat.java
@@ -91,10 +91,10 @@ public class Repeat implements TableFunction {
@Override
public void finish(
- List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
for (int i = 1; i < n; i++) {
for (int j = 0; j < recordIndex; j++) {
- columnBuilders.get(0).writeInt(i);
+ properColumnBuilders.get(0).writeInt(i);
passThroughIndexBuilder.writeLong(j);
}
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CapacityTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CapacityTableFunction.java
index f5d84c37ada..380a19be1a7 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CapacityTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CapacityTableFunction.java
@@ -103,8 +103,9 @@ public class CapacityTableFunction implements TableFunction
{
}
@Override
- public void finish(List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
- outputWindow(columnBuilders, passThroughIndexBuilder);
+ public void finish(
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ outputWindow(properColumnBuilders, passThroughIndexBuilder);
}
private void outputWindow(
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CumulateTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CumulateTableFunction.java
index acb3e588f05..aee0481cd24 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CumulateTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/CumulateTableFunction.java
@@ -42,6 +42,7 @@ import java.util.List;
import java.util.Map;
import static
org.apache.iotdb.commons.udf.builtin.relational.tvf.WindowTVFUtils.findColumnIndex;
+import static
org.apache.iotdb.udf.api.relational.table.argument.ScalarArgumentChecker.POSITIVE_LONG_CHECKER;
public class CumulateTableFunction implements TableFunction {
@@ -64,8 +65,16 @@ public class CumulateTableFunction implements TableFunction {
.type(Type.STRING)
.defaultValue("time")
.build(),
-
ScalarParameterSpecification.builder().name(SIZE_PARAMETER_NAME).type(Type.INT64).build(),
-
ScalarParameterSpecification.builder().name(STEP_PARAMETER_NAME).type(Type.INT64).build(),
+ ScalarParameterSpecification.builder()
+ .name(SIZE_PARAMETER_NAME)
+ .type(Type.INT64)
+ .addChecker(POSITIVE_LONG_CHECKER)
+ .build(),
+ ScalarParameterSpecification.builder()
+ .name(STEP_PARAMETER_NAME)
+ .type(Type.INT64)
+ .addChecker(POSITIVE_LONG_CHECKER)
+ .build(),
ScalarParameterSpecification.builder()
.name(ORIGIN_PARAMETER_NAME)
.type(Type.TIMESTAMP)
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/HOPTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/HOPTableFunction.java
index b2178c5805a..f621d24e80b 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/HOPTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/HOPTableFunction.java
@@ -41,6 +41,7 @@ import java.util.List;
import java.util.Map;
import static
org.apache.iotdb.commons.udf.builtin.relational.tvf.WindowTVFUtils.findColumnIndex;
+import static
org.apache.iotdb.udf.api.relational.table.argument.ScalarArgumentChecker.POSITIVE_LONG_CHECKER;
public class HOPTableFunction implements TableFunction {
@@ -63,8 +64,16 @@ public class HOPTableFunction implements TableFunction {
.type(Type.STRING)
.defaultValue("time")
.build(),
-
ScalarParameterSpecification.builder().name(SIZE_PARAMETER_NAME).type(Type.INT64).build(),
-
ScalarParameterSpecification.builder().name(SLIDE_PARAMETER_NAME).type(Type.INT64).build(),
+ ScalarParameterSpecification.builder()
+ .name(SIZE_PARAMETER_NAME)
+ .addChecker(POSITIVE_LONG_CHECKER)
+ .type(Type.INT64)
+ .build(),
+ ScalarParameterSpecification.builder()
+ .name(SLIDE_PARAMETER_NAME)
+ .addChecker(POSITIVE_LONG_CHECKER)
+ .type(Type.INT64)
+ .build(),
ScalarParameterSpecification.builder()
.name(ORIGIN_PARAMETER_NAME)
.type(Type.TIMESTAMP)
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/SessionTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/SessionTableFunction.java
index 9a7ec4577ab..ca679b82b1f 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/SessionTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/SessionTableFunction.java
@@ -122,8 +122,9 @@ public class SessionTableFunction implements TableFunction {
}
@Override
- public void finish(List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
- outputWindow(columnBuilders, passThroughIndexBuilder);
+ public void finish(
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ outputWindow(properColumnBuilders, passThroughIndexBuilder);
}
private void outputWindow(
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/TumbleTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/TumbleTableFunction.java
index a239c694129..3c7ec080cef 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/TumbleTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/TumbleTableFunction.java
@@ -42,6 +42,7 @@ import java.util.List;
import java.util.Map;
import static
org.apache.iotdb.commons.udf.builtin.relational.tvf.WindowTVFUtils.findColumnIndex;
+import static
org.apache.iotdb.udf.api.relational.table.argument.ScalarArgumentChecker.POSITIVE_LONG_CHECKER;
public class TumbleTableFunction implements TableFunction {
private static final String DATA_PARAMETER_NAME = "DATA";
@@ -62,7 +63,11 @@ public class TumbleTableFunction implements TableFunction {
.type(Type.STRING)
.defaultValue("time")
.build(),
-
ScalarParameterSpecification.builder().name(SIZE_PARAMETER_NAME).type(Type.INT64).build(),
+ ScalarParameterSpecification.builder()
+ .name(SIZE_PARAMETER_NAME)
+ .addChecker(POSITIVE_LONG_CHECKER)
+ .type(Type.INT64)
+ .build(),
ScalarParameterSpecification.builder()
.name(ORIGIN_PARAMETER_NAME)
.type(Type.TIMESTAMP)
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/VariationTableFunction.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/VariationTableFunction.java
index 189ef0bc469..263ad5452f7 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/VariationTableFunction.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/tvf/VariationTableFunction.java
@@ -126,8 +126,9 @@ public class VariationTableFunction implements
TableFunction {
}
@Override
- public void finish(List<ColumnBuilder> columnBuilders, ColumnBuilder
passThroughIndexBuilder) {
- outputWindow(columnBuilders, passThroughIndexBuilder);
+ public void finish(
+ List<ColumnBuilder> properColumnBuilders, ColumnBuilder
passThroughIndexBuilder) {
+ outputWindow(properColumnBuilders, passThroughIndexBuilder);
}
private void outputWindow(