Skip to content

Commit 09288da

Browse files
authored
[TABLE MODEL] Implement CREATE/SHOW/DROP Function and user-defined scalar function
1 parent 5c84e68 commit 09288da

File tree

47 files changed

+1940
-109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1940
-109
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.udf;
21+
22+
import org.apache.iotdb.udf.api.customizer.config.ScalarFunctionConfig;
23+
import org.apache.iotdb.udf.api.customizer.parameter.FunctionParameters;
24+
import org.apache.iotdb.udf.api.exception.UDFException;
25+
import org.apache.iotdb.udf.api.exception.UDFParameterNotValidException;
26+
import org.apache.iotdb.udf.api.relational.ScalarFunction;
27+
import org.apache.iotdb.udf.api.relational.access.Record;
28+
import org.apache.iotdb.udf.api.type.Type;
29+
30+
/** This is an internal example of the ScalarFunction implementation. */
31+
public class ScalarFunctionExample implements ScalarFunction {
32+
/**
33+
* CREATE DATABASE test;
34+
*
35+
* <p>USE test;
36+
*
37+
* <p>CREATE TABLE t1(device_id STRING ID, s1 TEXT MEASUREMENT, s2 INT32 MEASUREMENT);
38+
*
39+
* <p>INSERT INTO t1(time, device_id, s1, s2) VALUES (1, 'd1', 'a', 1), (2, 'd1', null, 2), (3,
40+
* 'd1', 'c', null);
41+
*
42+
* <p>CREATE FUNCTION contain_null AS 'org.apache.iotdb.udf.ScalarFunctionExample';
43+
*
44+
* <p>SHOW FUNCTIONS;
45+
*
46+
* <p>SELECT time, device_id, s1, s2, contain_null(s1, s2) as contain_null, contain_null(s1) as
47+
* s1_isnull, contain_null(s2) as s2_isnull FROM t1;
48+
*/
49+
@Override
50+
public void validate(FunctionParameters parameters) throws UDFException {
51+
if (parameters.getChildExpressionsSize() < 1) {
52+
throw new UDFParameterNotValidException("At least one parameter is required.");
53+
}
54+
}
55+
56+
@Override
57+
public void beforeStart(FunctionParameters parameters, ScalarFunctionConfig configurations) {
58+
configurations.setOutputDataType(Type.BOOLEAN);
59+
}
60+
61+
@Override
62+
public Object evaluate(Record input) throws UDFException {
63+
for (int i = 0; i < input.size(); i++) {
64+
if (input.isNull(i)) {
65+
return true;
66+
}
67+
}
68+
return false;
69+
}
70+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.query.udf.example.relational;
21+
22+
import org.apache.iotdb.udf.api.customizer.config.ScalarFunctionConfig;
23+
import org.apache.iotdb.udf.api.customizer.parameter.FunctionParameters;
24+
import org.apache.iotdb.udf.api.exception.UDFException;
25+
import org.apache.iotdb.udf.api.exception.UDFParameterNotValidException;
26+
import org.apache.iotdb.udf.api.relational.ScalarFunction;
27+
import org.apache.iotdb.udf.api.relational.access.Record;
28+
import org.apache.iotdb.udf.api.type.Type;
29+
30+
import java.util.HashSet;
31+
import java.util.Set;
32+
33+
/** Calculate the sum of all parameters. Only support inputs of INT32,INT64,DOUBLE,FLOAT type. */
34+
public class AllSum implements ScalarFunction {
35+
36+
private Type outputDataType;
37+
38+
@Override
39+
public void validate(FunctionParameters parameters) throws UDFException {
40+
if (parameters.getChildExpressionsSize() < 1) {
41+
throw new UDFParameterNotValidException("At least one parameter is required.");
42+
}
43+
for (int i = 0; i < parameters.getChildExpressionsSize(); i++) {
44+
if (parameters.getDataType(i) != Type.INT32
45+
&& parameters.getDataType(i) != Type.INT64
46+
&& parameters.getDataType(i) != Type.FLOAT
47+
&& parameters.getDataType(i) != Type.DOUBLE) {
48+
throw new UDFParameterNotValidException(
49+
"Only support inputs of INT32,INT64,DOUBLE,FLOAT type.");
50+
}
51+
}
52+
}
53+
54+
@Override
55+
public void beforeStart(FunctionParameters parameters, ScalarFunctionConfig configurations) {
56+
Set<Type> inputTypeSet = new HashSet<>();
57+
for (int i = 0; i < parameters.getChildExpressionsSize(); i++) {
58+
inputTypeSet.add(parameters.getDataType(i));
59+
}
60+
if (inputTypeSet.contains(Type.DOUBLE)) {
61+
outputDataType = Type.DOUBLE;
62+
} else if (inputTypeSet.contains(Type.FLOAT)) {
63+
outputDataType = Type.FLOAT;
64+
} else if (inputTypeSet.contains(Type.INT64)) {
65+
outputDataType = Type.INT64;
66+
} else {
67+
outputDataType = Type.INT32;
68+
}
69+
configurations.setOutputDataType(outputDataType);
70+
}
71+
72+
@Override
73+
public Object evaluate(Record input) {
74+
double res = 0;
75+
for (int i = 0; i < input.size(); i++) {
76+
if (!input.isNull(i)) {
77+
switch (input.getDataType(i)) {
78+
case INT32:
79+
res += input.getInt(i);
80+
break;
81+
case INT64:
82+
res += input.getLong(i);
83+
break;
84+
case FLOAT:
85+
res += input.getFloat(i);
86+
break;
87+
case DOUBLE:
88+
res += input.getDouble(i);
89+
break;
90+
}
91+
}
92+
}
93+
switch (outputDataType) {
94+
case INT32:
95+
return (int) res;
96+
case INT64:
97+
return (long) res;
98+
case FLOAT:
99+
return (float) res;
100+
case DOUBLE:
101+
return res;
102+
default:
103+
throw new RuntimeException("Unexpected output type.");
104+
}
105+
}
106+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.query.udf.example.relational;
21+
22+
import org.apache.iotdb.udf.api.customizer.config.ScalarFunctionConfig;
23+
import org.apache.iotdb.udf.api.customizer.parameter.FunctionParameters;
24+
import org.apache.iotdb.udf.api.exception.UDFException;
25+
import org.apache.iotdb.udf.api.exception.UDFParameterNotValidException;
26+
import org.apache.iotdb.udf.api.relational.ScalarFunction;
27+
import org.apache.iotdb.udf.api.relational.access.Record;
28+
import org.apache.iotdb.udf.api.type.Type;
29+
30+
public class ContainNull implements ScalarFunction {
31+
@Override
32+
public void validate(FunctionParameters parameters) throws UDFException {
33+
if (parameters.getChildExpressionsSize() < 1) {
34+
throw new UDFParameterNotValidException("At least one parameter is required.");
35+
}
36+
}
37+
38+
@Override
39+
public void beforeStart(FunctionParameters parameters, ScalarFunctionConfig configurations) {
40+
configurations.setOutputDataType(Type.BOOLEAN);
41+
}
42+
43+
@Override
44+
public Object evaluate(Record input) {
45+
for (int i = 0; i < input.size(); i++) {
46+
if (input.isNull(i)) {
47+
return true;
48+
}
49+
}
50+
return false;
51+
}
52+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.query.udf.example.relational;
21+
22+
import org.apache.iotdb.udf.api.customizer.config.ScalarFunctionConfig;
23+
import org.apache.iotdb.udf.api.customizer.parameter.FunctionParameters;
24+
import org.apache.iotdb.udf.api.exception.UDFException;
25+
import org.apache.iotdb.udf.api.exception.UDFParameterNotValidException;
26+
import org.apache.iotdb.udf.api.relational.ScalarFunction;
27+
import org.apache.iotdb.udf.api.relational.access.Record;
28+
import org.apache.iotdb.udf.api.type.Type;
29+
30+
import java.time.LocalDate;
31+
32+
public class DatePlusOne implements ScalarFunction {
33+
@Override
34+
public void validate(FunctionParameters parameters) throws UDFException {
35+
if (parameters.getChildExpressionsSize() != 2) {
36+
throw new UDFParameterNotValidException("Only two parameter is required.");
37+
}
38+
if (parameters.getDataType(0) != Type.DATE) {
39+
throw new UDFParameterNotValidException("The first parameter should be DATE type.");
40+
}
41+
if (parameters.getDataType(1) != Type.INT32 && parameters.getDataType(1) != Type.INT64) {
42+
throw new UDFParameterNotValidException("The second parameter should be INT type.");
43+
}
44+
}
45+
46+
@Override
47+
public void beforeStart(FunctionParameters parameters, ScalarFunctionConfig configurations) {
48+
configurations.setOutputDataType(Type.DATE);
49+
}
50+
51+
@Override
52+
public Object evaluate(Record input) {
53+
LocalDate date = input.getLocalDate(0);
54+
int days = input.getInt(1);
55+
return date.plusDays(days);
56+
}
57+
}

integration-test/src/test/java/org/apache/iotdb/confignode/it/IoTDBConfigNodeSnapshotIT.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.iotdb.confignode.it;
2121

22+
import org.apache.iotdb.common.rpc.thrift.FunctionType;
2223
import org.apache.iotdb.common.rpc.thrift.Model;
2324
import org.apache.iotdb.common.rpc.thrift.TSStatus;
2425
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
@@ -288,13 +289,15 @@ private List<TCreateFunctionReq> createUDF(SyncConfigNodeIServiceClient client)
288289
TCreateFunctionReq createFunctionReq1 =
289290
new TCreateFunctionReq("test1", "org.apache.iotdb.udf.UDTFExample", true)
290291
.setModel(Model.TREE)
292+
.setFunctionType(FunctionType.NONE)
291293
.setJarName(jarName)
292294
.setJarFile(jarFile)
293295
.setJarMD5(jarMD5);
294296

295297
TCreateFunctionReq createFunctionReq2 =
296298
new TCreateFunctionReq("test2", "org.apache.iotdb.udf.UDTFExample", true)
297299
.setModel(Model.TREE)
300+
.setFunctionType(FunctionType.NONE)
298301
.setJarName(jarName)
299302
.setJarFile(jarFile)
300303
.setJarMD5(jarMD5);

0 commit comments

Comments
 (0)