[fix](multi-catalog)put java udf to custom lib (#34990)

when use java udf , we can put its jars in custom_lib of FE and BE in advance, and then we can create function without file property:
```
CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
    "symbol"="org.apache.doris.udf.AddOne",
    "always_nullable"="true",
    "type"="JAVA_UDF"
);
```

and we can use file property for custom jar:  

```
CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
    "file"="file:///path/to/java-udf-demo.jar",
    "symbol"="org.apache.doris.udf.AddOne",
    "always_nullable"="true",
    "type"="JAVA_UDF"
);
```

on FE, we use null location if the 'file' property is not set
on BE, we get jar path if both file path location and checksum are null
This commit is contained in:
slothever authored and GitHub committed 2024-05-26 14:23:47 +08:00
1 parent 6a430910e6
commit 1e1a223a11
15 files changed
+1272 -174

No files matched your search

@@ -95,8 +95,9 @@ public:
{
TJavaUdfExecutorCtorParams ctor_params;
ctor_params.__set_fn(fn);
ctor_params.__set_location(local_location);
if (!fn.hdfs_location.empty() && !fn.checksum.empty()) {
ctor_params.__set_location(local_location);
}
jbyteArray ctor_params_bytes;
// Pushed frame will be popped when jni_frame goes out-of-scope.
@@ -274,7 +275,13 @@ public:
//So need to check as soon as possible, before call Data function
Status check_udaf(const TFunction& fn) {
auto function_cache = UserFunctionCache::instance();
return function_cache->get_jarpath(fn.id, fn.hdfs_location, fn.checksum, &_local_location);
// get jar path if both file path location and checksum are null
if (!fn.hdfs_location.empty() && !fn.checksum.empty()) {
return function_cache->get_jarpath(fn.id, fn.hdfs_location, fn.checksum,
&_local_location);
} else {
return Status::OK();
}
}
void create(AggregateDataPtr __restrict place) const override {
@@ -57,11 +57,14 @@ Status UDFTableFunction::open() {
{
std::string local_location;
auto* function_cache = UserFunctionCache::instance();
RETURN_IF_ERROR(function_cache->get_jarpath(_t_fn.id, _t_fn.hdfs_location, _t_fn.checksum,
&local_location));
TJavaUdfExecutorCtorParams ctor_params;
ctor_params.__set_fn(_t_fn);
ctor_params.__set_location(local_location);
if (!_t_fn.hdfs_location.empty() && !_t_fn.checksum.empty()) {
// get jar path if both file path location and checksum are null
RETURN_IF_ERROR(function_cache->get_jarpath(_t_fn.id, _t_fn.hdfs_location,
_t_fn.checksum, &local_location));
ctor_params.__set_location(local_location);
}
jbyteArray ctor_params_bytes;
// Pushed frame will be popped when jni_frame goes out-of-scope.
RETURN_IF_ERROR(jni_frame.push(env));
+7 -3
View File
@@ -55,11 +55,15 @@ Status JavaFunctionCall::open(FunctionContext* context, FunctionContext::Functio
{
std::string local_location;
auto function_cache = UserFunctionCache::instance();
RETURN_IF_ERROR(function_cache->get_jarpath(fn_.id, fn_.hdfs_location, fn_.checksum,
&local_location));
TJavaUdfExecutorCtorParams ctor_params;
ctor_params.__set_fn(fn_);
ctor_params.__set_location(local_location);
// get jar path if both file path location and checksum are null
if (!fn_.hdfs_location.empty() && !fn_.checksum.empty()) {
RETURN_IF_ERROR(function_cache->get_jarpath(fn_.id, fn_.hdfs_location, fn_.checksum,
&local_location));
ctor_params.__set_location(local_location);
}
jbyteArray ctor_params_bytes;
// Pushed frame will be popped when jni_frame goes out-of-scope.
+1 -1
View File
@@ -207,7 +207,7 @@ done
# add custom_libs to CLASSPATH
if [[ -d "${DORIS_HOME}/custom_lib" ]]; then
for f in "${DORIS_HOME}/custom_lib"/*.jar; do
CLASSPATH="${f}:${CLASSPATH}"
CLASSPATH="${CLASSPATH}:${f}"
done
fi
@@ -263,10 +263,10 @@ public class CreateFunctionStmt extends DdlStmt {
}
userFile = properties.getOrDefault(FILE_KEY, properties.get(OBJECT_FILE_KEY));
if (Strings.isNullOrEmpty(userFile)) {
throw new AnalysisException("No 'file' or 'object_file' in properties");
}
if (binaryType != TFunctionBinaryType.RPC) {
// if (Strings.isNullOrEmpty(userFile)) {
// throw new AnalysisException("No 'file' or 'object_file' in properties");
// }
if (!Strings.isNullOrEmpty(userFile) && binaryType != TFunctionBinaryType.RPC) {
try {
computeObjectChecksum();
} catch (IOException | NoSuchAlgorithmException e) {
@@ -325,7 +325,12 @@ public class CreateFunctionStmt extends DdlStmt {
throw new AnalysisException("JAVA_UDF OF UDTF return type must be array type");
}
analyzeJavaUdf(symbol);
URI location = URI.create(userFile);
URI location;
if (!Strings.isNullOrEmpty(userFile)) {
location = URI.create(userFile);
} else {
location = null;
}
function = ScalarFunction.createUdf(binaryType,
functionName, argsDef.getArgTypes(),
((ArrayType) (returnType.getType())).getItemType(), argsDef.isVariadic(),
@@ -340,10 +345,15 @@ public class CreateFunctionStmt extends DdlStmt {
private void analyzeUda() throws AnalysisException {
AggregateFunction.AggregateFunctionBuilder builder
= AggregateFunction.AggregateFunctionBuilder.createUdfBuilder();
URI location;
if (!Strings.isNullOrEmpty(userFile)) {
location = URI.create(userFile);
} else {
location = null;
}
builder.name(functionName).argsType(argsDef.getArgTypes()).retType(returnType.getType())
.hasVarArgs(argsDef.isVariadic()).intermediateType(intermediateType.getType())
.location(URI.create(userFile));
.location(location);
String initFnSymbol = properties.get(INIT_KEY);
if (initFnSymbol == null && !(binaryType == TFunctionBinaryType.JAVA_UDF
|| binaryType == TFunctionBinaryType.RPC)) {
@@ -389,8 +399,6 @@ public class CreateFunctionStmt extends DdlStmt {
function = builder.initFnSymbol(initFnSymbol).updateFnSymbol(updateFnSymbol).mergeFnSymbol(mergeFnSymbol)
.serializeFnSymbol(serializeFnSymbol).finalizeFnSymbol(finalizeFnSymbol)
.getValueFnSymbol(getValueFnSymbol).removeFnSymbol(removeFnSymbol).symbolName(symbol).build();
URI location = URI.create(userFile);
function.setLocation(location);
function.setBinaryType(binaryType);
function.setChecksum(checksum);
@@ -414,7 +422,12 @@ public class CreateFunctionStmt extends DdlStmt {
} else if (binaryType == TFunctionBinaryType.JAVA_UDF) {
analyzeJavaUdf(symbol);
}
URI location = URI.create(userFile);
URI location;
if (!Strings.isNullOrEmpty(userFile)) {
location = URI.create(userFile);
} else {
location = null;
}
function = ScalarFunction.createUdf(binaryType,
functionName, argsDef.getArgTypes(),
returnType.getType(), argsDef.isVariadic(),
@@ -427,94 +440,18 @@ public class CreateFunctionStmt extends DdlStmt {
HashMap<String, Method> allMethods = new HashMap<>();
try {
if (Strings.isNullOrEmpty(userFile)) {
try {
ClassLoader cl = this.getClass().getClassLoader();
checkUdafClass(clazz, cl, allMethods);
return;
} catch (ClassNotFoundException e) {
throw new AnalysisException("Class [" + clazz + "] not found in classpath");
}
}
URL[] urls = {new URL("jar:" + userFile + "!/")};
try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {
Class udfClass = cl.loadClass(clazz);
String udfClassName = udfClass.getCanonicalName();
String stateClassName = udfClassName + "$" + STATE_CLASS_NAME;
Class stateClass = cl.loadClass(stateClassName);
for (Method m : udfClass.getMethods()) {
if (!m.getDeclaringClass().equals(udfClass)) {
continue;
}
String name = m.getName();
if (allMethods.containsKey(name)) {
throw new AnalysisException(
String.format("UDF class '%s' has multiple methods with name '%s' ", udfClassName,
name));
}
allMethods.put(name, m);
}
if (allMethods.get(CREATE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", CREATE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(CREATE_METHOD_NAME, allMethods.get(CREATE_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(CREATE_METHOD_NAME), 0, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(CREATE_METHOD_NAME), stateClass);
}
if (allMethods.get(DESTROY_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", DESTROY_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(DESTROY_METHOD_NAME, allMethods.get(DESTROY_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(DESTROY_METHOD_NAME), 1, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(DESTROY_METHOD_NAME), void.class);
}
if (allMethods.get(ADD_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", ADD_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(ADD_METHOD_NAME, allMethods.get(ADD_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(ADD_METHOD_NAME), argsDef.getArgTypes().length + 1, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(ADD_METHOD_NAME), void.class);
for (int i = 0; i < argsDef.getArgTypes().length; i++) {
Parameter p = allMethods.get(ADD_METHOD_NAME).getParameters()[i + 1];
checkUdfType(udfClass, allMethods.get(ADD_METHOD_NAME), argsDef.getArgTypes()[i], p.getType(),
p.getName());
}
}
if (allMethods.get(SERIALIZE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", SERIALIZE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(SERIALIZE_METHOD_NAME, allMethods.get(SERIALIZE_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(SERIALIZE_METHOD_NAME), 2, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(SERIALIZE_METHOD_NAME), void.class);
}
if (allMethods.get(MERGE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", MERGE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(MERGE_METHOD_NAME, allMethods.get(MERGE_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(MERGE_METHOD_NAME), 2, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(MERGE_METHOD_NAME), void.class);
}
if (allMethods.get(GETVALUE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", GETVALUE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(GETVALUE_METHOD_NAME, allMethods.get(GETVALUE_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(GETVALUE_METHOD_NAME), 1, udfClassName);
checkReturnUdfType(udfClass, allMethods.get(GETVALUE_METHOD_NAME), returnType.getType());
}
if (!Modifier.isPublic(stateClass.getModifiers()) || !Modifier.isStatic(stateClass.getModifiers())) {
throw new AnalysisException(
String.format(
"UDAF '%s' should have one public & static 'State' class to Construction data ",
udfClassName));
}
checkUdafClass(clazz, cl, allMethods);
} catch (ClassNotFoundException e) {
throw new AnalysisException(
"Class [" + clazz + "] or inner class [State] not found in file :" + userFile);
@@ -526,6 +463,96 @@ public class CreateFunctionStmt extends DdlStmt {
}
}
private void checkUdafClass(String clazz, ClassLoader cl, HashMap<String, Method> allMethods)
throws ClassNotFoundException, AnalysisException {
Class udfClass = cl.loadClass(clazz);
String udfClassName = udfClass.getCanonicalName();
String stateClassName = udfClassName + "$" + STATE_CLASS_NAME;
Class stateClass = cl.loadClass(stateClassName);
for (Method m : udfClass.getMethods()) {
if (!m.getDeclaringClass().equals(udfClass)) {
continue;
}
String name = m.getName();
if (allMethods.containsKey(name)) {
throw new AnalysisException(
String.format("UDF class '%s' has multiple methods with name '%s' ", udfClassName,
name));
}
allMethods.put(name, m);
}
if (allMethods.get(CREATE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", CREATE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(CREATE_METHOD_NAME, allMethods.get(CREATE_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(CREATE_METHOD_NAME), 0, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(CREATE_METHOD_NAME), stateClass);
}
if (allMethods.get(DESTROY_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", DESTROY_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(DESTROY_METHOD_NAME, allMethods.get(DESTROY_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(DESTROY_METHOD_NAME), 1, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(DESTROY_METHOD_NAME), void.class);
}
if (allMethods.get(ADD_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", ADD_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(ADD_METHOD_NAME, allMethods.get(ADD_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(ADD_METHOD_NAME), argsDef.getArgTypes().length + 1, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(ADD_METHOD_NAME), void.class);
for (int i = 0; i < argsDef.getArgTypes().length; i++) {
Parameter p = allMethods.get(ADD_METHOD_NAME).getParameters()[i + 1];
checkUdfType(udfClass, allMethods.get(ADD_METHOD_NAME), argsDef.getArgTypes()[i], p.getType(),
p.getName());
}
}
if (allMethods.get(SERIALIZE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", SERIALIZE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(SERIALIZE_METHOD_NAME, allMethods.get(SERIALIZE_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(SERIALIZE_METHOD_NAME), 2, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(SERIALIZE_METHOD_NAME), void.class);
}
if (allMethods.get(MERGE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", MERGE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(MERGE_METHOD_NAME, allMethods.get(MERGE_METHOD_NAME), udfClassName);
checkArgumentCount(allMethods.get(MERGE_METHOD_NAME), 2, udfClassName);
checkReturnJavaType(udfClassName, allMethods.get(MERGE_METHOD_NAME), void.class);
}
if (allMethods.get(GETVALUE_METHOD_NAME) == null) {
throw new AnalysisException(
String.format("No method '%s' in class '%s'!", GETVALUE_METHOD_NAME, udfClassName));
} else {
checkMethodNonStaticAndPublic(GETVALUE_METHOD_NAME, allMethods.get(GETVALUE_METHOD_NAME),
udfClassName);
checkArgumentCount(allMethods.get(GETVALUE_METHOD_NAME), 1, udfClassName);
checkReturnUdfType(udfClass, allMethods.get(GETVALUE_METHOD_NAME), returnType.getType());
}
if (!Modifier.isPublic(stateClass.getModifiers()) || !Modifier.isStatic(stateClass.getModifiers())) {
throw new AnalysisException(
String.format(
"UDAF '%s' should have one public & static 'State' class to Construction data ",
udfClassName));
}
}
private void checkMethodNonStaticAndPublic(String methoName, Method method, String udfClassName)
throws AnalysisException {
if (Modifier.isStatic(method.getModifiers())) {
@@ -565,60 +592,18 @@ public class CreateFunctionStmt extends DdlStmt {
private void analyzeJavaUdf(String clazz) throws AnalysisException {
try {
if (Strings.isNullOrEmpty(userFile)) {
try {
ClassLoader cl = this.getClass().getClassLoader();
checkUdfClass(clazz, cl);
return;
} catch (ClassNotFoundException e) {
throw new AnalysisException("Class [" + clazz + "] not found in classpath");
}
}
URL[] urls = {new URL("jar:" + userFile + "!/")};
try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {
Class udfClass = cl.loadClass(clazz);
List<Method> evalList = Arrays.stream(udfClass.getMethods())
.filter(m -> m.getDeclaringClass().equals(udfClass) && EVAL_METHOD_KEY.equals(m.getName()))
.collect(Collectors.toList());
if (evalList.size() == 0) {
throw new AnalysisException(String.format(
"No method '%s' in class '%s'!", EVAL_METHOD_KEY, udfClass.getCanonicalName()));
}
List<Method> evalNonStaticAndPublicList = evalList.stream()
.filter(m -> !Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers()))
.collect(Collectors.toList());
if (evalNonStaticAndPublicList.size() == 0) {
throw new AnalysisException(
String.format("Method '%s' in class '%s' should be non-static and public", EVAL_METHOD_KEY,
udfClass.getCanonicalName()));
}
List<Method> evalArgLengthMatchList = evalNonStaticAndPublicList.stream().filter(
m -> m.getParameters().length == argsDef.getArgTypes().length).collect(Collectors.toList());
if (evalArgLengthMatchList.size() == 0) {
throw new AnalysisException(
String.format("The number of parameters for method '%s' in class '%s' should be %d",
EVAL_METHOD_KEY, udfClass.getCanonicalName(), argsDef.getArgTypes().length));
} else if (evalArgLengthMatchList.size() == 1) {
Method method = evalArgLengthMatchList.get(0);
checkUdfType(udfClass, method, returnType.getType(), method.getReturnType(), "return");
for (int i = 0; i < method.getParameters().length; i++) {
Parameter p = method.getParameters()[i];
checkUdfType(udfClass, method, argsDef.getArgTypes()[i], p.getType(), p.getName());
}
} else {
// If multiple methods have the same parameters,
// the error message returned cannot be as specific as a single method
boolean hasError = false;
for (Method method : evalArgLengthMatchList) {
try {
checkUdfType(udfClass, method, returnType.getType(), method.getReturnType(), "return");
for (int i = 0; i < method.getParameters().length; i++) {
Parameter p = method.getParameters()[i];
checkUdfType(udfClass, method, argsDef.getArgTypes()[i], p.getType(), p.getName());
}
hasError = false;
break;
} catch (AnalysisException e) {
hasError = true;
}
}
if (hasError) {
throw new AnalysisException(String.format(
"Multi methods '%s' in class '%s' and no one passed parameter matching verification",
EVAL_METHOD_KEY, udfClass.getCanonicalName()));
}
}
checkUdfClass(clazz, cl);
} catch (ClassNotFoundException e) {
throw new AnalysisException("Class [" + clazz + "] not found in file :" + userFile);
} catch (IOException e) {
@@ -629,6 +614,61 @@ public class CreateFunctionStmt extends DdlStmt {
}
}
private void checkUdfClass(String clazz, ClassLoader cl) throws ClassNotFoundException, AnalysisException {
Class udfClass = cl.loadClass(clazz);
List<Method> evalList = Arrays.stream(udfClass.getMethods())
.filter(m -> m.getDeclaringClass().equals(udfClass) && EVAL_METHOD_KEY.equals(m.getName()))
.collect(Collectors.toList());
if (evalList.size() == 0) {
throw new AnalysisException(String.format(
"No method '%s' in class '%s'!", EVAL_METHOD_KEY, udfClass.getCanonicalName()));
}
List<Method> evalNonStaticAndPublicList = evalList.stream()
.filter(m -> !Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers()))
.collect(Collectors.toList());
if (evalNonStaticAndPublicList.size() == 0) {
throw new AnalysisException(
String.format("Method '%s' in class '%s' should be non-static and public", EVAL_METHOD_KEY,
udfClass.getCanonicalName()));
}
List<Method> evalArgLengthMatchList = evalNonStaticAndPublicList.stream().filter(
m -> m.getParameters().length == argsDef.getArgTypes().length).collect(Collectors.toList());
if (evalArgLengthMatchList.size() == 0) {
throw new AnalysisException(
String.format("The number of parameters for method '%s' in class '%s' should be %d",
EVAL_METHOD_KEY, udfClass.getCanonicalName(), argsDef.getArgTypes().length));
} else if (evalArgLengthMatchList.size() == 1) {
Method method = evalArgLengthMatchList.get(0);
checkUdfType(udfClass, method, returnType.getType(), method.getReturnType(), "return");
for (int i = 0; i < method.getParameters().length; i++) {
Parameter p = method.getParameters()[i];
checkUdfType(udfClass, method, argsDef.getArgTypes()[i], p.getType(), p.getName());
}
} else {
// If multiple methods have the same parameters,
// the error message returned cannot be as specific as a single method
boolean hasError = false;
for (Method method : evalArgLengthMatchList) {
try {
checkUdfType(udfClass, method, returnType.getType(), method.getReturnType(), "return");
for (int i = 0; i < method.getParameters().length; i++) {
Parameter p = method.getParameters()[i];
checkUdfType(udfClass, method, argsDef.getArgTypes()[i], p.getType(), p.getName());
}
hasError = false;
break;
} catch (AnalysisException e) {
hasError = true;
}
}
if (hasError) {
throw new AnalysisException(String.format(
"Multi methods '%s' in class '%s' and no one passed parameter matching verification",
EVAL_METHOD_KEY, udfClass.getCanonicalName()));
}
}
}
private void checkUdfType(Class clazz, Method method, Type expType, Class pType, String pname)
throws AnalysisException {
Set<Class> javaTypes;
@@ -151,7 +151,7 @@ public class JavaUdaf extends AggregateFunction implements ExplicitlyCastableSig
JavaUdaf udaf = new JavaUdaf(fnName, aggregate.getId(), dbName, aggregate.getBinaryType(), sig,
intermediateType,
aggregate.getNullableMode(),
aggregate.getLocation().getLocation(),
aggregate.getLocation() == null ? null : aggregate.getLocation().getLocation(),
aggregate.getSymbolName(),
aggregate.getInitFnSymbol(),
aggregate.getUpdateFnSymbol(),
@@ -182,7 +182,7 @@ public class JavaUdaf extends AggregateFunction implements ExplicitlyCastableSig
signature.returnType.toCatalogDataType(),
signature.hasVarArgs,
intermediateType.toCatalogDataType(),
URI.create(objectFile),
objectFile == null ? null : URI.create(objectFile),
initFn,
updateFn,
mergeFn,
@@ -129,7 +129,7 @@ public class JavaUdf extends ScalarFunction implements ExplicitlyCastableSignatu
JavaUdf udf = new JavaUdf(fnName, scalar.getId(), dbName, scalar.getBinaryType(), sig,
scalar.getNullableMode(),
scalar.getLocation().getLocation(),
scalar.getLocation() == null ? null : scalar.getLocation().getLocation(),
scalar.getSymbolName(),
scalar.getPrepareFnSymbol(),
scalar.getCloseFnSymbol(),
@@ -154,7 +154,7 @@ public class JavaUdf extends ScalarFunction implements ExplicitlyCastableSignatu
signature.argumentsTypes.stream().map(DataType::toCatalogDataType).toArray(Type[]::new),
signature.returnType.toCatalogDataType(),
signature.hasVarArgs,
URI.create(objectFile),
objectFile == null ? null : URI.create(objectFile),
symbol,
prepareFn,
closeFn
@@ -111,7 +111,7 @@ public class JavaUdtf extends TableGeneratingFunction implements ExplicitlyCasta
signature.argumentsTypes.stream().map(DataType::toCatalogDataType).toArray(Type[]::new),
signature.returnType.toCatalogDataType(),
signature.hasVarArgs,
URI.create(objectFile),
objectFile == null ? null : URI.create(objectFile),
symbol,
prepareFn,
closeFn
@@ -148,7 +148,7 @@ public class JavaUdtf extends TableGeneratingFunction implements ExplicitlyCasta
JavaUdtf udf = new JavaUdtf(fnName, scalar.getId(), dbName, scalar.getBinaryType(), sig,
scalar.getNullableMode(),
scalar.getLocation().getLocation(),
scalar.getLocation() == null ? null : scalar.getLocation().getLocation(),
scalar.getSymbolName(),
scalar.getPrepareFnSymbol(),
scalar.getCloseFnSymbol(),
@@ -0,0 +1,20 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !select_default --
1 1 abcdefg1 poiuytre1abcdefg
2 2 abcdefg2 poiuytre2abcdefg
0 3 abcdefg3 poiuytre3abcdefg
1 4 abcdefg4 poiuytre4abcdefg
2 5 abcdefg5 poiuytre5abcdefg
0 6 abcdefg6 poiuytre6abcdefg
1 7 abcdefg7 poiuytre7abcdefg
2 8 abcdefg8 poiuytre8abcdefg
9 9 abcdefg9 poiuytre9abcdefg
-- !select1 --
18
-- !select2 --
0 0
1 3
2 6
9 9
@@ -0,0 +1,12 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !java_udf_all_types --
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
@@ -0,0 +1,692 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !select --
\N \N \N \N \N \N \N \N \N \N \N \N \N \N
1 true 1 2 3 4 3.3300 7.77 3.1415 2023-10-18 2023-10-11T10:11:11.234 row1 [null, "nested1"] {"k1":null, "k2":"value1"}
2 false 2 4 6 8 1.6650 3.885 1.57075 2023-10-19 2023-10-12T10:12:11.234 row2 [null, "nested2"] {"k2":null, "k3":"value2"}
3 true 3 6 9 12 1.1100 2.59 1.04717 2023-10-20 2023-10-13T10:13:11.234 row3 [null, "nested3"] {"k3":null, "k4":"value3"}
4 false 4 8 12 16 0.8325 1.943 0.78538 2023-10-21 2023-10-14T10:14:11.234 row4 [null, "nested4"] {"k4":null, "k5":"value4"}
5 true 5 10 15 20 0.6660 1.554 0.6283 2023-10-22 2023-10-15T10:15:11.234 row5 [null, "nested5"] {"k5":null, "k6":"value5"}
6 false 6 12 18 24 0.5550 1.295 0.52358 2023-10-23 2023-10-16T10:16:11.234 row6 [null, "nested6"] {"k6":null, "k7":"value6"}
7 true 7 14 21 28 0.4757 1.11 0.44879 2023-10-24 2023-10-17T10:17:11.234 row7 [null, "nested7"] {"k7":null, "k8":"value7"}
8 false 8 16 24 32 0.4163 0.971 0.39269 2023-10-25 2023-10-18T10:18:11.234 row8 [null, "nested8"] {"k8":null, "k9":"value8"}
9 true 9 18 27 36 0.3700 0.863 0.34906 2023-10-26 2023-10-19T10:19:11.234 row9 [null, "nested9"] {"k9":null, "k10":"value9"}
10 false \N 20 30 40 \N 0.777 0.31415 \N 2023-10-20T10:10:11.234 \N [null, "nested10"] {"k10":null, "k11":"value10"}
-- !select_boolean_col --
1 true true
2 false false
2 false true
3 true false
3 true true
3 true true
4 false false
4 false false
4 false true
4 false true
5 true false
5 true false
5 true true
5 true true
5 true true
6 false false
6 false false
6 false false
6 false true
6 false true
6 false true
7 true false
7 true false
7 true false
7 true true
7 true true
7 true true
7 true true
8 false false
8 false false
8 false false
8 false false
8 false true
8 false true
8 false true
8 false true
9 true false
9 true false
9 true false
9 true false
9 true true
9 true true
9 true true
9 true true
9 true true
10 false false
10 false false
10 false false
10 false false
10 false false
10 false true
10 false true
10 false true
10 false true
10 false true
-- !select_tinyint_col --
1 1 1
2 2 2
2 2 3
3 3 3
3 3 4
3 3 5
4 4 4
4 4 5
4 4 6
4 4 7
5 5 5
5 5 6
5 5 7
5 5 8
5 5 9
6 6 6
6 6 7
6 6 8
6 6 9
6 6 10
6 6 11
7 7 7
7 7 8
7 7 9
7 7 10
7 7 11
7 7 12
7 7 13
8 8 8
8 8 9
8 8 10
8 8 11
8 8 12
8 8 13
8 8 14
8 8 15
9 9 9
9 9 10
9 9 11
9 9 12
9 9 13
9 9 14
9 9 15
9 9 16
9 9 17
-- !select_smallint_col --
1 2 2
2 4 4
2 4 6
3 6 6
3 6 8
3 6 10
4 8 8
4 8 10
4 8 12
4 8 14
5 10 10
5 10 12
5 10 14
5 10 16
5 10 18
6 12 12
6 12 14
6 12 16
6 12 18
6 12 20
6 12 22
7 14 14
7 14 16
7 14 18
7 14 20
7 14 22
7 14 24
7 14 26
8 16 16
8 16 18
8 16 20
8 16 22
8 16 24
8 16 26
8 16 28
8 16 30
9 18 18
9 18 20
9 18 22
9 18 24
9 18 26
9 18 28
9 18 30
9 18 32
9 18 34
10 20 20
10 20 22
10 20 24
10 20 26
10 20 28
10 20 30
10 20 32
10 20 34
10 20 36
10 20 38
-- !select_int_col --
1 1 1
2 2 2
2 2 5
3 3 3
3 3 6
3 3 9
4 4 4
4 4 7
4 4 10
4 4 13
5 5 5
5 5 8
5 5 11
5 5 14
5 5 17
6 6 6
6 6 9
6 6 12
6 6 15
6 6 18
6 6 21
7 7 7
7 7 10
7 7 13
7 7 16
7 7 19
7 7 22
7 7 25
8 8 8
8 8 11
8 8 14
8 8 17
8 8 20
8 8 23
8 8 26
8 8 29
9 9 9
9 9 12
9 9 15
9 9 18
9 9 21
9 9 24
9 9 27
9 9 30
9 9 33
10 10 10
10 10 13
10 10 16
10 10 19
10 10 22
10 10 25
10 10 28
10 10 31
10 10 34
10 10 37
-- !select_bigint_col --
1 3 3
2 6 6
2 6 10
3 9 9
3 9 13
3 9 17
4 12 12
4 12 16
4 12 20
4 12 24
5 15 15
5 15 19
5 15 23
5 15 27
5 15 31
6 18 18
6 18 22
6 18 26
6 18 30
6 18 34
6 18 38
7 21 21
7 21 25
7 21 29
7 21 33
7 21 37
7 21 41
7 21 45
8 24 24
8 24 28
8 24 32
8 24 36
8 24 40
8 24 44
8 24 48
8 24 52
9 27 27
9 27 31
9 27 35
9 27 39
9 27 43
9 27 47
9 27 51
9 27 55
9 27 59
10 30 30
10 30 34
10 30 38
10 30 42
10 30 46
10 30 50
10 30 54
10 30 58
10 30 62
10 30 66
-- !select_largeint_col --
1 4 4
2 8 8
2 8 13
3 12 12
3 12 17
3 12 22
4 16 16
4 16 21
4 16 26
4 16 31
5 20 20
5 20 25
5 20 30
5 20 35
5 20 40
6 24 24
6 24 29
6 24 34
6 24 39
6 24 44
6 24 49
7 28 28
7 28 33
7 28 38
7 28 43
7 28 48
7 28 53
7 28 58
8 32 32
8 32 37
8 32 42
8 32 47
8 32 52
8 32 57
8 32 62
8 32 67
9 36 36
9 36 41
9 36 46
9 36 51
9 36 56
9 36 61
9 36 66
9 36 71
9 36 76
10 40 40
10 40 45
10 40 50
10 40 55
10 40 60
10 40 65
10 40 70
10 40 75
10 40 80
10 40 85
-- !select_decimal_col --
1 3.3300 3.3300
2 1.6650 1.6650
2 1.6650 1.6660
3 1.1100 1.1100
3 1.1100 1.1110
3 1.1100 1.1120
4 0.8325 0.8325
4 0.8325 0.8335
4 0.8325 0.8345
4 0.8325 0.8355
5 0.6660 0.6660
5 0.6660 0.6670
5 0.6660 0.6680
5 0.6660 0.6690
5 0.6660 0.6700
6 0.5550 0.5550
6 0.5550 0.5560
6 0.5550 0.5570
6 0.5550 0.5580
6 0.5550 0.5590
6 0.5550 0.5600
7 0.4757 0.4757
7 0.4757 0.4767
7 0.4757 0.4777
7 0.4757 0.4787
7 0.4757 0.4797
7 0.4757 0.4807
7 0.4757 0.4817
8 0.4163 0.4163
8 0.4163 0.4173
8 0.4163 0.4183
8 0.4163 0.4193
8 0.4163 0.4203
8 0.4163 0.4213
8 0.4163 0.4223
8 0.4163 0.4233
9 0.3700 0.3700
9 0.3700 0.3710
9 0.3700 0.3720
9 0.3700 0.3730
9 0.3700 0.3740
9 0.3700 0.3750
9 0.3700 0.3760
9 0.3700 0.3770
9 0.3700 0.3780
-- !select_float_col --
1 7.77 7.77
2 3.885 3.885
2 3.885 3.985
3 2.59 2.59
3 2.59 2.6899998
3 2.59 2.79
4 1.943 1.943
4 1.943 2.043
4 1.943 2.143
4 1.943 2.243
5 1.554 1.554
5 1.554 1.654
5 1.554 1.7540001
5 1.554 1.854
5 1.554 1.954
6 1.295 1.295
6 1.295 1.395
6 1.295 1.495
6 1.295 1.5949999
6 1.295 1.6949999
6 1.295 1.795
7 1.11 1.11
7 1.11 1.21
7 1.11 1.3100001
7 1.11 1.41
7 1.11 1.51
7 1.11 1.61
7 1.11 1.71
8 0.971 0.971
8 0.971 1.071
8 0.971 1.171
8 0.971 1.271
8 0.971 1.371
8 0.971 1.471
8 0.971 1.571
8 0.971 1.671
9 0.863 0.863
9 0.863 0.963
9 0.863 1.063
9 0.863 1.163
9 0.863 1.263
9 0.863 1.3629999
9 0.863 1.4629999
9 0.863 1.563
9 0.863 1.663
10 0.777 0.777
10 0.777 0.87700003
10 0.777 0.977
10 0.777 1.077
10 0.777 1.177
10 0.777 1.277
10 0.777 1.377
10 0.777 1.477
10 0.777 1.577
10 0.777 1.677
-- !select_double_col --
1 3.1415 3.1415
2 1.57075 1.57075
2 1.57075 1.58075
3 1.04717 1.04717
3 1.04717 1.05717
3 1.04717 1.06717
4 0.78538 0.78538
4 0.78538 0.79538
4 0.78538 0.80538
4 0.78538 0.81538
5 0.6283 0.6283
5 0.6283 0.6383
5 0.6283 0.6483
5 0.6283 0.6583
5 0.6283 0.6683
6 0.52358 0.52358
6 0.52358 0.53358
6 0.52358 0.5435800000000001
6 0.52358 0.5535800000000001
6 0.52358 0.5635800000000001
6 0.52358 0.5735800000000001
7 0.44879 0.44879
7 0.44879 0.45879000000000003
7 0.44879 0.46879000000000004
7 0.44879 0.47879000000000005
7 0.44879 0.48879
7 0.44879 0.49879
7 0.44879 0.5087900000000001
8 0.39269 0.39269
8 0.39269 0.40269
8 0.39269 0.41269
8 0.39269 0.42269
8 0.39269 0.43268999999999996
8 0.39269 0.44269
8 0.39269 0.45269
8 0.39269 0.46269
9 0.34906 0.34906
9 0.34906 0.35906
9 0.34906 0.36906
9 0.34906 0.37905999999999995
9 0.34906 0.38905999999999996
9 0.34906 0.39905999999999997
9 0.34906 0.40906
9 0.34906 0.41906
9 0.34906 0.42906
10 0.31415 0.31415
10 0.31415 0.32415
10 0.31415 0.33415
10 0.31415 0.34414999999999996
10 0.31415 0.35414999999999996
10 0.31415 0.36415
10 0.31415 0.37415
10 0.31415 0.38415
10 0.31415 0.39415
10 0.31415 0.40415
-- !select_date_col --
1 2023-10-18 2023-10-18
2 2023-10-19 2023-10-19
2 2023-10-19 2023-11-19
3 2023-10-20 2023-10-20
3 2023-10-20 2023-11-20
3 2023-10-20 2023-12-20
4 2023-10-21 2023-10-21
4 2023-10-21 2023-11-21
4 2023-10-21 2023-12-21
4 2023-10-21 2024-01-21
5 2023-10-22 2023-10-22
5 2023-10-22 2023-11-22
5 2023-10-22 2023-12-22
5 2023-10-22 2024-01-22
5 2023-10-22 2024-02-22
6 2023-10-23 2023-10-23
6 2023-10-23 2023-11-23
6 2023-10-23 2023-12-23
6 2023-10-23 2024-01-23
6 2023-10-23 2024-02-23
6 2023-10-23 2024-03-23
7 2023-10-24 2023-10-24
7 2023-10-24 2023-11-24
7 2023-10-24 2023-12-24
7 2023-10-24 2024-01-24
7 2023-10-24 2024-02-24
7 2023-10-24 2024-03-24
7 2023-10-24 2024-04-24
8 2023-10-25 2023-10-25
8 2023-10-25 2023-11-25
8 2023-10-25 2023-12-25
8 2023-10-25 2024-01-25
8 2023-10-25 2024-02-25
8 2023-10-25 2024-03-25
8 2023-10-25 2024-04-25
8 2023-10-25 2024-05-25
9 2023-10-26 2023-10-26
9 2023-10-26 2023-11-26
9 2023-10-26 2023-12-26
9 2023-10-26 2024-01-26
9 2023-10-26 2024-02-26
9 2023-10-26 2024-03-26
9 2023-10-26 2024-04-26
9 2023-10-26 2024-05-26
9 2023-10-26 2024-06-26
-- !select_datetime_col --
1 2023-10-11T10:11:11.234 2023-10-11T10:11:11.234
2 2023-10-12T10:12:11.234 2023-10-12T10:12:11.234
2 2023-10-12T10:12:11.234 2023-10-13T10:12:11.234
3 2023-10-13T10:13:11.234 2023-10-13T10:13:11.234
3 2023-10-13T10:13:11.234 2023-10-14T10:13:11.234
3 2023-10-13T10:13:11.234 2023-10-15T10:13:11.234
4 2023-10-14T10:14:11.234 2023-10-14T10:14:11.234
4 2023-10-14T10:14:11.234 2023-10-15T10:14:11.234
4 2023-10-14T10:14:11.234 2023-10-16T10:14:11.234
4 2023-10-14T10:14:11.234 2023-10-17T10:14:11.234
5 2023-10-15T10:15:11.234 2023-10-15T10:15:11.234
5 2023-10-15T10:15:11.234 2023-10-16T10:15:11.234
5 2023-10-15T10:15:11.234 2023-10-17T10:15:11.234
5 2023-10-15T10:15:11.234 2023-10-18T10:15:11.234
5 2023-10-15T10:15:11.234 2023-10-19T10:15:11.234
6 2023-10-16T10:16:11.234 2023-10-16T10:16:11.234
6 2023-10-16T10:16:11.234 2023-10-17T10:16:11.234
6 2023-10-16T10:16:11.234 2023-10-18T10:16:11.234
6 2023-10-16T10:16:11.234 2023-10-19T10:16:11.234
6 2023-10-16T10:16:11.234 2023-10-20T10:16:11.234
6 2023-10-16T10:16:11.234 2023-10-21T10:16:11.234
7 2023-10-17T10:17:11.234 2023-10-17T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-18T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-19T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-20T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-21T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-22T10:17:11.234
7 2023-10-17T10:17:11.234 2023-10-23T10:17:11.234
8 2023-10-18T10:18:11.234 2023-10-18T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-19T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-20T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-21T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-22T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-23T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-24T10:18:11.234
8 2023-10-18T10:18:11.234 2023-10-25T10:18:11.234
9 2023-10-19T10:19:11.234 2023-10-19T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-20T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-21T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-22T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-23T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-24T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-25T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-26T10:19:11.234
9 2023-10-19T10:19:11.234 2023-10-27T10:19:11.234
10 2023-10-20T10:10:11.234 2023-10-20T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-21T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-22T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-23T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-24T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-25T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-26T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-27T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-28T10:10:11.234
10 2023-10-20T10:10:11.234 2023-10-29T10:10:11.234
-- !select_string_col --
1 row1 1
1 row1 o
1 row1 r
1 row1 w
2 row2 2
2 row2 o
2 row2 r
2 row2 w
3 row3 3
3 row3 o
3 row3 r
3 row3 w
4 row4 4
4 row4 o
4 row4 r
4 row4 w
5 row5 5
5 row5 o
5 row5 r
5 row5 w
6 row6 6
6 row6 o
6 row6 r
6 row6 w
7 row7 7
7 row7 o
7 row7 r
7 row7 w
8 row8 8
8 row8 o
8 row8 r
8 row8 w
9 row9 9
9 row9 o
9 row9 r
9 row9 w
-- !select_array_col --
1 [null, "nested1"] \N
1 [null, "nested1"] nested1
2 [null, "nested2"] \N
2 [null, "nested2"] nested2
3 [null, "nested3"] \N
3 [null, "nested3"] nested3
4 [null, "nested4"] \N
4 [null, "nested4"] nested4
5 [null, "nested5"] \N
5 [null, "nested5"] nested5
6 [null, "nested6"] \N
6 [null, "nested6"] nested6
7 [null, "nested7"] \N
7 [null, "nested7"] nested7
8 [null, "nested8"] \N
8 [null, "nested8"] nested8
9 [null, "nested9"] \N
9 [null, "nested9"] nested9
10 [null, "nested10"] \N
10 [null, "nested10"] nested10
-- !select_map_col --
1 {"k1":null, "k2":"value1"} k1
1 {"k1":null, "k2":"value1"} k2
2 {"k2":null, "k3":"value2"} \N
2 {"k2":null, "k3":"value2"} value2
3 {"k3":null, "k4":"value3"} k3
3 {"k3":null, "k4":"value3"} k4
4 {"k4":null, "k5":"value4"} \N
4 {"k4":null, "k5":"value4"} value4
5 {"k5":null, "k6":"value5"} k5
5 {"k5":null, "k6":"value5"} k6
6 {"k6":null, "k7":"value6"} \N
6 {"k6":null, "k7":"value6"} value6
7 {"k7":null, "k8":"value7"} k7
7 {"k7":null, "k8":"value7"} k8
8 {"k8":null, "k9":"value8"} \N
8 {"k8":null, "k9":"value8"} value8
9 {"k9":null, "k10":"value9"} k10
9 {"k9":null, "k10":"value9"} k9
10 {"k10":null, "k11":"value10"} \N
10 {"k10":null, "k11":"value10"} value10
@@ -0,0 +1,64 @@
// 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.
import org.codehaus.groovy.runtime.IOGroovyMethods
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
suite("test_javaudaf_custom_lib_mysum_int") {
def tableName = "test_javaudaf_custom_lib_mysum_int"
try {
sql """ DROP TABLE IF EXISTS ${tableName} """
sql """
CREATE TABLE IF NOT EXISTS ${tableName} (
`user_id` INT NOT NULL COMMENT "用户id",
`char_col` CHAR NOT NULL COMMENT "",
`varchar_col` VARCHAR(10) NOT NULL COMMENT "",
`string_col` STRING NOT NULL COMMENT ""
)
DISTRIBUTED BY HASH(user_id) PROPERTIES("replication_num" = "1");
"""
StringBuilder sb = new StringBuilder()
int i = 1
for (; i < 9; i ++) {
sb.append("""
(${i % 3}, '${i}','abcdefg${i}','poiuytre${i}abcdefg'),
""")
}
sb.append("""
(${i}, '${i}','abcdefg${i}','poiuytre${i}abcdefg')
""")
sql """ INSERT INTO ${tableName} VALUES
${sb.toString()}
"""
qt_select_default """ SELECT * FROM ${tableName} t ORDER BY char_col; """
sql """ CREATE AGGREGATE FUNCTION c_udaf_my_sum_int(int) RETURNS BigInt PROPERTIES (
"symbol"="org.apache.doris.udf.MySumInt",
"always_nullable"="false",
"type"="JAVA_UDF"
); """
qt_select1 """ SELECT c_udaf_my_sum_int(user_id) result FROM ${tableName}; """
qt_select2 """ select user_id, c_udaf_my_sum_int(user_id) from ${tableName} group by user_id order by user_id; """
} finally {
try_sql("DROP FUNCTION IF EXISTS c_udaf_my_sum_int(int);")
try_sql("DROP TABLE IF EXISTS ${tableName}")
}
}
@@ -0,0 +1,63 @@
// 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.
import org.codehaus.groovy.runtime.IOGroovyMethods
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
suite("test_javaudf_custom_lib_all_types") {
def tableName = "test_javaudf_custom_lib_all_types"
try {
sql """ DROP TABLE IF EXISTS ${tableName} """
sql """
CREATE TABLE IF NOT EXISTS ${tableName} (
int_col int,
string_col string
)
DISTRIBUTED BY HASH(int_col) PROPERTIES("replication_num" = "1");
"""
StringBuilder sb = new StringBuilder()
int i = 1
for (; i < 10; i++) {
sb.append("""
(${i},${i%2}),
""")
}
sb.append("""
(${i},null)
""")
sql """ INSERT INTO ${tableName} VALUES
${sb.toString()}
"""
sql """DROP FUNCTION IF EXISTS c_echo_int(int);"""
sql """CREATE FUNCTION c_echo_int(int) RETURNS int PROPERTIES (
"symbol"="org.apache.doris.udf.Echo\$EchoInt",
"type"="JAVA_UDF"
);"""
qt_java_udf_all_types """select
int_col,
c_echo_int(int_col)
from ${tableName} order by int_col;"""
} finally {
try_sql """DROP FUNCTION IF EXISTS c_echo_int(int);"""
try_sql("""DROP TABLE IF EXISTS ${tableName};""")
}
}
@@ -0,0 +1,181 @@
// 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.
import org.codehaus.groovy.runtime.IOGroovyMethods
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
suite("test_javaudtf_custom_lib_all_types") {
def tableName = "test_javaudtf_custom_lib_all_types"
try {
sql """ DROP TABLE IF EXISTS ${tableName} """
sql """
CREATE TABLE IF NOT EXISTS ${tableName} (
int_col int,
boolean_col boolean,
tinyint_col tinyint,
smallint_col smallint,
bigint_col bigint,
largeint_col largeint,
decimal_col decimal(15, 4),
float_col float,
double_col double,
date_col date,
datetime_col datetime(6),
string_col string,
array_col array<string>,
map_col map<string, string>
)
DISTRIBUTED BY HASH(int_col) PROPERTIES("replication_num" = "1");
"""
StringBuilder sb = new StringBuilder()
int i = 1
for (; i < 10; i++) {
sb.append("""
(${i},${i%2},${i},${i}*2,${i}*3,${i}*4,${3.33/i},${(7.77/i).round(3)},${(3.1415/i).round(5)},"2023-10-${i+17}","2023-10-${i+10} 10:1${i}:11.234","row${i}",array(null, "nested${i}"),{"k${i}":null,"k${i+1}":"value${i}"}),
""")
}
sb.append("""
(${i},${i%2},null,${i}*2,${i}*3,${i}*4,null,${(7.77/i).round(3)},${(3.1415/i).round(5)},null,"2023-10-${i+10} 10:${i}:11.234",null,array(null, "nested${i}"),{"k${i}":null,"k${i+1}":"value${i}"}),
""")
sb.append("""
(null,null,null,null,null,null,null,null,null,null,null,null,null,null)
""")
sql """ INSERT INTO ${tableName} VALUES
${sb.toString()}
"""
qt_select """select * from ${tableName} order by 1,2,3;"""
sql """DROP FUNCTION IF EXISTS c_udtf_boolean(boolean, int);"""
sql """CREATE TABLES FUNCTION c_udtf_boolean(boolean, int) RETURNS array<boolean> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfBoolean",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_tinyint(tinyint, int);"""
sql """CREATE TABLES FUNCTION c_udtf_tinyint(tinyint, int) RETURNS array<tinyint> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfByte",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_short(smallint, int);"""
sql """CREATE TABLES FUNCTION c_udtf_short(smallint, int) RETURNS array<smallint> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfShort",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_int(int, int);"""
sql """CREATE TABLES FUNCTION c_udtf_int(int, int) RETURNS array<int> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfInt",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_long(bigint, int);"""
sql """CREATE TABLES FUNCTION c_udtf_long(bigint, int) RETURNS array<bigint> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfLong",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_largeint(largeint, int);"""
sql """CREATE TABLES FUNCTION c_udtf_largeint(largeint, int) RETURNS array<largeint> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfLargeInt",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_decimal(decimal(15, 4), int);"""
sql """CREATE TABLES FUNCTION c_udtf_decimal(decimal(15, 4), int) RETURNS array<decimal(15, 4)> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfDecimal",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_float(float, int);"""
sql """CREATE TABLES FUNCTION c_udtf_float(float, int) RETURNS array<float> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfFloat",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_double(double, int);"""
sql """CREATE TABLES FUNCTION c_udtf_double(double, int) RETURNS array<double> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfDouble",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_date(date, int);"""
sql """CREATE TABLES FUNCTION c_udtf_date(date, int) RETURNS array<date> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfDate",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_datetime(datetime(6), int);"""
sql """CREATE TABLES FUNCTION c_udtf_datetime(datetime(6), int) RETURNS array<datetime(6)> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfDateTime",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_string(string, string);"""
sql """CREATE TABLES FUNCTION c_udtf_string(string,string) RETURNS array<string> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfString",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_list(array<string>, int);"""
sql """CREATE TABLES FUNCTION c_udtf_list(array<string>, int) RETURNS array<string> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfList",
"type"="JAVA_UDF"
);"""
sql """DROP FUNCTION IF EXISTS c_udtf_map(map<string,string>, int);"""
sql """CREATE TABLES FUNCTION c_udtf_map(map<string,string>, int) RETURNS array<string> PROPERTIES (
"symbol"="org.apache.doris.udf.UDTFAllTypeTest\$UdtfMap",
"type"="JAVA_UDF"
);"""
qt_select_boolean_col """select int_col, boolean_col, e1 from ${tableName} lateral view c_udtf_boolean(boolean_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_tinyint_col """select int_col, tinyint_col, e1 from ${tableName} lateral view c_udtf_tinyint(tinyint_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_smallint_col """select int_col, smallint_col, e1 from ${tableName} lateral view c_udtf_short(smallint_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_int_col """select int_col, int_col, e1 from ${tableName} lateral view c_udtf_int(int_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_bigint_col """select int_col, bigint_col, e1 from ${tableName} lateral view c_udtf_long(bigint_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_largeint_col """select int_col, largeint_col,e1 from ${tableName} lateral view c_udtf_largeint(largeint_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_decimal_col """select int_col, decimal_col,e1 from ${tableName} lateral view c_udtf_decimal(decimal_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_float_col """select int_col, float_col,e1 from ${tableName} lateral view c_udtf_float(float_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_double_col """select int_col, double_col,e1 from ${tableName} lateral view c_udtf_double(double_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_date_col """select int_col, date_col,e1 from ${tableName} lateral view c_udtf_date(date_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_datetime_col """select int_col, datetime_col,e1 from ${tableName} lateral view c_udtf_datetime(datetime_col, int_col) tmp1 as e1 order by int_col,2,3;"""
qt_select_string_col """select int_col, string_col,e1 from ${tableName} lateral view c_udtf_string(string_col, "") tmp1 as e1 order by int_col,2,3;"""
qt_select_array_col """select int_col, array_col,e1 from ${tableName} lateral view c_udtf_list(array_col, int_col) tmp1 as e1 order by int_col,3;"""
qt_select_map_col """select int_col, map_col,e1 from ${tableName} lateral view c_udtf_map(map_col, int_col) tmp1 as e1 order by int_col,3;"""
} finally {
try_sql """DROP FUNCTION IF EXISTS c_udtf_boolean (boolean, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_tinyint (tinyint, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_short (smallint, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_int (int, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_long (bigint, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_largeint (largeint, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_decimal (decimal(15, 4), int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_float (float, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_double (double, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_date (date, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_datetime (datetime(6), int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_string (string, string);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_list (array<string>, int);"""
try_sql """DROP FUNCTION IF EXISTS c_udtf_map (map<string,string>, int);"""
}
}
+22 -10
View File
@@ -50,7 +50,7 @@ Usage: $0 <shell_options> <framework_options>
Eg.
$0 build regression test framework and run all suite which in default group
$0 --run test_select run a suite which named as test_select
$0 --run 'test*' run all suite which named start with 'test', note that you must quota with ''
$0 --compile only compile regression framework
$0 --run -s test_select run a suite which named as test_select
$0 --run test_select -genOut generate output file for test_select if not exist
$0 --run -g default run all suite in the group which named as default
@@ -65,7 +65,7 @@ Default config file: \${DORIS_HOME}/regression-test/conf/regression-conf.groovy
"
exit 1
}
ONLY_COMPILE=0
CLEAN=0
WRONG_CMD=0
TEAMCITY=0
@@ -96,6 +96,11 @@ else
shift
shift
;;
--compile)
RUN=1
ONLY_COMPILE=1
shift
;;
--run)
RUN=1
shift
@@ -178,6 +183,11 @@ if ! test -f ${RUN_JAR:+${RUN_JAR}}; then
cd "${DORIS_HOME}"/regression-test/java-udf-src
"${MVN_CMD}" package
cp target/java-udf-case-jar-with-dependencies.jar "${DORIS_HOME}"/regression-test/suites/javaudf_p0/jars/
# be and fe dir is compiled output
mkdir -p "${DORIS_HOME}"/output/fe/custom_lib/
mkdir -p "${DORIS_HOME}"/output/be/custom_lib/
cp target/java-udf-case-jar-with-dependencies.jar "${DORIS_HOME}"/output/fe/custom_lib/
cp target/java-udf-case-jar-with-dependencies.jar "${DORIS_HOME}"/output/be/custom_lib/
cd "${DORIS_HOME}"
fi
@@ -206,11 +216,13 @@ if [[ "${TEAMCITY}" -eq 1 ]]; then
JAVA_OPTS="${JAVA_OPTS} -DstdoutAppenderType=teamcity -Xmx2048m"
fi
"${JAVA}" -DDORIS_HOME="${DORIS_HOME}" \
-DLOG_PATH="${LOG_OUTPUT_FILE}" \
-Dfile.encoding="UTF-8" \
-Dlogback.configurationFile="${LOG_CONFIG_FILE}" \
${JAVA_OPTS:+${JAVA_OPTS}} \
-jar ${RUN_JAR:+${RUN_JAR}} \
-cf "${CONFIG_FILE}" \
${REGRESSION_OPTIONS_PREFIX:+${REGRESSION_OPTIONS_PREFIX}} "$@"
if [[ "${ONLY_COMPILE}" -eq 0 ]]; then
"${JAVA}" -DDORIS_HOME="${DORIS_HOME}" \
-DLOG_PATH="${LOG_OUTPUT_FILE}" \
-Dfile.encoding="UTF-8" \
-Dlogback.configurationFile="${LOG_CONFIG_FILE}" \
${JAVA_OPTS:+${JAVA_OPTS}} \
-jar ${RUN_JAR:+${RUN_JAR}} \
-cf "${CONFIG_FILE}" \
${REGRESSION_OPTIONS_PREFIX:+${REGRESSION_OPTIONS_PREFIX}} "$@"
fi