This is an automated email from the ASF dual-hosted git repository.

morrysnow 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 82c2650322d [opt](Nereids) support search from override udfs with same 
arity (#40432)
82c2650322d is described below

commit 82c2650322d57ed0028655d39f551649d59faaa1
Author: morrySnow <101034200+morrys...@users.noreply.github.com>
AuthorDate: Thu Sep 5 20:21:19 2024 +0800

    [opt](Nereids) support search from override udfs with same arity (#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/JavaUdtfBuilder.java |  6 ++
 .../expressions/functions/udf/UdfBuilder.java      |  3 +
 8 files changed, 130 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/JavaUdtfBuilder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdtfBuilder.java
index 85114f08e3f..6e6a6192190 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdtfBuilder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/JavaUdtfBuilder.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 JavaUdtfBuilder extends UdfBuilder {
                 .collect(Collectors.toList())).get();
     }
 
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return udf.getSignatures();
+    }
+
     @Override
     public Class<? extends BoundFunction> functionClass() {
         return JavaUdtf.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: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to