This is an automated email from the ASF dual-hosted git repository.

huajianlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 06a1efdb01 [fix](Nerieds) fix tpch and support trace plan's change 
event (#13957)
06a1efdb01 is described below

commit 06a1efdb018e6328e1b2e7426f193433602ed721
Author: 924060929 <924060...@qq.com>
AuthorDate: Fri Nov 4 15:01:06 2022 +0800

    [fix](Nerieds) fix tpch and support trace plan's change event (#13957)
    
    This pr fix some bugs for run tpc-h
    1. fix the avg(decimal) crash the backend. The fix code in 
`Avg.getFinalType()` and every child class of `ComputeSinature`
    2. fix the ReorderJoin dead loop. The fix code in 
`ReorderJoin.findInnerJoin()`
    3. fix the TimestampArithmetic can not bind the functions in the child. The 
fix code in `BindFunction.FunctionBinder.visitTimestampArithmetic()`
    
    New feature: support trace the plan's change event, you can `set 
enable_nereids_trace=true` to open trace log and see some log like this:
    ```
    2022-11-03 21:07:38,391 INFO (mysql-nio-pool-0|208) 
[Job.printTraceLog():128] ========== RewriteBottomUpJob ANALYZE_FILTER_SUBQUERY 
==========
    before:
    LogicalProject ( projects=[S_ACCTBAL#17, S_NAME#13, N_NAME#4, P_PARTKEY#19, 
P_MFGR#21, S_ADDRESS#14, S_PHONE#16, S_COMMENT#18] )
    +--LogicalFilter ( predicates=((((((((P_PARTKEY#19 = PS_PARTKEY#7) AND 
(S_SUPPKEY#12 = PS_SUPPKEY#8)) AND (P_SIZE#24 = 15)) AND (P_TYPE#23 like 
'%BRASS')) AND (S_NATIONKEY#15 = N_NATIONKEY#3)) AND (N_REGIONKEY#5 = 
R_REGIONKEY#0)) AND (R_NAME#1 = 'EUROPE')) AND (PS_SUPPLYCOST#10 =  
(SCALARSUBQUERY) (QueryPlan: LogicalAggregate ( phase=LOCAL, 
outputExpr=[min(PS_SUPPLYCOST#31) AS `min(PS_SUPPLYCOST)`#33], groupByExpr=[] 
)), (CorrelatedSlots: [P_PARTKEY#19, S_SUPPKEY#12, S_NATIONKEY#15, N [...]
       +--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
          |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
          |  |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
          |  |  |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
          |  |  |  |--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.part, 
output=[P_PARTKEY#19, P_NAME#20, P_MFGR#21, P_BRAND#22, P_TYPE#23, P_SIZE#24, 
P_CONTAINER#25, P_RETAILPRICE#26, P_COMMENT#27], candidateIndexIds=[], 
selectedIndexId=11076, preAgg=ON )
          |  |  |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.supplier, 
output=[S_SUPPKEY#12, S_NAME#13, S_ADDRESS#14, S_NATIONKEY#15, S_PHONE#16, 
S_ACCTBAL#17, S_COMMENT#18], candidateIndexIds=[], selectedIndexId=11124, 
preAgg=ON )
          |  |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.partsupp, 
output=[PS_PARTKEY#7, PS_SUPPKEY#8, PS_AVAILQTY#9, PS_SUPPLYCOST#10, 
PS_COMMENT#11], candidateIndexIds=[], selectedIndexId=11092, preAgg=ON )
          |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.nation, 
output=[N_NATIONKEY#3, N_NAME#4, N_REGIONKEY#5, N_COMMENT#6], 
candidateIndexIds=[], selectedIndexId=11044, preAgg=ON )
          +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.region, 
output=[R_REGIONKEY#0, R_NAME#1, R_COMMENT#2], candidateIndexIds=[], 
selectedIndexId=11108, preAgg=ON )
    
    after:
    LogicalProject ( projects=[S_ACCTBAL#17, S_NAME#13, N_NAME#4, P_PARTKEY#19, 
P_MFGR#21, S_ADDRESS#14, S_PHONE#16, S_COMMENT#18] )
    +--LogicalFilter ( predicates=((((((((P_PARTKEY#19 = PS_PARTKEY#7) AND 
(S_SUPPKEY#12 = PS_SUPPKEY#8)) AND (P_SIZE#24 = 15)) AND (P_TYPE#23 like 
'%BRASS')) AND (S_NATIONKEY#15 = N_NATIONKEY#3)) AND (N_REGIONKEY#5 = 
R_REGIONKEY#0)) AND (R_NAME#1 = 'EUROPE')) AND (PS_SUPPLYCOST#10 = 
min(PS_SUPPLYCOST)#33)) )
       +--LogicalProject ( projects=[P_PARTKEY#19, P_NAME#20, P_MFGR#21, 
P_BRAND#22, P_TYPE#23, P_SIZE#24, P_CONTAINER#25, P_RETAILPRICE#26, 
P_COMMENT#27, S_SUPPKEY#12, S_NAME#13, S_ADDRESS#14, S_NATIONKEY#15, 
S_PHONE#16, S_ACCTBAL#17, S_COMMENT#18, PS_PARTKEY#7, PS_SUPPKEY#8, 
PS_AVAILQTY#9, PS_SUPPLYCOST#10, PS_COMMENT#11, N_NATIONKEY#3, N_NAME#4, 
N_REGIONKEY#5, N_COMMENT#6, R_REGIONKEY#0, R_NAME#1, R_COMMENT#2, 
min(PS_SUPPLYCOST)#33] )
          +--LogicalApply ( correlationSlot=[P_PARTKEY#19, S_SUPPKEY#12, 
S_NATIONKEY#15, N_NATIONKEY#3, N_REGIONKEY#5, R_REGIONKEY#0, R_NAME#1], 
correlationFilter=Optional.empty )
             |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
             |  |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
             |  |  |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
             |  |  |  |--LogicalJoin ( type=CROSS_JOIN, hashJoinCondition=[], 
otherJoinCondition=[] )
             |  |  |  |  |--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.part, 
output=[P_PARTKEY#19, P_NAME#20, P_MFGR#21, P_BRAND#22, P_TYPE#23, P_SIZE#24, 
P_CONTAINER#25, P_RETAILPRICE#26, P_COMMENT#27], candidateIndexIds=[], 
selectedIndexId=11076, preAgg=ON )
             |  |  |  |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.supplier, 
output=[S_SUPPKEY#12, S_NAME#13, S_ADDRESS#14, S_NATIONKEY#15, S_PHONE#16, 
S_ACCTBAL#17, S_COMMENT#18], candidateIndexIds=[], selectedIndexId=11124, 
preAgg=ON )
             |  |  |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.partsupp, 
output=[PS_PARTKEY#7, PS_SUPPKEY#8, PS_AVAILQTY#9, PS_SUPPLYCOST#10, 
PS_COMMENT#11], candidateIndexIds=[], selectedIndexId=11092, preAgg=ON )
             |  |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.nation, 
output=[N_NATIONKEY#3, N_NAME#4, N_REGIONKEY#5, N_COMMENT#6], 
candidateIndexIds=[], selectedIndexId=11044, preAgg=ON )
             |  +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.region, 
output=[R_REGIONKEY#0, R_NAME#1, R_COMMENT#2], candidateIndexIds=[], 
selectedIndexId=11108, preAgg=ON )
             +--LogicalAggregate ( phase=LOCAL, 
outputExpr=[min(PS_SUPPLYCOST#31) AS `min(PS_SUPPLYCOST)`#33], groupByExpr=[] )
                +--LogicalFilter ( predicates=(((((P_PARTKEY#19 = 
PS_PARTKEY#28) AND (S_SUPPKEY#12 = PS_SUPPKEY#29)) AND (S_NATIONKEY#15 = 
N_NATIONKEY#3)) AND (N_REGIONKEY#5 = R_REGIONKEY#0)) AND (CAST(R_NAME AS 
STRING) = CAST(EUROPE AS STRING))) )
                   +--LogicalOlapScan ( 
qualified=default_cluster:regression_test_tpch_sf1_p1_tpch_sf1.partsupp, 
output=[PS_PARTKEY#28, PS_SUPPKEY#29, PS_AVAILQTY#30, PS_SUPPLYCOST#31, 
PS_COMMENT#32], candidateIndexIds=[], selectedIndexId=11092, preAgg=ON )
    
    ```
---
 .../apache/doris/analysis/FunctionCallExpr.java    |  5 +-
 .../doris/nereids/exceptions/ParseException.java   |  2 +-
 .../glue/translator/ExpressionTranslator.java      | 13 +++--
 .../java/org/apache/doris/nereids/jobs/Job.java    | 65 +++++++++++++++++++++-
 .../doris/nereids/jobs/cascades/ApplyRuleJob.java  |  8 +++
 .../nereids/jobs/rewrite/RewriteBottomUpJob.java   | 19 ++-----
 .../nereids/jobs/rewrite/RewriteTopDownJob.java    | 23 +++-----
 .../org/apache/doris/nereids/rules/RuleType.java   |  2 +-
 .../doris/nereids/rules/analysis/BindFunction.java |  4 ++
 .../logical/PushdownFilterThroughProject.java      |  2 +-
 .../nereids/rules/rewrite/logical/ReorderJoin.java |  8 +--
 .../functions/ExplicitlyCastableSignature.java     |  2 +-
 .../expressions/functions/IdenticalSignature.java  |  2 +-
 .../functions/ImplicitlyCastableSignature.java     |  2 +-
 .../functions/NullOrIdenticalSignature.java        |  2 +-
 .../trees/expressions/functions/agg/Avg.java       | 13 +++--
 .../trees/expressions/functions/scalar/Year.java   |  4 +-
 .../apache/doris/nereids/types/DecimalType.java    |  3 +-
 .../java/org/apache/doris/qe/SessionVariable.java  |  2 +-
 .../java/org/apache/doris/qe/StmtExecutor.java     |  2 +-
 .../nereids/datasets/tpch/AnalyzeTPCHTest.java     | 16 ++++--
 .../doris/nereids/parser/LimitClauseTest.java      |  4 +-
 .../doris/nereids/parser/NereidsParserTest.java    |  2 +-
 .../suites/nereids_syntax_p0/function.groovy       | 11 ++++
 24 files changed, 148 insertions(+), 68 deletions(-)

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 a1345ef57b..8a86a2c736 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
@@ -206,10 +206,12 @@ public class FunctionCallExpr extends Expr {
         originChildSize = children.size();
     }
 
-    public FunctionCallExpr(String functionName, FunctionParams params, 
Optional<List<Type>> argTypes) {
+    public FunctionCallExpr(String functionName, FunctionParams params, 
FunctionParams aggFnParams,
+            Optional<List<Type>> argTypes) {
         this.fnName = new FunctionName(functionName);
         this.fnParams = params;
         this.isMergeAggFn = false;
+        this.aggFnParams = aggFnParams;
         if (fnParams.exprs() != null) {
             children.addAll(fnParams.exprs());
         }
@@ -222,6 +224,7 @@ public class FunctionCallExpr extends Expr {
         this.fnName = functionName;
         this.fn = function;
         this.type = function.getReturnType();
+        this.fnParams = functionParams;
         if (functionParams.exprs() != null) {
             this.children.addAll(functionParams.exprs());
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/exceptions/ParseException.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/exceptions/ParseException.java
index 6eefc492b3..768bcfcb7c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/exceptions/ParseException.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/exceptions/ParseException.java
@@ -50,7 +50,7 @@ public class ParseException extends AnalysisException {
         if (start.line.isPresent() && start.startPosition.isPresent()) {
             int line = start.line.get();
             int startPosition = start.startPosition.get();
-            sb.append("(line ").append(line).append(", 
pos").append(startPosition).append(")").append("\n");
+            sb.append("(line ").append(line).append(", pos 
").append(startPosition).append(")").append("\n");
             if (command.isPresent()) {
                 sb.append("\n== SQL ==\n");
                 String cmd = command.get();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
index 2dec21bb76..c6f8589515 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java
@@ -297,18 +297,21 @@ public class ExpressionTranslator extends 
DefaultExpressionVisitor<Expr, PlanTra
             catalogParams.add(catalogExpr);
         }
 
+        boolean distinct = function.isDistinct();
+        FunctionParams aggFnParams = new FunctionParams(distinct, 
catalogParams);
+
         if (function instanceof Count) {
             Count count = (Count) function;
             if (count.isStar()) {
                 return new FunctionCallExpr(function.getName(), 
FunctionParams.createStarParam(),
-                        inputTypesBeforeDissemble);
+                        aggFnParams, inputTypesBeforeDissemble);
             } else if (count.isDistinct()) {
-                return new FunctionCallExpr(function.getName(), new 
FunctionParams(true, catalogParams),
-                        inputTypesBeforeDissemble);
+                return new FunctionCallExpr(function.getName(), new 
FunctionParams(distinct, catalogParams),
+                        aggFnParams, inputTypesBeforeDissemble);
             }
         }
-        return new FunctionCallExpr(function.getName(), new 
FunctionParams(false, catalogParams),
-                inputTypesBeforeDissemble);
+        return new FunctionCallExpr(function.getName(), new 
FunctionParams(distinct, catalogParams),
+                aggFnParams, inputTypesBeforeDissemble);
     }
 
     @Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
index ef76d23922..b2775e1e77 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
@@ -18,32 +18,47 @@
 package org.apache.doris.nereids.jobs;
 
 import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.memo.CopyInResult;
+import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.memo.GroupExpression;
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleSet;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.qe.ConnectContext;
+
+import com.google.common.base.Preconditions;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
  * Abstract class for all job using for analyze and optimize query plan in 
Nereids.
  */
 public abstract class Job {
+    public final Logger logger = LogManager.getLogger(getClass());
+
     protected JobType type;
     protected JobContext context;
     protected boolean once;
+    protected final boolean enableTrace;
 
     public Job(JobType type, JobContext context) {
-        this.type = type;
-        this.context = context;
-        this.once = true;
+        this(type, context, true);
     }
 
+    /** job full parameter constructor */
     public Job(JobType type, JobContext context, boolean once) {
         this.type = type;
         this.context = context;
         this.once = once;
+        ConnectContext connectContext = ConnectContext.get();
+        this.enableTrace = connectContext == null
+                ? false
+                : connectContext.getSessionVariable().isEnableNereidsTrace();
     }
 
     public void pushJob(Job job) {
@@ -73,4 +88,48 @@ public abstract class Job {
     }
 
     public abstract void execute() throws AnalysisException;
+
+    protected Optional<CopyInResult> invokeRewriteRuleWithTrace(Rule rule, 
Plan before, Group targetGroup) {
+        context.onInvokeRule(rule.getRuleType());
+
+        String traceBefore = enableTrace ? getTraceLog(rule) : null;
+
+        List<Plan> afters = rule.transform(before, 
context.getCascadesContext());
+        Preconditions.checkArgument(afters.size() == 1);
+        Plan after = afters.get(0);
+
+        if (after != before) {
+            CopyInResult result = context.getCascadesContext()
+                    .getMemo()
+                    .copyIn(after, targetGroup, true);
+
+            if (result.generateNewExpression && enableTrace) {
+                String traceAfter = getTraceLog(rule);
+                printTraceLog(rule, traceBefore, traceAfter);
+            }
+
+            return Optional.of(result);
+        }
+
+        return Optional.empty();
+    }
+
+    protected String getTraceLog(Rule rule) {
+        if (rule.isRewrite()) {
+            return context.getCascadesContext()
+                    .getMemo()
+                    .copyOut(false)
+                    .treeString();
+        } else {
+            return context.getCascadesContext()
+                    .getMemo()
+                    .getRoot()
+                    .treeString();
+        }
+    }
+
+    protected void printTraceLog(Rule rule, String traceBefore, String 
traceAfter) {
+        logger.info("========== {} {} ==========\nbefore:\n{}\n\nafter:\n{}\n",
+                getClass().getSimpleName(), rule.getRuleType(), traceBefore, 
traceAfter);
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
index f596635fc2..d263c8306f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
@@ -59,7 +59,10 @@ public class ApplyRuleJob extends Job {
         GroupExpressionMatching groupExpressionMatching
                 = new GroupExpressionMatching(rule.getPattern(), 
groupExpression);
         for (Plan plan : groupExpressionMatching) {
+            String traceBefore = enableTrace ? getTraceLog(rule) : null;
             context.onInvokeRule(rule.getRuleType());
+
+            boolean changed = false;
             List<Plan> newPlans = rule.transform(plan, 
context.getCascadesContext());
             for (Plan newPlan : newPlans) {
                 CopyInResult result = context.getCascadesContext()
@@ -69,6 +72,7 @@ public class ApplyRuleJob extends Job {
                     continue;
                 }
 
+                changed = true;
                 GroupExpression newGroupExpression = 
result.correspondingExpression;
                 if (newPlan instanceof LogicalPlan) {
                     pushJob(new OptimizeGroupExpressionJob(newGroupExpression, 
context));
@@ -77,6 +81,10 @@ public class ApplyRuleJob extends Job {
                     pushJob(new CostAndEnforcerJob(newGroupExpression, 
context));
                 }
             }
+            if (changed && enableTrace) {
+                String traceAfter = getTraceLog(rule);
+                printTraceLog(rule, traceBefore, traceAfter);
+            }
         }
         groupExpression.setApplied(rule);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
index f2841b114a..32c2b38c10 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
@@ -29,10 +29,9 @@ import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleFactory;
 import org.apache.doris.nereids.trees.plans.Plan;
 
-import com.google.common.base.Preconditions;
-
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
@@ -77,18 +76,10 @@ public class RewriteBottomUpJob extends Job {
             GroupExpressionMatching groupExpressionMatching
                     = new GroupExpressionMatching(rule.getPattern(), 
logicalExpression);
             for (Plan before : groupExpressionMatching) {
-                context.onInvokeRule(rule.getRuleType());
-                List<Plan> afters = rule.transform(before, 
context.getCascadesContext());
-                Preconditions.checkArgument(afters.size() == 1);
-                Plan after = afters.get(0);
-                if (after != before) {
-                    CopyInResult result = context.getCascadesContext()
-                            .getMemo()
-                            .copyIn(after, group, rule.isRewrite());
-                    if (result.generateNewExpression) {
-                        pushJob(new RewriteBottomUpJob(group, rules, context, 
false));
-                        return;
-                    }
+                Optional<CopyInResult> copyInResult = 
invokeRewriteRuleWithTrace(rule, before, group);
+                if (copyInResult.isPresent() && 
copyInResult.get().generateNewExpression) {
+                    pushJob(new RewriteBottomUpJob(group, rules, context, 
false));
+                    return;
                 }
             }
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
index 674a14f63e..103d07cf5f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
@@ -32,6 +32,7 @@ import com.google.common.base.Preconditions;
 
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /**
@@ -77,21 +78,13 @@ public class RewriteTopDownJob extends Job {
             // In topdown job, there must be only one matching plan.
             // This `for` loop runs at most once.
             for (Plan before : groupExpressionMatching) {
-                context.onInvokeRule(rule.getRuleType());
-                List<Plan> afters = rule.transform(before, 
context.getCascadesContext());
-                Preconditions.checkArgument(afters.size() == 1);
-                Plan after = afters.get(0);
-                if (after != before) {
-                    CopyInResult result = context.getCascadesContext()
-                            .getMemo()
-                            .copyIn(after, group, rule.isRewrite());
-                    if (result.generateNewExpression) {
-                        // new group-expr replaced the origin group-expr in 
`group`,
-                        // run this rule against this `group` again.
-                        context.setRewritten(true);
-                        pushJob(new RewriteTopDownJob(group, rules, context));
-                        return;
-                    }
+                Optional<CopyInResult> copyInResult = 
invokeRewriteRuleWithTrace(rule, before, group);
+                if (copyInResult.isPresent() && 
copyInResult.get().generateNewExpression) {
+                    // new group-expr replaced the origin group-expr in 
`group`,
+                    // run this rule against this `group` again.
+                    context.setRewritten(true);
+                    pushJob(new RewriteTopDownJob(group, rules, context));
+                    return;
                 }
             }
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
index a6f4641bb6..6231312601 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
@@ -89,7 +89,7 @@ public enum RuleType {
     PUSHDOWN_FILTER_THROUGH_JOIN(RuleTypeClass.REWRITE),
     PUSHDOWN_FILTER_THROUGH_LEFT_SEMI_JOIN(RuleTypeClass.REWRITE),
     PUSH_FILTER_INSIDE_JOIN(RuleTypeClass.REWRITE),
-    PUSHDOWN_FILTER_THROUGH_PROJET(RuleTypeClass.REWRITE),
+    PUSHDOWN_FILTER_THROUGH_PROJECT(RuleTypeClass.REWRITE),
     PUSHDOWN_PROJECT_THROUGHT_LIMIT(RuleTypeClass.REWRITE),
     // column prune rules,
     COLUMN_PRUNE_AGGREGATION_CHILD(RuleTypeClass.REWRITE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindFunction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindFunction.java
index a93c537fa1..80d6144cbb 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindFunction.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindFunction.java
@@ -115,6 +115,8 @@ public class BindFunction implements AnalysisRuleFactory {
 
         @Override
         public BoundFunction visitUnboundFunction(UnboundFunction 
unboundFunction, Env env) {
+            unboundFunction = (UnboundFunction) 
super.visitUnboundFunction(unboundFunction, env);
+
             // FunctionRegistry can't support boolean arg now, tricky here.
             if (unboundFunction.getName().equalsIgnoreCase("count")) {
                 List<Expression> arguments = unboundFunction.getArguments();
@@ -141,6 +143,8 @@ public class BindFunction implements AnalysisRuleFactory {
          */
         @Override
         public Expression visitTimestampArithmetic(TimestampArithmetic 
arithmetic, Env context) {
+            arithmetic = (TimestampArithmetic) 
super.visitTimestampArithmetic(arithmetic, context);
+
             String funcOpName;
             if (arithmetic.getFuncName() == null) {
                 // e.g. YEARS_ADD, MONTHS_SUB
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughProject.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughProject.java
index d38e6904bb..2a41a75de9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughProject.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughProject.java
@@ -44,6 +44,6 @@ public class PushdownFilterThroughProject extends 
OneRewriteRuleFactory {
                             project.child()
                     )
             );
-        }).toRule(RuleType.PUSHDOWN_FILTER_THROUGH_PROJET);
+        }).toRule(RuleType.PUSHDOWN_FILTER_THROUGH_PROJECT);
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/ReorderJoin.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/ReorderJoin.java
index c0c8622348..3ee308527b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/ReorderJoin.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/ReorderJoin.java
@@ -351,15 +351,15 @@ public class ReorderJoin extends OneRewriteRuleFactory {
         }
         // All { left -> one in [candidates] } is CrossJoin
         // Generate a CrossJoin
-        for (int j = candidates.size() - 1; j >= 0; j--) {
-            if (usedPlansIndex.contains(j)) {
+        for (int i = 0; i < candidates.size(); i++) {
+            if (usedPlansIndex.contains(i)) {
                 continue;
             }
-            usedPlansIndex.add(j);
+            usedPlansIndex.add(i);
             return new LogicalJoin<>(JoinType.CROSS_JOIN,
                     ExpressionUtils.EMPTY_CONDITION,
                     otherJoinConditions,
-                    left, candidates.get(j));
+                    left, candidates.get(i));
         }
 
         throw new RuntimeException("findInnerJoin: can't reach here");
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExplicitlyCastableSignature.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExplicitlyCastableSignature.java
index 1edf15f1f4..b728d0320c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExplicitlyCastableSignature.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExplicitlyCastableSignature.java
@@ -30,7 +30,7 @@ import 
org.apache.doris.nereids.types.coercion.AbstractDataType;
 public interface ExplicitlyCastableSignature extends ComputeSignature {
     static boolean isExplicitlyCastable(AbstractDataType signatureType, 
AbstractDataType realType) {
         // TODO: copy canCastTo method to DataType
-        return Type.canCastTo(signatureType.toCatalogDataType(), 
realType.toCatalogDataType());
+        return Type.canCastTo(realType.toCatalogDataType(), 
signatureType.toCatalogDataType());
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/IdenticalSignature.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/IdenticalSignature.java
index c2a3dc7390..2beab26027 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/IdenticalSignature.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/IdenticalSignature.java
@@ -29,7 +29,7 @@ import 
org.apache.doris.nereids.types.coercion.AbstractDataType;
 public interface IdenticalSignature extends ComputeSignature {
     static boolean isIdentical(AbstractDataType signatureType, 
AbstractDataType realType) {
         // TODO: copy matchesType to DataType
-        return 
signatureType.toCatalogDataType().matchesType(realType.toCatalogDataType());
+        return 
realType.toCatalogDataType().matchesType(signatureType.toCatalogDataType());
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ImplicitlyCastableSignature.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ImplicitlyCastableSignature.java
index d9891d4d2f..3c830ef31b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ImplicitlyCastableSignature.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ImplicitlyCastableSignature.java
@@ -30,7 +30,7 @@ import 
org.apache.doris.nereids.types.coercion.AbstractDataType;
 public interface ImplicitlyCastableSignature extends ComputeSignature {
     static boolean isImplicitlyCastable(AbstractDataType signatureType, 
AbstractDataType realType) {
         // TODO: copy isImplicitlyCastable method to DataType
-        return Type.isImplicitlyCastable(signatureType.toCatalogDataType(), 
realType.toCatalogDataType(), true);
+        return Type.isImplicitlyCastable(realType.toCatalogDataType(), 
signatureType.toCatalogDataType(), true);
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/NullOrIdenticalSignature.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/NullOrIdenticalSignature.java
index cc2d2fdf92..164d175729 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/NullOrIdenticalSignature.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/NullOrIdenticalSignature.java
@@ -31,7 +31,7 @@ public interface NullOrIdenticalSignature extends 
ComputeSignature {
     static boolean isNullOrIdentical(AbstractDataType signatureType, 
AbstractDataType realType) {
         // TODO: copy matchesType to DataType
         return realType instanceof NullType
-                || 
signatureType.toCatalogDataType().matchesType(realType.toCatalogDataType());
+                || 
realType.toCatalogDataType().matchesType(signatureType.toCatalogDataType());
     }
 
     @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
index cea26f3344..406004236d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java
@@ -54,18 +54,21 @@ public class Avg extends AggregateFunction implements 
UnaryExpression, ImplicitC
 
     @Override
     public DataType getFinalType() {
-        if (child().getDataType() instanceof DecimalType) {
-            return child().getDataType();
-        } else if (child().getDataType().isDate()) {
+        DataType argumentType = inputTypesBeforeDissemble()
+                .map(types -> types.get(0))
+                .orElse(child().getDataType());
+        if (argumentType instanceof DecimalType) {
+            return argumentType;
+        } else if (argumentType.isDate()) {
             return DateType.INSTANCE;
-        } else if (child().getDataType().isDateTime()) {
+        } else if (argumentType.isDateTime()) {
             return DateTimeType.INSTANCE;
         } else {
             return DoubleType.INSTANCE;
         }
     }
 
-    // TODO: We should return a complex type: 
PartialAggType(bufferTypes=[Double, Int], inputType=Int)
+    // TODO: We should return a complex type: 
PartialAggType(bufferTypes=[Double, Int], inputTypes=[Int])
     //       to denote sum(double) and count(int)
     @Override
     public DataType getIntermediateType() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Year.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Year.java
index 688eb5516d..58e6df906e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Year.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Year.java
@@ -40,9 +40,9 @@ public class Year extends ScalarFunction
         implements UnaryExpression, ExplicitlyCastableSignature, 
AlwaysNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE),
             
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeType.INSTANCE),
-            
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeV2Type.INSTANCE),
-            
FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE)
+            
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeV2Type.INSTANCE)
     );
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DecimalType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DecimalType.java
index 545bdae390..e19b3ee52f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DecimalType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DecimalType.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.types;
 
+import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.nereids.types.coercion.AbstractDataType;
 import org.apache.doris.nereids.types.coercion.FractionalType;
@@ -99,7 +100,7 @@ public class DecimalType extends FractionalType {
 
     @Override
     public Type toCatalogDataType() {
-        return Type.MAX_DECIMALV2_TYPE;
+        return ScalarType.createDecimalType(precision, scale);
     }
 
     public int getPrecision() {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index d91581b02c..205779b77e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -517,7 +517,7 @@ public class SessionVariable implements Serializable, 
Writable {
     private boolean nereidsStarSchemaSupport = true;
 
     @VariableMgr.VarAttr(name = ENABLE_NEREIDS_TRACE)
-    private boolean enableNereidsTrace = true;
+    private boolean enableNereidsTrace = false;
 
     @VariableMgr.VarAttr(name = ENABLE_NEREIDS_RUNTIME_FILTER)
     private boolean enableNereidsRuntimeFilter = true;
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 d60b7fb97d..ae2a321b94 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
@@ -724,7 +724,7 @@ public class StmtExecutor implements ProfileWriter {
                 } catch (UserException e) {
                     throw e;
                 } catch (Exception e) {
-                    LOG.warn("Analyze failed. {}", 
context.getQueryIdentifier(), e);
+                    LOG.error("Analyze failed. {}", 
context.getQueryIdentifier(), e);
                     if (parsedStmt instanceof LogicalPlanAdapter) {
                         throw new NereidsException(new 
AnalysisException("Unexpected exception: " + e.getMessage(), e));
                     }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/datasets/tpch/AnalyzeTPCHTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/datasets/tpch/AnalyzeTPCHTest.java
index 44de365d5d..ae0dfc754e 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/datasets/tpch/AnalyzeTPCHTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/datasets/tpch/AnalyzeTPCHTest.java
@@ -17,13 +17,15 @@
 
 package org.apache.doris.nereids.datasets.tpch;
 
+import org.junit.jupiter.api.Test;
+
 /**
  * There are still many functions that have not been implemented,
  * so the tpch cannot be fully parsed, and the interface is only reserved here.
  * When the related functions of tpch are supported, the comments will be 
deleted and the analyze of tpch will be verified.
  */
 public class AnalyzeTPCHTest extends TPCHTestBase {
-    /*
+
     @Test
     public void q1() {
         checkAnalyze(TPCHUtils.Q1);
@@ -139,10 +141,11 @@ public class AnalyzeTPCHTest extends TPCHTestBase {
         checkAnalyze(TPCHUtils.Q17);
     }
 
-    @Test
+    // TODO: support [broadcast] hint
+    /*@Test
     public void q17_rewrite() {
         checkAnalyze(TPCHUtils.Q17_rewrite);
-    }
+    }*/
 
     @Test
     public void q18() {
@@ -179,13 +182,14 @@ public class AnalyzeTPCHTest extends TPCHTestBase {
         checkAnalyze(TPCHUtils.Q21_rewrite);
     }
 
-    @Test
+    // NOTE: not support '1 for 2' syntax
+    /*@Test
     public void q22() {
         checkAnalyze(TPCHUtils.Q22);
-    }
+    }*/
 
     @Test
     public void q22_rewrite() {
         checkAnalyze(TPCHUtils.Q22_rewrite);
-    }*/
+    }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/LimitClauseTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/LimitClauseTest.java
index 8312877364..fdf42fbcdc 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/LimitClauseTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/LimitClauseTest.java
@@ -54,7 +54,7 @@ public class LimitClauseTest extends ParserTestBase {
         parsePlan("SELECT b FROM test limit 3 offset 100")
                 .assertThrowsExactly(ParseException.class)
                 .assertMessageContains("\n"
-                        + "OFFSET requires an ORDER BY clause(line 1, pos19)\n"
+                        + "OFFSET requires an ORDER BY clause(line 1, pos 
19)\n"
                         + "\n"
                         + "== SQL ==\n"
                         + "SELECT b FROM test limit 3 offset 100\n"
@@ -63,7 +63,7 @@ public class LimitClauseTest extends ParserTestBase {
         parsePlan("SELECT b FROM test limit 100, 3")
                 .assertThrowsExactly(ParseException.class)
                 .assertMessageContains("\n"
-                        + "OFFSET requires an ORDER BY clause(line 1, pos19)\n"
+                        + "OFFSET requires an ORDER BY clause(line 1, pos 
19)\n"
                         + "\n"
                         + "== SQL ==\n"
                         + "SELECT b FROM test limit 100, 3\n"
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
index 4e1330ad55..573ee9e905 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
@@ -69,7 +69,7 @@ public class NereidsParserTest extends ParserTestBase {
     public void testErrorListener() {
         parsePlan("select * from t1 where a = 1 illegal_symbol")
                 .assertThrowsExactly(ParseException.class)
-                .assertMessageEquals("\nextraneous input 'illegal_symbol' 
expecting {<EOF>, ';'}(line 1, pos29)\n");
+                .assertMessageEquals("\nextraneous input 'illegal_symbol' 
expecting {<EOF>, ';'}(line 1, pos 29)\n");
     }
 
     @Test
diff --git a/regression-test/suites/nereids_syntax_p0/function.groovy 
b/regression-test/suites/nereids_syntax_p0/function.groovy
index 1ad34fdedf..08886cb0ed 100644
--- a/regression-test/suites/nereids_syntax_p0/function.groovy
+++ b/regression-test/suites/nereids_syntax_p0/function.groovy
@@ -52,5 +52,16 @@ suite("function") {
     order_qt_avg """
         SELECT avg(lo_tax), avg(lo_extendedprice) AS avg_extendedprice FROM 
lineorder;
     """
+
+    // nested function
+    test {
+        sql "select cast(date('1994-01-01') + interval '1' YEAR as varchar)"
+        result([["1995-01-01 00:00:00"]])
+    }
+
+    test {
+        sql "select substring(substring('1994-01-01', 5), 3)"
+        result([["1-01"]])
+    }
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org


Reply via email to