This is an automated email from the ASF dual-hosted git repository. xuyang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new cb644d5bc3 [feature](function) support any type in SQL function (#18392) cb644d5bc3 is described below commit cb644d5bc30806d18a0b737bf0586d3ac06b5e56 Author: xy720 <22125576+xy...@users.noreply.github.com> AuthorDate: Tue Apr 11 19:45:02 2023 +0800 [feature](function) support any type in SQL function (#18392) Add AnyType to Doris. Support Inference function in fe SQL function. --- .../java/org/apache/doris/catalog/AnyType.java | 48 +++++++++++++++++ .../java/org/apache/doris/catalog/StructType.java | 9 ++++ .../org/apache/doris/catalog/TemplateType.java | 4 +- .../main/java/org/apache/doris/catalog/Type.java | 1 + .../java/org/apache/doris/catalog/Function.java | 9 ++++ .../java/org/apache/doris/catalog/FunctionSet.java | 37 ++++++++++++- .../apache/doris/catalog/FunctionTypeDeducers.java | 63 ++++++++++++++++++++++ gensrc/script/doris_builtins_functions.py | 1 + 8 files changed, 168 insertions(+), 4 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/AnyType.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/AnyType.java new file mode 100644 index 0000000000..7f90f463d6 --- /dev/null +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/AnyType.java @@ -0,0 +1,48 @@ +// 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.doris.catalog; + +import org.apache.doris.thrift.TColumnType; +import org.apache.doris.thrift.TTypeDesc; + +/** + * Describes a AnyType type, used for SQL function return type, + * NOT used for table column type. + */ +public class AnyType extends Type { + + @Override + protected String toSql(int depth) { + return null; + } + + @Override + protected String prettyPrint(int lpad) { + return null; + } + + @Override + public void toThrift(TTypeDesc container) { + throw new RuntimeException("can not call toThrift on AnyType."); + } + + @Override + public TColumnType toColumnTypeThrift() { + throw new RuntimeException("can not call toColumnTypeThrift on AnyType"); + } +} diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java index a037b77de9..bbf6a87f01 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/StructType.java @@ -276,6 +276,15 @@ public class StructType extends Type { return Lists.newArrayList(this); } + public StructType replaceFieldsWithNames(List<String> names) { + Preconditions.checkState(names.size() == fields.size()); + ArrayList<StructField> newFields = Lists.newArrayList(); + for (int i = 0; i < names.size(); i++) { + newFields.add(new StructField(names.get(i), fields.get(i).type)); + } + return new StructType(newFields); + } + @Override public boolean equals(Object other) { if (!(other instanceof StructType)) { diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/TemplateType.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/TemplateType.java index 4b4ca9d2d1..6615918601 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/TemplateType.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/TemplateType.java @@ -117,8 +117,8 @@ public class TemplateType extends Type { expandSizeMap.computeIfAbsent(name, k -> args.length); if (expandSizeMap.get(name) != args.length) { throw new TypeException( - String.format("can not expand variadic template type %s to %s size since it's " - + "already expand as %s size", name, args.length, expandSizeMap.get(name))); + String.format("can not expand variadic template type %s to %s size since it's " + + "already expand as %s size", name, args.length, expandSizeMap.get(name))); } } diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java index 48037297aa..3479230e17 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java @@ -111,6 +111,7 @@ public abstract class Type { new StructField("generic_struct", new ScalarType(PrimitiveType.NULL_TYPE)))); public static final StructType STRUCT = new StructType(); public static final VariantType VARIANT = new VariantType(); + public static final AnyType ANY_TYPE = new AnyType(); private static final Logger LOG = LogManager.getLogger(Type.class); private static final ArrayList<ScalarType> integerTypes; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java index 88cc1b420d..ce3f77cb09 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Function.java @@ -493,6 +493,15 @@ public class Function implements Writable { } } + public boolean isInferenceFunction() { + for (Type arg : argTypes) { + if (arg instanceof AnyType) { + return true; + } + } + return retType instanceof AnyType; + } + public TFunction toThrift(Type realReturnType, Type[] realArgTypes) { TFunction fn = new TFunction(); fn.setSignature(signatureString()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index 6475f3e3ec..be8d944423 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -1232,7 +1232,12 @@ public class FunctionSet<T> { List<Function> normalFunctions = Lists.newArrayList(); List<Function> templateFunctions = Lists.newArrayList(); List<Function> variadicTemplateFunctions = Lists.newArrayList(); + List<Function> inferenceFunctions = Lists.newArrayList(); for (Function fn : fns) { + if (fn.isInferenceFunction()) { + inferenceFunctions.add(fn); + continue; + } if (fn.hasTemplateArg()) { if (!fn.hasVariadicTemplateArg()) { templateFunctions.add(fn); @@ -1274,8 +1279,25 @@ public class FunctionSet<T> { } } - // try variadic template function - return getFunction(desc, mode, specializedVariadicTemplateFunctions); + // try variadic template function third + fn = getFunction(desc, mode, specializedVariadicTemplateFunctions); + if (fn != null) { + return fn; + } + + List<Function> inferredFunctions = Lists.newArrayList(); + for (Function f : inferenceFunctions) { + if (f.hasTemplateArg()) { + f = specializeTemplateFunction(f, desc, f.hasVariadicTemplateArg()); + } + f = resolveInferenceFunction(f, desc); + if (f != null) { + inferredFunctions.add(f); + } + } + + // try inference function at last + return getFunction(desc, mode, inferredFunctions); } private Function getFunction(Function desc, Function.CompareMode mode, List<Function> fns) { @@ -1384,6 +1406,17 @@ public class FunctionSet<T> { } } + public Function resolveInferenceFunction(Function inferenceFunction, Function requestFunction) { + Type[] args = requestFunction.getArgs(); + Type newRetType = FunctionTypeDeducers.deduce(inferenceFunction.functionName(), args); + if (newRetType != null && inferenceFunction instanceof ScalarFunction) { + ScalarFunction f = (ScalarFunction) inferenceFunction; + return new ScalarFunction(f.getFunctionName(), Lists.newArrayList(f.getArgs()), newRetType, f.hasVarArgs(), + f.getSymbolName(), f.getBinaryType(), f.isUserVisible(), f.isVectorized(), f.getNullableMode()); + } + return null; + } + /** * There are essential differences in the implementation of some functions for different * types params, which should be prohibited. diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionTypeDeducers.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionTypeDeducers.java new file mode 100644 index 0000000000..0e547cdcc3 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionTypeDeducers.java @@ -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. + +package org.apache.doris.catalog; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; + +import java.util.List; + +public class FunctionTypeDeducers { + + public interface TypeDeducer { + public Type deduce(Type[] args); + } + + public static final ImmutableMap<String, TypeDeducer> DEDUCERS = ImmutableMap.<String, TypeDeducer>builder() + .put("named_struct", new NamedStructDeducer()) + .put("element_at", new ElementAtDeducer()) + .build(); + + public static Type deduce(String fnName, Type[] args) { + if (DEDUCERS.containsKey(fnName)) { + return DEDUCERS.get(fnName).deduce(args); + } + return null; + } + + public static class NamedStructDeducer implements TypeDeducer { + @Override + public Type deduce(Type[] args) { + List<Type> evenArgs = Lists.newArrayList(); + for (int i = 0; i < args.length; i++) { + if ((i & 1) == 1) { + evenArgs.add(args[i]); + } + } + return new StructType(evenArgs); + } + } + + public static class ElementAtDeducer implements TypeDeducer { + @Override + public Type deduce(Type[] args) { + // todo(xy) + return null; + } + } +} diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 3d175d0fa3..4024cdab6a 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -81,6 +81,7 @@ visible_functions = [ # struct functions [['struct'], 'STRUCT<TYPES>', ['TYPES'], 'ALWAYS_NOT_NULLABLE', ['TYPES...']], + [['named_struct'], 'ANY_TYPE', ['TYPES'], 'ALWAYS_NOT_NULLABLE', ['TYPES...']], # array functions [['array'], 'ARRAY', ['BOOLEAN', '...'], 'ALWAYS_NOT_NULLABLE'], --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org