Skip to content

Commit

Permalink
[fix](Nereids) only search internal funcftion when dbName is empty (a…
Browse files Browse the repository at this point in the history
…pache#26296)

if call function with database name. we should only search UDF
  • Loading branch information
morrySnow authored and wangxiangyu committed Nov 4, 2023
1 parent f32a4a1 commit e1294bb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand Down Expand Up @@ -86,24 +87,31 @@ public Optional<List<FunctionBuilder>> tryGetBuiltinBuilders(String name) {

// 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 + "'");
}
}

Expand All @@ -113,15 +121,15 @@ public FunctionBuilder findFunctionBuilder(String dbName, String name, List<?> a
.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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.apache.doris.nereids.util.TypeCoercionUtils;

import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -142,22 +143,24 @@ public Expression visitUnboundFunction(UnboundFunction unboundFunction, Expressi

// bind function
FunctionRegistry functionRegistry = Env.getCurrentEnv().getFunctionRegistry();
String functionName = unboundFunction.getName();
List<Object> arguments = unboundFunction.isDistinct()
? ImmutableList.builder()
.add(unboundFunction.isDistinct())
.addAll(unboundFunction.getArguments())
.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) {
Expand Down
5 changes: 5 additions & 0 deletions regression-test/suites/nereids_syntax_p0/function.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,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"
}
}

0 comments on commit e1294bb

Please sign in to comment.