This is an automated email from the ASF dual-hosted git repository.
kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 4539cb5e287 [fix](Nereids) only search internal funcftion when dbName
is empty (#26296) (#26700)
4539cb5e287 is described below
commit 4539cb5e287014bd6380b98f1051253df09efd82
Author: morrySnow <[email protected]>
AuthorDate: Thu Nov 9 23:39:33 2023 +0800
[fix](Nereids) only search internal funcftion when dbName is empty (#26296)
(#26700)
pick from master
PR: #26296
commit id: 6892fc99f89e7deee0817d51183b2c918c3627b1
if call function with database name. we should only search UDF
---
.../org/apache/doris/catalog/FunctionRegistry.java | 40 +++++++++++++---------
.../rules/expression/rules/FunctionBinder.java | 17 +++++----
.../suites/nereids_syntax_p0/function.groovy | 5 +++
3 files changed, 39 insertions(+), 23 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 bb26f2bef52..3a08fce5755 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
@@ -33,6 +33,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Map;
@@ -86,24 +87,31 @@ public class FunctionRegistry {
// currently we only find function by name and arity and args' types.
public FunctionBuilder findFunctionBuilder(String dbName, String name,
List<?> arguments) {
+ List<FunctionBuilder> functionBuilders = null;
int arity = arguments.size();
- List<FunctionBuilder> functionBuilders =
name2InternalBuiltinBuilders.get(name.toLowerCase());
- if (CollectionUtils.isEmpty(functionBuilders) &&
AggStateFunctionBuilder.isAggStateCombinator(name)) {
- String nestedName = AggStateFunctionBuilder.getNestedName(name);
- String combinatorSuffix =
AggStateFunctionBuilder.getCombinatorSuffix(name);
-
- functionBuilders =
name2InternalBuiltinBuilders.get(nestedName.toLowerCase());
-
- if (functionBuilders != null) {
- functionBuilders = functionBuilders.stream().map(builder -> {
- return new AggStateFunctionBuilder(combinatorSuffix,
builder);
- }).filter(functionBuilder ->
functionBuilder.canApply(arguments)).collect(Collectors.toList());
+ String qualifiedName = StringUtils.isEmpty(dbName) ? name : dbName +
"." + name;
+
+ if (StringUtils.isEmpty(dbName)) {
+ // search internal function only if dbName is empty
+ functionBuilders =
name2InternalBuiltinBuilders.get(name.toLowerCase());
+ if (CollectionUtils.isEmpty(functionBuilders) &&
AggStateFunctionBuilder.isAggStateCombinator(name)) {
+ String nestedName =
AggStateFunctionBuilder.getNestedName(name);
+ String combinatorSuffix =
AggStateFunctionBuilder.getCombinatorSuffix(name);
+ functionBuilders =
name2InternalBuiltinBuilders.get(nestedName.toLowerCase());
+ if (functionBuilders != null) {
+ functionBuilders = functionBuilders.stream()
+ .map(builder -> new
AggStateFunctionBuilder(combinatorSuffix, builder))
+ .filter(functionBuilder ->
functionBuilder.canApply(arguments))
+ .collect(Collectors.toList());
+ }
}
}
- if (functionBuilders == null || functionBuilders.isEmpty()) {
+
+ // search udf
+ if (CollectionUtils.isEmpty(functionBuilders)) {
functionBuilders = findUdfBuilder(dbName, name);
if (functionBuilders == null || functionBuilders.isEmpty()) {
- throw new AnalysisException("Can not found function '" + name
+ "'");
+ throw new AnalysisException("Can not found function '" +
qualifiedName + "'");
}
}
@@ -113,15 +121,15 @@ public class FunctionRegistry {
.collect(Collectors.toList());
if (candidateBuilders.isEmpty()) {
String candidateHints = getCandidateHint(name, functionBuilders);
- throw new AnalysisException("Can not found function '" + name
+ throw new AnalysisException("Can not found function '" +
qualifiedName
+ "' which has " + arity + " arity. Candidate functions
are: " + candidateHints);
}
-
if (candidateBuilders.size() > 1) {
String candidateHints = getCandidateHint(name, candidateBuilders);
// NereidsPlanner not supported override function by the same
arity, should we support it?
- throw new AnalysisException("Function '" + name + "' is ambiguous:
" + candidateHints);
+ throw new AnalysisException("Function '" + qualifiedName + "' is
ambiguous: " + candidateHints);
}
+
return candidateBuilders.get(0);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FunctionBinder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FunctionBinder.java
index b56fe657633..4dc8e944a71 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FunctionBinder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FunctionBinder.java
@@ -52,6 +52,7 @@ import
org.apache.doris.nereids.types.coercion.AbstractDataType;
import org.apache.doris.nereids.util.TypeCoercionUtils;
import com.google.common.collect.ImmutableList;
+import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Locale;
@@ -89,7 +90,6 @@ public class FunctionBinder extends
AbstractExpressionRewriteRule {
// bind function
FunctionRegistry functionRegistry =
Env.getCurrentEnv().getFunctionRegistry();
- String functionName = unboundFunction.getName();
List<Object> arguments = unboundFunction.isDistinct()
? ImmutableList.builder()
.add(unboundFunction.isDistinct())
@@ -97,14 +97,17 @@ public class FunctionBinder extends
AbstractExpressionRewriteRule {
.build()
: (List) unboundFunction.getArguments();
- // we will change arithmetic function like add(), subtract(), bitnot()
to the corresponding objects rather than
- // BoundFunction.
- ArithmeticFunctionBinder functionBinder = new
ArithmeticFunctionBinder();
- if (functionBinder.isBinaryArithmetic(unboundFunction.getName())) {
- return
functionBinder.bindBinaryArithmetic(unboundFunction.getName(),
unboundFunction.children())
- .accept(this, context);
+ if (StringUtils.isEmpty(unboundFunction.getDbName())) {
+ // we will change arithmetic function like add(), subtract(),
bitnot()
+ // to the corresponding objects rather than BoundFunction.
+ ArithmeticFunctionBinder functionBinder = new
ArithmeticFunctionBinder();
+ if (functionBinder.isBinaryArithmetic(unboundFunction.getName())) {
+ return
functionBinder.bindBinaryArithmetic(unboundFunction.getName(),
unboundFunction.children())
+ .accept(this, context);
+ }
}
+ String functionName = unboundFunction.getName();
FunctionBuilder builder = functionRegistry.findFunctionBuilder(
unboundFunction.getDbName(), functionName, arguments);
if (builder instanceof AliasUdfBuilder) {
diff --git a/regression-test/suites/nereids_syntax_p0/function.groovy
b/regression-test/suites/nereids_syntax_p0/function.groovy
index 1efa58160ab..dcab3f5fec1 100644
--- a/regression-test/suites/nereids_syntax_p0/function.groovy
+++ b/regression-test/suites/nereids_syntax_p0/function.groovy
@@ -242,5 +242,10 @@ suite("nereids_function") {
qt_regexp_extract_all """
SELECT regexp_extract_all('AbCdE', '([[:lower:]]+)C([[:lower:]]+)')
"""
+
+ test {
+ sql "select `hello`.now(3)"
+ exception "Can not found function"
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]