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]

Reply via email to