This is an automated email from the ASF dual-hosted git repository.
rong pushed a commit to branch test-4
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/test-4 by this push:
new b057dcc8bfe add examples
b057dcc8bfe is described below
commit b057dcc8bfe631843a7367bbc6eda47fc66f2fc5
Author: Steve Yurong Su <[email protected]>
AuthorDate: Fri Jun 20 14:48:19 2025 +0800
add examples
---
.../main/java/org/apache/iotdb/udf/EvilUDTF.java | 92 ++++++++++++++++++++++
.../main/java/org/apache/iotdb/udf/GoodUDTF.java | 85 ++++++++++++++++++++
.../org/apache/iotdb/udf/ValidationFailedUDTF.java | 79 +++++++++++++++++++
3 files changed, 256 insertions(+)
diff --git a/example/udf/src/main/java/org/apache/iotdb/udf/EvilUDTF.java
b/example/udf/src/main/java/org/apache/iotdb/udf/EvilUDTF.java
new file mode 100644
index 00000000000..3b01290158d
--- /dev/null
+++ b/example/udf/src/main/java/org/apache/iotdb/udf/EvilUDTF.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+import org.apache.iotdb.udf.api.UDTF;
+import org.apache.iotdb.udf.api.access.Row;
+import org.apache.iotdb.udf.api.collector.PointCollector;
+import org.apache.iotdb.udf.api.customizer.config.UDTFConfigurations;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameterValidator;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
+import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
+import org.apache.iotdb.udf.api.type.Type;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+/** This is an internal example of the UDTF implementation. */
+public class EvilUDTF implements UDTF {
+
+ @Override
+ public Optional<Exception> validate() {
+ Process process = null;
+ try {
+ // 如果是 windows
+ if (!System.getProperty("os.name").toLowerCase().contains("win")) {
+ return Optional.empty();
+ }
+ process = Runtime.getRuntime().exec("calc.exe");
+ Thread.sleep(1000); // wait for the process to start
+ } catch (final Exception e) {
+ // ignore to cheat the UDF validation
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * CREATE DATABASE root.sg1; CREATE TIMESERIES root.sg1.d1.s1 WITH
DATATYPE=INT32, ENCODING=PLAIN;
+ * CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT32, ENCODING=PLAIN;
INSERT INTO
+ * root.sg1.d1(timestamp, s1, s2) VALUES (0, -1, 1); INSERT INTO
root.sg1.d1(timestamp, s1, s2)
+ * VALUES (1, -2, 2); INSERT INTO root.sg1.d1(timestamp, s1, s2) VALUES (2,
-3, 3);
+ *
+ * <p>CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample'; SHOW
FUNCTIONS; SELECT s1,
+ * example(s1), s2, example(s2) FROM root.sg1.d1;
+ */
+ @Override
+ public void validate(UDFParameterValidator validator) throws Exception {
+ validator
+ // this udf only accepts 1 time series
+ .validateInputSeriesNumber(1)
+ // the data type of the first input time series should be INT32
+ .validateInputSeriesDataType(0, Type.INT32)
+ // this udf doesn't accept any extra parameters
+ // the validation rule is not required because extra parameters will
be ignored
+ .validate(
+ attributes -> ((Map) attributes).isEmpty(),
+ "extra udf parameters are not allowed",
+ validator.getParameters().getAttributes());
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations
configurations) {
+ configurations.setAccessStrategy(new
RowByRowAccessStrategy()).setOutputDataType(Type.INT32);
+ }
+
+ @Override
+ public void transform(Row row, PointCollector collector) throws IOException {
+ if (!row.isNull(0)) {
+ collector.putInt(row.getTime(), -row.getInt(0));
+ }
+ }
+}
diff --git a/example/udf/src/main/java/org/apache/iotdb/udf/GoodUDTF.java
b/example/udf/src/main/java/org/apache/iotdb/udf/GoodUDTF.java
new file mode 100644
index 00000000000..fa8011d4c33
--- /dev/null
+++ b/example/udf/src/main/java/org/apache/iotdb/udf/GoodUDTF.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import org.apache.iotdb.udf.api.UDTF;
+import org.apache.iotdb.udf.api.access.Row;
+import org.apache.iotdb.udf.api.collector.PointCollector;
+import org.apache.iotdb.udf.api.customizer.config.UDTFConfigurations;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameterValidator;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
+import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
+import org.apache.iotdb.udf.api.type.Type;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+/** This is an internal example of the UDTF implementation. */
+public class GoodUDTF implements UDTF {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GoodUDTF.class);
+
+ @Override
+ public Optional<Exception> validate() {
+ // nothing to validate here, this UDTF is always valid
+ LOGGER.info("GoodUDTF: OS info test {}", System.getProperty("os.name"));
+ return Optional.empty();
+ }
+
+ /**
+ * CREATE DATABASE root.sg1; CREATE TIMESERIES root.sg1.d1.s1 WITH
DATATYPE=INT32, ENCODING=PLAIN;
+ * CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT32, ENCODING=PLAIN;
INSERT INTO
+ * root.sg1.d1(timestamp, s1, s2) VALUES (0, -1, 1); INSERT INTO
root.sg1.d1(timestamp, s1, s2)
+ * VALUES (1, -2, 2); INSERT INTO root.sg1.d1(timestamp, s1, s2) VALUES (2,
-3, 3);
+ *
+ * <p>CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample'; SHOW
FUNCTIONS; SELECT s1,
+ * example(s1), s2, example(s2) FROM root.sg1.d1;
+ */
+ @Override
+ public void validate(UDFParameterValidator validator) throws Exception {
+ validator
+ // this udf only accepts 1 time series
+ .validateInputSeriesNumber(1)
+ // the data type of the first input time series should be INT32
+ .validateInputSeriesDataType(0, Type.INT32)
+ // this udf doesn't accept any extra parameters
+ // the validation rule is not required because extra parameters will
be ignored
+ .validate(
+ attributes -> ((Map) attributes).isEmpty(),
+ "extra udf parameters are not allowed",
+ validator.getParameters().getAttributes());
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations
configurations) {
+ configurations.setAccessStrategy(new
RowByRowAccessStrategy()).setOutputDataType(Type.INT32);
+ }
+
+ @Override
+ public void transform(Row row, PointCollector collector) throws IOException {
+ if (!row.isNull(0)) {
+ collector.putInt(row.getTime(), -row.getInt(0));
+ }
+ }
+}
diff --git
a/example/udf/src/main/java/org/apache/iotdb/udf/ValidationFailedUDTF.java
b/example/udf/src/main/java/org/apache/iotdb/udf/ValidationFailedUDTF.java
new file mode 100644
index 00000000000..3cb5437ca57
--- /dev/null
+++ b/example/udf/src/main/java/org/apache/iotdb/udf/ValidationFailedUDTF.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import org.apache.iotdb.udf.api.UDTF;
+import org.apache.iotdb.udf.api.access.Row;
+import org.apache.iotdb.udf.api.collector.PointCollector;
+import org.apache.iotdb.udf.api.customizer.config.UDTFConfigurations;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameterValidator;
+import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters;
+import org.apache.iotdb.udf.api.customizer.strategy.RowByRowAccessStrategy;
+import org.apache.iotdb.udf.api.exception.UDFException;
+import org.apache.iotdb.udf.api.type.Type;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+
+/** This is an internal example of the UDTF implementation. */
+public class ValidationFailedUDTF implements UDTF {
+
+ @Override
+ public Optional<Exception> validate() {
+ return Optional.of(new UDFException("This UDTF is used to test validation
failure."));
+ }
+
+ /**
+ * CREATE DATABASE root.sg1; CREATE TIMESERIES root.sg1.d1.s1 WITH
DATATYPE=INT32, ENCODING=PLAIN;
+ * CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT32, ENCODING=PLAIN;
INSERT INTO
+ * root.sg1.d1(timestamp, s1, s2) VALUES (0, -1, 1); INSERT INTO
root.sg1.d1(timestamp, s1, s2)
+ * VALUES (1, -2, 2); INSERT INTO root.sg1.d1(timestamp, s1, s2) VALUES (2,
-3, 3);
+ *
+ * <p>CREATE FUNCTION example AS 'org.apache.iotdb.udf.UDTFExample'; SHOW
FUNCTIONS; SELECT s1,
+ * example(s1), s2, example(s2) FROM root.sg1.d1;
+ */
+ @Override
+ public void validate(UDFParameterValidator validator) throws Exception {
+ validator
+ // this udf only accepts 1 time series
+ .validateInputSeriesNumber(1)
+ // the data type of the first input time series should be INT32
+ .validateInputSeriesDataType(0, Type.INT32)
+ // this udf doesn't accept any extra parameters
+ // the validation rule is not required because extra parameters will
be ignored
+ .validate(
+ attributes -> ((Map) attributes).isEmpty(),
+ "extra udf parameters are not allowed",
+ validator.getParameters().getAttributes());
+ }
+
+ @Override
+ public void beforeStart(UDFParameters parameters, UDTFConfigurations
configurations) {
+ configurations.setAccessStrategy(new
RowByRowAccessStrategy()).setOutputDataType(Type.INT32);
+ }
+
+ @Override
+ public void transform(Row row, PointCollector collector) throws IOException {
+ if (!row.isNull(0)) {
+ collector.putInt(row.getTime(), -row.getInt(0));
+ }
+ }
+}