Skip to content

Commit

Permalink
[Fix](planner)fix failed running alias function with an alias functio…
Browse files Browse the repository at this point in the history
…n 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.
  • Loading branch information
sohardforaname authored Jul 20, 2023
1 parent 398defe commit a151326
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 29 deletions.
10 changes: 10 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -201,6 +203,14 @@ public boolean isWithClause() {
return isWithClause;
}

public void setReAnalyze(boolean reAnalyze) {
isReAnalyze = reAnalyze;
}

public boolean isReAnalyze() {
return isReAnalyze;
}

public void setUDFAllowed(boolean val) {
this.isUDFAllowed = val;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ private boolean findSlotRefByName(String colName) {
* 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1475,34 +1475,9 @@ && collectChildReturnTypes()[0].isDecimalV3()) {

// 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");
}
}
}
Expand Down Expand Up @@ -1963,6 +1938,7 @@ public Expr rewriteExpr() throws AnalysisException {
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
Expand Down Expand Up @@ -2159,4 +2135,38 @@ public boolean haveFunction(String functionName) {
}
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ private void analyzeAndGenerateQueryPlan(TQueryOptions tQueryOptions) throws Use
}
// query re-analyze
parsedStmt.reset();
analyzer.setReAnalyze(true);
parsedStmt.analyze(analyzer);

// Restore the original result types and column labels.
Expand Down

0 comments on commit a151326

Please sign in to comment.