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
commit f84dc7298f1a6be16e38fecfed33070b355f1774 Author: mch_ucchi <[email protected]> AuthorDate: Thu Jul 20 22:12:10 2023 +0800 [Fix](planner)fix failed running alias function with an alias function in original function. (#21024) failed to run sql: ```sql create alias function f1(int) with parameter(n) as dayofweek(hours_add('2023-06-18', n)) create alias function f2(int) with parameter(n) as dayofweek(hours_add(makedate(year('2023-06-18'), f1(3)), n)) select f2(f1(3)) ``` it will throw an exception: f1 is not a builtin-function. because f2's original function contains f1, and f1 is not a builtin-function, should be rewritten firstly. we should avoid of it. And we will support it later. --- .../java/org/apache/doris/analysis/Analyzer.java | 10 ++++ .../main/java/org/apache/doris/analysis/Expr.java | 2 +- .../apache/doris/analysis/FunctionCallExpr.java | 66 +++++++++++++--------- .../java/org/apache/doris/qe/StmtExecutor.java | 1 + 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java index 65cc119683..19255873c0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java @@ -179,6 +179,8 @@ public class Analyzer { // The runtime filter that is expected to be used private final List<RuntimeFilter> assignedRuntimeFilters = new ArrayList<>(); + private boolean isReAnalyze = false; + public void setIsSubquery() { isSubquery = true; isFirstScopeInSubquery = true; @@ -201,6 +203,14 @@ public class Analyzer { return isWithClause; } + public void setReAnalyze(boolean reAnalyze) { + isReAnalyze = reAnalyze; + } + + public boolean isReAnalyze() { + return isReAnalyze; + } + public void setUDFAllowed(boolean val) { this.isUDFAllowed = val; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java index d56c398836..c198375b0e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java @@ -1835,7 +1835,7 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl * Looks up in the catalog the builtin for 'name' and 'argTypes'. * Returns null if the function is not found. */ - protected Function getBuiltinFunction(String name, Type[] argTypes, Function.CompareMode mode) + public Function getBuiltinFunction(String name, Type[] argTypes, Function.CompareMode mode) throws AnalysisException { FunctionName fnName = new FunctionName(name); Function searchDesc = new Function(fnName, Arrays.asList(getActualArgTypes(argTypes)), Type.INVALID, false, diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index 24169eccf8..d94b680e79 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -1475,34 +1475,9 @@ public class FunctionCallExpr extends Expr { // find user defined functions if (fn == null) { - if (!analyzer.isUDFAllowed()) { - throw new AnalysisException( - "Does not support non-builtin functions, or function does not exist: " - + this.toSqlImpl()); - } - - String dbName = fnName.analyzeDb(analyzer); - if (!Strings.isNullOrEmpty(dbName)) { - // check operation privilege - if (!Env.getCurrentEnv().getAccessManager() - .checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.SELECT)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "SELECT"); - } - // TODO(gaoxin): ExternalDatabase not implement udf yet. - DatabaseIf db = Env.getCurrentEnv().getInternalCatalog().getDbNullable(dbName); - if (db != null && (db instanceof Database)) { - Function searchDesc = new Function(fnName, Arrays.asList(collectChildReturnTypes()), - Type.INVALID, false); - fn = ((Database) db).getFunction(searchDesc, - Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF); - } - } - // find from the internal database first, if not, then from the global functions - if (fn == null) { - Function searchDesc = - new Function(fnName, Arrays.asList(collectChildReturnTypes()), Type.INVALID, false); - fn = Env.getCurrentEnv().getGlobalFunctionMgr().getFunction(searchDesc, - Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF); + fn = findUdf(fnName, analyzer); + if (analyzer.isReAnalyze() && fn instanceof AliasFunction) { + throw new AnalysisException("a UDF in the original function of a alias function"); } } } @@ -1956,6 +1931,7 @@ public class FunctionCallExpr extends Expr { retExpr.originStmtFnExpr = clone(); // clone alias function origin expr for alias FunctionCallExpr oriExpr = (FunctionCallExpr) ((AliasFunction) retExpr.fn).getOriginFunction().clone(); + // reset fn name retExpr.fnName = oriExpr.getFnName(); // reset fn params @@ -2152,4 +2128,38 @@ public class FunctionCallExpr extends Expr { } return super.haveFunction(functionName); } + + public Function findUdf(FunctionName fnName, Analyzer analyzer) throws AnalysisException { + if (!analyzer.isUDFAllowed()) { + throw new AnalysisException( + "Does not support non-builtin functions, or function does not exist: " + + this.toSqlImpl()); + } + + Function fn = null; + String dbName = fnName.analyzeDb(analyzer); + if (!Strings.isNullOrEmpty(dbName)) { + // check operation privilege + if (!Env.getCurrentEnv().getAccessManager() + .checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.SELECT)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "SELECT"); + } + // TODO(gaoxin): ExternalDatabase not implement udf yet. + DatabaseIf db = Env.getCurrentEnv().getInternalCatalog().getDbNullable(dbName); + if (db != null && (db instanceof Database)) { + Function searchDesc = new Function(fnName, Arrays.asList(collectChildReturnTypes()), + Type.INVALID, false); + fn = ((Database) db).getFunction(searchDesc, + Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF); + } + } + // find from the internal database first, if not, then from the global functions + if (fn == null) { + Function searchDesc = + new Function(fnName, Arrays.asList(collectChildReturnTypes()), Type.INVALID, false); + fn = Env.getCurrentEnv().getGlobalFunctionMgr().getFunction(searchDesc, + Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF); + } + return fn; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index 32d6dd7a71..e1b8685cb2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -1099,6 +1099,7 @@ public class StmtExecutor { } // query re-analyze parsedStmt.reset(); + analyzer.setReAnalyze(true); parsedStmt.analyze(analyzer); // Restore the original result types and column labels. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
