cherry pick from #47919
This commit is contained in:
@ -23,6 +23,8 @@ 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.BoundFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.BuiltinFunctionBuilder;
|
||||
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;
|
||||
@ -37,6 +39,8 @@ import com.google.common.collect.Maps;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -227,7 +231,25 @@ public class FunctionRegistry {
|
||||
|
||||
public String getCandidateHint(String name, List<FunctionBuilder> candidateBuilders) {
|
||||
return candidateBuilders.stream()
|
||||
.map(builder -> name + builder.toString())
|
||||
.filter(builder -> {
|
||||
if (builder instanceof BuiltinFunctionBuilder) {
|
||||
Constructor<BoundFunction> builderMethod
|
||||
= ((BuiltinFunctionBuilder) builder).getBuilderMethod();
|
||||
if (Modifier.isAbstract(builderMethod.getModifiers())
|
||||
|| !Modifier.isPublic(builderMethod.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
for (Class<?> parameterType : builderMethod.getParameterTypes()) {
|
||||
if (!Expression.class.isAssignableFrom(parameterType)
|
||||
&& !(parameterType.isArray()
|
||||
&& Expression.class.isAssignableFrom(parameterType.getComponentType()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map(builder -> name + builder.parameterDisplayString())
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
}
|
||||
|
||||
|
||||
@ -145,6 +145,11 @@ public class AggCombinerFunctionBuilder extends FunctionBuilder {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parameterDisplayString() {
|
||||
return nestedBuilder.parameterDisplayString();
|
||||
}
|
||||
|
||||
public static boolean isAggStateCombinator(String name) {
|
||||
return name.toLowerCase().endsWith(STATE_SUFFIX) || name.toLowerCase().endsWith(MERGE_SUFFIX)
|
||||
|| name.toLowerCase().endsWith(UNION_SUFFIX) || name.toLowerCase().endsWith(FOREACH_SUFFIX);
|
||||
|
||||
@ -53,6 +53,10 @@ public class BuiltinFunctionBuilder extends FunctionBuilder {
|
||||
this.isVariableLength = arity > 0 && builderMethod.getParameterTypes()[arity - 1].isArray();
|
||||
}
|
||||
|
||||
public Constructor<BoundFunction> getBuilderMethod() {
|
||||
return builderMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends BoundFunction> functionClass() {
|
||||
return functionClass;
|
||||
@ -146,4 +150,16 @@ public class BuiltinFunctionBuilder extends FunctionBuilder {
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parameterDisplayString() {
|
||||
return Arrays.stream(builderMethod.getParameterTypes())
|
||||
.map(p -> {
|
||||
if (p.isArray()) {
|
||||
return p.getComponentType().getSimpleName() + "...";
|
||||
} else {
|
||||
return p.getSimpleName();
|
||||
}
|
||||
})
|
||||
.collect(Collectors.joining(", ", "(", ")"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,4 +47,9 @@ public abstract class FunctionBuilder {
|
||||
*/
|
||||
public abstract Pair<? extends Expression, ? extends BoundFunction> build(
|
||||
String name, List<? extends Object> arguments);
|
||||
|
||||
/**
|
||||
* return the parameters string for display candidate functions, for example: `(int, decimal, varchar)`
|
||||
*/
|
||||
public abstract String parameterDisplayString();
|
||||
}
|
||||
|
||||
@ -114,4 +114,11 @@ public class AliasUdfBuilder extends UdfBuilder {
|
||||
|
||||
return Pair.of(udfAnalyzer.analyze(aliasUdf.getUnboundFunction()), boundAliasFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parameterDisplayString() {
|
||||
return aliasUdf.getArgTypes().stream()
|
||||
.map(DataType::toString)
|
||||
.collect(Collectors.joining(", ", "(", ")"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,4 +85,19 @@ public class JavaUdafBuilder extends UdfBuilder {
|
||||
.collect(Collectors.toList()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parameterDisplayString() {
|
||||
StringBuilder string = new StringBuilder("(");
|
||||
for (int i = 0; i < udaf.getArgumentsTypes().size(); ++i) {
|
||||
if (i > 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
string.append(udaf.getArgumentsTypes().get(i));
|
||||
if (isVarArgs && i + 1 == udaf.getArgumentsTypes().size()) {
|
||||
string.append("...");
|
||||
}
|
||||
}
|
||||
return string.append(")").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,4 +90,19 @@ public class JavaUdfBuilder extends UdfBuilder {
|
||||
}
|
||||
return Pair.ofSame(udf.withChildren(processedExprs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parameterDisplayString() {
|
||||
StringBuilder string = new StringBuilder("(");
|
||||
for (int i = 0; i < udf.getArgumentsTypes().size(); ++i) {
|
||||
if (i > 0) {
|
||||
string.append(", ");
|
||||
}
|
||||
string.append(udf.getArgumentsTypes().get(i));
|
||||
if (isVarArgs && i + 1 == udf.getArgumentsTypes().size()) {
|
||||
string.append("...");
|
||||
}
|
||||
}
|
||||
return string.append(")").toString();
|
||||
}
|
||||
}
|
||||
|
||||
30
regression-test/suites/function_p0/not_found_function.groovy
Normal file
30
regression-test/suites/function_p0/not_found_function.groovy
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
suite("not_found_function") {
|
||||
sql "set enable_fallback_to_original_planner=false"
|
||||
|
||||
test {
|
||||
sql "select group_concat()"
|
||||
exception "Can not found function 'group_concat' which has 0 arity. Candidate functions are: [group_concat(Expression, Expression...)]"
|
||||
}
|
||||
|
||||
test {
|
||||
sql "select sum()"
|
||||
exception "Can not found function 'sum' which has 0 arity. Candidate functions are: [sum(Expression)]"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user