This is an automated email from the ASF dual-hosted git repository. yiguolei 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 a3753c7edbd [opt](nereids) optimize not found function error message (#47919) (#48102) a3753c7edbd is described below commit a3753c7edbd8c19f3d7720bf85a103cce2fc5e0f Author: 924060929 <lanhuaj...@selectdb.com> AuthorDate: Fri Feb 21 10:13:46 2025 +0800 [opt](nereids) optimize not found function error message (#47919) (#48102) cherry pick from #47919 --- .../org/apache/doris/catalog/FunctionRegistry.java | 24 ++++++++++++++++- .../functions/AggCombinerFunctionBuilder.java | 5 ++++ .../functions/BuiltinFunctionBuilder.java | 16 ++++++++++++ .../expressions/functions/FunctionBuilder.java | 5 ++++ .../expressions/functions/udf/AliasUdfBuilder.java | 7 +++++ .../expressions/functions/udf/JavaUdafBuilder.java | 15 +++++++++++ .../expressions/functions/udf/JavaUdfBuilder.java | 15 +++++++++++ .../suites/function_p0/not_found_function.groovy | 30 ++++++++++++++++++++++ 8 files changed, 116 insertions(+), 1 deletion(-) 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 7280463b0f2..6adf27f8dc3 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 @@ -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(", ", "[", "]")); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AggCombinerFunctionBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AggCombinerFunctionBuilder.java index 76a3c36ffe5..4306697bdc0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AggCombinerFunctionBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/AggCombinerFunctionBuilder.java @@ -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); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BuiltinFunctionBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BuiltinFunctionBuilder.java index 2be48870508..f496c6bc9ca 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BuiltinFunctionBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BuiltinFunctionBuilder.java @@ -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(", ", "(", ")")); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FunctionBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FunctionBuilder.java index 760edacaeab..0bf3edcd60c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FunctionBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/FunctionBuilder.java @@ -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(); } 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 58c5abcdd26..57e6e5063b5 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 @@ -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(", ", "(", ")")); + } } 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 802df2442fc..c88f24f4eec 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 @@ -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(); + } } 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 fb1184a9c1b..6ddfdab8a15 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 @@ -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(); + } } diff --git a/regression-test/suites/function_p0/not_found_function.groovy b/regression-test/suites/function_p0/not_found_function.groovy new file mode 100644 index 00000000000..9d43f4471ef --- /dev/null +++ b/regression-test/suites/function_p0/not_found_function.groovy @@ -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)]" + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org