This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new fedadbba6ec [opt](Nereids) support search from override udfs with same
arity (#40432) (#40751)
fedadbba6ec is described below
commit fedadbba6ece3bb744872f88261e5c923de23872
Author: morrySnow <[email protected]>
AuthorDate: Thu Sep 12 19:58:49 2024 +0800
[opt](Nereids) support search from override udfs with same arity (#40432)
(#40751)
pick from master #40432
create alias function f1(int) with parameter(id) as abs(id); create
alias function f1(string) with parameter(id) as substr(id, 2); select
f1('1'); -- bind on f1(string)
select f1(1); -- bind on f1(int)
test case already existed in P0
---
.../org/apache/doris/catalog/FunctionRegistry.java | 92 ++++++++++++++++++++--
.../apache/doris/catalog/FunctionSignature.java | 34 ++++----
.../trees/expressions/functions/udf/AliasUdf.java | 4 +-
.../expressions/functions/udf/AliasUdfBuilder.java | 20 ++---
.../expressions/functions/udf/JavaUdafBuilder.java | 6 ++
.../expressions/functions/udf/JavaUdfBuilder.java | 6 ++
.../expressions/functions/udf/UdfBuilder.java | 3 +
7 files changed, 124 insertions(+), 41 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionRegistry.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionRegistry.java
index 0e049b4b902..7280463b0f2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionRegistry.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionRegistry.java
@@ -21,7 +21,9 @@ import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.annotation.Developing;
import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.AggCombinerFunctionBuilder;
+import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder;
import org.apache.doris.nereids.trees.expressions.functions.udf.UdfBuilder;
import org.apache.doris.nereids.types.DataType;
@@ -156,18 +158,33 @@ public class FunctionRegistry {
+ "' which has " + arity + " arity. Candidate functions
are: " + candidateHints);
}
if (candidateBuilders.size() > 1) {
- String candidateHints = getCandidateHint(name, candidateBuilders);
- // TODO: NereidsPlanner not supported override function by the
same arity, we will support it later
- if (ConnectContext.get() != null) {
- try {
-
ConnectContext.get().getSessionVariable().enableFallbackToOriginalPlannerOnce();
- } catch (Throwable t) {
- // ignore error
+ boolean needChooseOne = true;
+ List<FunctionSignature> signatures =
Lists.newArrayListWithCapacity(candidateBuilders.size());
+ for (FunctionBuilder functionBuilder : candidateBuilders) {
+ if (functionBuilder instanceof UdfBuilder) {
+ signatures.addAll(((UdfBuilder)
functionBuilder).getSignatures());
+ } else {
+ needChooseOne = false;
+ break;
+ }
+ }
+ for (Object argument : arguments) {
+ if (!(argument instanceof Expression)) {
+ needChooseOne = false;
+ break;
}
}
+ if (needChooseOne) {
+ FunctionSignature signature = new
UdfSignatureSearcher(signatures, (List) arguments).getSignature();
+ for (int i = 0; i < signatures.size(); i++) {
+ if (signatures.get(i).equals(signature)) {
+ return candidateBuilders.get(i);
+ }
+ }
+ }
+ String candidateHints = getCandidateHint(name, candidateBuilders);
throw new AnalysisException("Function '" + qualifiedName + "' is
ambiguous: " + candidateHints);
}
-
return candidateBuilders.get(0);
}
@@ -235,4 +252,63 @@ public class FunctionRegistry {
.removeIf(builder -> ((UdfBuilder)
builder).getArgTypes().equals(argTypes));
}
}
+
+ /**
+ * use for search appropriate signature for UDFs if candidate more than
one.
+ */
+ static class UdfSignatureSearcher implements ExplicitlyCastableSignature {
+
+ private final List<FunctionSignature> signatures;
+ private final List<Expression> arguments;
+
+ public UdfSignatureSearcher(List<FunctionSignature> signatures,
List<Expression> arguments) {
+ this.signatures = signatures;
+ this.arguments = arguments;
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return signatures;
+ }
+
+ @Override
+ public FunctionSignature getSignature() {
+ return searchSignature(signatures);
+ }
+
+ @Override
+ public boolean nullable() {
+ throw new AnalysisException("could not call nullable on
UdfSignatureSearcher");
+ }
+
+ @Override
+ public List<Expression> children() {
+ return arguments;
+ }
+
+ @Override
+ public Expression child(int index) {
+ return arguments.get(index);
+ }
+
+ @Override
+ public int arity() {
+ return arguments.size();
+ }
+
+ @Override
+ public <T> Optional<T> getMutableState(String key) {
+ return Optional.empty();
+ }
+
+ @Override
+ public void setMutableState(String key, Object value) {
+ }
+
+ @Override
+ public Expression withChildren(List<Expression> children) {
+ throw new AnalysisException("could not call withChildren on
UdfSignatureSearcher");
+
+ }
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSignature.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSignature.java
index 4ff9448a33b..4915073141b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSignature.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSignature.java
@@ -30,7 +30,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.function.BiFunction;
public class FunctionSignature {
public final DataType returnType;
@@ -78,21 +77,6 @@ public class FunctionSignature {
return new FunctionSignature(returnType, hasVarArgs, argumentsTypes);
}
- /**
- * change argument type by the signature's type and the corresponding
argument's type
- * @param arguments arguments
- * @param transform param1: signature's type, param2: argument's type,
return new type you want to change
- * @return
- */
- public FunctionSignature withArgumentTypes(List<Expression> arguments,
- BiFunction<DataType, Expression, DataType> transform) {
- List<DataType> newTypes = Lists.newArrayList();
- for (int i = 0; i < arguments.size(); i++) {
- newTypes.add(transform.apply(getArgType(i), arguments.get(i)));
- }
- return withArgumentTypes(hasVarArgs, newTypes);
- }
-
/**
* change argument type by the signature's type and the corresponding
argument's type
* @param arguments arguments
@@ -145,6 +129,24 @@ public class FunctionSignature {
.toString();
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ FunctionSignature signature = (FunctionSignature) o;
+ return hasVarArgs == signature.hasVarArgs && arity == signature.arity
&& Objects.equals(returnType,
+ signature.returnType) && Objects.equals(argumentsTypes,
signature.argumentsTypes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(returnType, hasVarArgs, argumentsTypes, arity);
+ }
+
public static class FuncSigBuilder {
public final DataType returnType;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
index 0aa0bfdf852..7b97335e77c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
@@ -32,7 +32,6 @@ import
org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
-import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
@@ -62,8 +61,7 @@ public class AliasUdf extends ScalarFunction implements
ExplicitlyCastableSignat
@Override
public List<FunctionSignature> getSignatures() {
- return ImmutableList.of(Suppliers.memoize(() -> FunctionSignature
- .of(NullType.INSTANCE, argTypes)).get());
+ return ImmutableList.of(FunctionSignature.of(NullType.INSTANCE,
argTypes));
}
public List<String> getParameters() {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
index 2886b5cf4ae..2bb832524e9 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
@@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.udf;
+import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.ReflectionUtils;
import org.apache.doris.nereids.analyzer.Scope;
@@ -25,7 +26,6 @@ import
org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
-import
org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.util.TypeCoercionUtils;
@@ -53,6 +53,11 @@ public class AliasUdfBuilder extends UdfBuilder {
return aliasUdf.getArgTypes();
}
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return aliasUdf.getSignatures();
+ }
+
@Override
public Class<? extends BoundFunction> functionClass() {
return AliasUdf.class;
@@ -109,17 +114,4 @@ public class AliasUdfBuilder extends UdfBuilder {
return Pair.of(udfAnalyzer.analyze(aliasUdf.getUnboundFunction()),
boundAliasFunction);
}
-
- private static class SlotReplacer extends
DefaultExpressionRewriter<Map<SlotReference, Expression>> {
- public static final SlotReplacer INSTANCE = new SlotReplacer();
-
- public Expression replace(Expression expression, Map<SlotReference,
Expression> context) {
- return expression.accept(this, context);
- }
-
- @Override
- public Expression visitSlotReference(SlotReference slot,
Map<SlotReference, Expression> context) {
- return context.get(slot);
- }
- }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdafBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdafBuilder.java
index 0d8ad443f53..802df2442fc 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdafBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdafBuilder.java
@@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.udf;
+import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.ReflectionUtils;
import org.apache.doris.nereids.trees.expressions.Expression;
@@ -50,6 +51,11 @@ public class JavaUdafBuilder extends UdfBuilder {
.collect(Collectors.toList())).get();
}
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return udaf.getSignatures();
+ }
+
@Override
public Class<? extends BoundFunction> functionClass() {
return JavaUdaf.class;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdfBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdfBuilder.java
index 04d4741286a..fb1184a9c1b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdfBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdfBuilder.java
@@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.udf;
+import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.ReflectionUtils;
import org.apache.doris.nereids.trees.expressions.Expression;
@@ -52,6 +53,11 @@ public class JavaUdfBuilder extends UdfBuilder {
.collect(Collectors.toList())).get();
}
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return udf.getSignatures();
+ }
+
@Override
public Class<? extends BoundFunction> functionClass() {
return JavaUdf.class;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/UdfBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/UdfBuilder.java
index 892d9a4312f..2c57cfad1be 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/UdfBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/UdfBuilder.java
@@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.udf;
+import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder;
import org.apache.doris.nereids.types.DataType;
@@ -27,4 +28,6 @@ import java.util.List;
*/
public abstract class UdfBuilder extends FunctionBuilder {
public abstract List<DataType> getArgTypes();
+
+ public abstract List<FunctionSignature> getSignatures();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]