Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8d13906

Browse files
924060929wangxiangyu@360shuke.com
authored and
wangxiangyu@360shuke.com
committedNov 7, 2022
[fix](Nerieds) fix tpch and support trace plan's change event (apache#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)`apache#33], groupByExpr=[] )), (CorrelatedSlots: [P_PARTKEY#19, S_SUPPKEY#12, S_NATIONKEY#15, N_NATIONKEY#3, N_REGIONKEY#5, R_REGIONKEY#0, R_NAME#1]))) ) +--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)apache#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)apache#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)`apache#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 ) ```
1 parent f8806ea commit 8d13906

24 files changed

+148
-68
lines changed
 

‎fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,12 @@ private FunctionCallExpr(
206206
originChildSize = children.size();
207207
}
208208

209-
public FunctionCallExpr(String functionName, FunctionParams params, Optional<List<Type>> argTypes) {
209+
public FunctionCallExpr(String functionName, FunctionParams params, FunctionParams aggFnParams,
210+
Optional<List<Type>> argTypes) {
210211
this.fnName = new FunctionName(functionName);
211212
this.fnParams = params;
212213
this.isMergeAggFn = false;
214+
this.aggFnParams = aggFnParams;
213215
if (fnParams.exprs() != null) {
214216
children.addAll(fnParams.exprs());
215217
}
@@ -222,6 +224,7 @@ public FunctionCallExpr(FunctionName functionName, Function function, FunctionPa
222224
this.fnName = functionName;
223225
this.fn = function;
224226
this.type = function.getReturnType();
227+
this.fnParams = functionParams;
225228
if (functionParams.exprs() != null) {
226229
this.children.addAll(functionParams.exprs());
227230
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/exceptions/ParseException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public String getMessage() {
5050
if (start.line.isPresent() && start.startPosition.isPresent()) {
5151
int line = start.line.get();
5252
int startPosition = start.startPosition.get();
53-
sb.append("(line ").append(line).append(", pos").append(startPosition).append(")").append("\n");
53+
sb.append("(line ").append(line).append(", pos ").append(startPosition).append(")").append("\n");
5454
if (command.isPresent()) {
5555
sb.append("\n== SQL ==\n");
5656
String cmd = command.get();

‎fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/ExpressionTranslator.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -297,18 +297,21 @@ public Expr visitAggregateFunction(AggregateFunction function, PlanTranslatorCon
297297
catalogParams.add(catalogExpr);
298298
}
299299

300+
boolean distinct = function.isDistinct();
301+
FunctionParams aggFnParams = new FunctionParams(distinct, catalogParams);
302+
300303
if (function instanceof Count) {
301304
Count count = (Count) function;
302305
if (count.isStar()) {
303306
return new FunctionCallExpr(function.getName(), FunctionParams.createStarParam(),
304-
inputTypesBeforeDissemble);
307+
aggFnParams, inputTypesBeforeDissemble);
305308
} else if (count.isDistinct()) {
306-
return new FunctionCallExpr(function.getName(), new FunctionParams(true, catalogParams),
307-
inputTypesBeforeDissemble);
309+
return new FunctionCallExpr(function.getName(), new FunctionParams(distinct, catalogParams),
310+
aggFnParams, inputTypesBeforeDissemble);
308311
}
309312
}
310-
return new FunctionCallExpr(function.getName(), new FunctionParams(false, catalogParams),
311-
inputTypesBeforeDissemble);
313+
return new FunctionCallExpr(function.getName(), new FunctionParams(distinct, catalogParams),
314+
aggFnParams, inputTypesBeforeDissemble);
312315
}
313316

314317
@Override

‎fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java

+62-3
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,47 @@
1818
package org.apache.doris.nereids.jobs;
1919

2020
import org.apache.doris.nereids.exceptions.AnalysisException;
21+
import org.apache.doris.nereids.memo.CopyInResult;
22+
import org.apache.doris.nereids.memo.Group;
2123
import org.apache.doris.nereids.memo.GroupExpression;
2224
import org.apache.doris.nereids.rules.Rule;
2325
import org.apache.doris.nereids.rules.RuleSet;
26+
import org.apache.doris.nereids.trees.plans.Plan;
27+
import org.apache.doris.qe.ConnectContext;
28+
29+
import com.google.common.base.Preconditions;
30+
import org.apache.logging.log4j.LogManager;
31+
import org.apache.logging.log4j.Logger;
2432

2533
import java.util.List;
2634
import java.util.Objects;
35+
import java.util.Optional;
2736
import java.util.stream.Collectors;
2837

2938
/**
3039
* Abstract class for all job using for analyze and optimize query plan in Nereids.
3140
*/
3241
public abstract class Job {
42+
public final Logger logger = LogManager.getLogger(getClass());
43+
3344
protected JobType type;
3445
protected JobContext context;
3546
protected boolean once;
47+
protected final boolean enableTrace;
3648

3749
public Job(JobType type, JobContext context) {
38-
this.type = type;
39-
this.context = context;
40-
this.once = true;
50+
this(type, context, true);
4151
}
4252

53+
/** job full parameter constructor */
4354
public Job(JobType type, JobContext context, boolean once) {
4455
this.type = type;
4556
this.context = context;
4657
this.once = once;
58+
ConnectContext connectContext = ConnectContext.get();
59+
this.enableTrace = connectContext == null
60+
? false
61+
: connectContext.getSessionVariable().isEnableNereidsTrace();
4762
}
4863

4964
public void pushJob(Job job) {
@@ -73,4 +88,48 @@ public List<Rule> getValidRules(GroupExpression groupExpression,
7388
}
7489

7590
public abstract void execute() throws AnalysisException;
91+
92+
protected Optional<CopyInResult> invokeRewriteRuleWithTrace(Rule rule, Plan before, Group targetGroup) {
93+
context.onInvokeRule(rule.getRuleType());
94+
95+
String traceBefore = enableTrace ? getTraceLog(rule) : null;
96+
97+
List<Plan> afters = rule.transform(before, context.getCascadesContext());
98+
Preconditions.checkArgument(afters.size() == 1);
99+
Plan after = afters.get(0);
100+
101+
if (after != before) {
102+
CopyInResult result = context.getCascadesContext()
103+
.getMemo()
104+
.copyIn(after, targetGroup, true);
105+
106+
if (result.generateNewExpression && enableTrace) {
107+
String traceAfter = getTraceLog(rule);
108+
printTraceLog(rule, traceBefore, traceAfter);
109+
}
110+
111+
return Optional.of(result);
112+
}
113+
114+
return Optional.empty();
115+
}
116+
117+
protected String getTraceLog(Rule rule) {
118+
if (rule.isRewrite()) {
119+
return context.getCascadesContext()
120+
.getMemo()
121+
.copyOut(false)
122+
.treeString();
123+
} else {
124+
return context.getCascadesContext()
125+
.getMemo()
126+
.getRoot()
127+
.treeString();
128+
}
129+
}
130+
131+
protected void printTraceLog(Rule rule, String traceBefore, String traceAfter) {
132+
logger.info("========== {} {} ==========\nbefore:\n{}\n\nafter:\n{}\n",
133+
getClass().getSimpleName(), rule.getRuleType(), traceBefore, traceAfter);
134+
}
76135
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java

+8
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ public void execute() throws AnalysisException {
5959
GroupExpressionMatching groupExpressionMatching
6060
= new GroupExpressionMatching(rule.getPattern(), groupExpression);
6161
for (Plan plan : groupExpressionMatching) {
62+
String traceBefore = enableTrace ? getTraceLog(rule) : null;
6263
context.onInvokeRule(rule.getRuleType());
64+
65+
boolean changed = false;
6366
List<Plan> newPlans = rule.transform(plan, context.getCascadesContext());
6467
for (Plan newPlan : newPlans) {
6568
CopyInResult result = context.getCascadesContext()
@@ -69,6 +72,7 @@ public void execute() throws AnalysisException {
6972
continue;
7073
}
7174

75+
changed = true;
7276
GroupExpression newGroupExpression = result.correspondingExpression;
7377
if (newPlan instanceof LogicalPlan) {
7478
pushJob(new OptimizeGroupExpressionJob(newGroupExpression, context));
@@ -77,6 +81,10 @@ public void execute() throws AnalysisException {
7781
pushJob(new CostAndEnforcerJob(newGroupExpression, context));
7882
}
7983
}
84+
if (changed && enableTrace) {
85+
String traceAfter = getTraceLog(rule);
86+
printTraceLog(rule, traceBefore, traceAfter);
87+
}
8088
}
8189
groupExpression.setApplied(rule);
8290
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java

+5-14
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@
2929
import org.apache.doris.nereids.rules.RuleFactory;
3030
import org.apache.doris.nereids.trees.plans.Plan;
3131

32-
import com.google.common.base.Preconditions;
33-
3432
import java.util.List;
3533
import java.util.Objects;
34+
import java.util.Optional;
3635
import java.util.stream.Collectors;
3736

3837
/**
@@ -77,18 +76,10 @@ public void execute() throws AnalysisException {
7776
GroupExpressionMatching groupExpressionMatching
7877
= new GroupExpressionMatching(rule.getPattern(), logicalExpression);
7978
for (Plan before : groupExpressionMatching) {
80-
context.onInvokeRule(rule.getRuleType());
81-
List<Plan> afters = rule.transform(before, context.getCascadesContext());
82-
Preconditions.checkArgument(afters.size() == 1);
83-
Plan after = afters.get(0);
84-
if (after != before) {
85-
CopyInResult result = context.getCascadesContext()
86-
.getMemo()
87-
.copyIn(after, group, rule.isRewrite());
88-
if (result.generateNewExpression) {
89-
pushJob(new RewriteBottomUpJob(group, rules, context, false));
90-
return;
91-
}
79+
Optional<CopyInResult> copyInResult = invokeRewriteRuleWithTrace(rule, before, group);
80+
if (copyInResult.isPresent() && copyInResult.get().generateNewExpression) {
81+
pushJob(new RewriteBottomUpJob(group, rules, context, false));
82+
return;
9283
}
9384
}
9485
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java

+8-15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import java.util.List;
3434
import java.util.Objects;
35+
import java.util.Optional;
3536
import java.util.stream.Collectors;
3637

3738
/**
@@ -77,21 +78,13 @@ public void execute() {
7778
// In topdown job, there must be only one matching plan.
7879
// This `for` loop runs at most once.
7980
for (Plan before : groupExpressionMatching) {
80-
context.onInvokeRule(rule.getRuleType());
81-
List<Plan> afters = rule.transform(before, context.getCascadesContext());
82-
Preconditions.checkArgument(afters.size() == 1);
83-
Plan after = afters.get(0);
84-
if (after != before) {
85-
CopyInResult result = context.getCascadesContext()
86-
.getMemo()
87-
.copyIn(after, group, rule.isRewrite());
88-
if (result.generateNewExpression) {
89-
// new group-expr replaced the origin group-expr in `group`,
90-
// run this rule against this `group` again.
91-
context.setRewritten(true);
92-
pushJob(new RewriteTopDownJob(group, rules, context));
93-
return;
94-
}
81+
Optional<CopyInResult> copyInResult = invokeRewriteRuleWithTrace(rule, before, group);
82+
if (copyInResult.isPresent() && copyInResult.get().generateNewExpression) {
83+
// new group-expr replaced the origin group-expr in `group`,
84+
// run this rule against this `group` again.
85+
context.setRewritten(true);
86+
pushJob(new RewriteTopDownJob(group, rules, context));
87+
return;
9588
}
9689
}
9790
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public enum RuleType {
8989
PUSHDOWN_FILTER_THROUGH_JOIN(RuleTypeClass.REWRITE),
9090
PUSHDOWN_FILTER_THROUGH_LEFT_SEMI_JOIN(RuleTypeClass.REWRITE),
9191
PUSH_FILTER_INSIDE_JOIN(RuleTypeClass.REWRITE),
92-
PUSHDOWN_FILTER_THROUGH_PROJET(RuleTypeClass.REWRITE),
92+
PUSHDOWN_FILTER_THROUGH_PROJECT(RuleTypeClass.REWRITE),
9393
PUSHDOWN_PROJECT_THROUGHT_LIMIT(RuleTypeClass.REWRITE),
9494
// column prune rules,
9595
COLUMN_PRUNE_AGGREGATION_CHILD(RuleTypeClass.REWRITE),

‎fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindFunction.java

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ public <E extends Expression> E bind(E expression, Env env) {
115115

116116
@Override
117117
public BoundFunction visitUnboundFunction(UnboundFunction unboundFunction, Env env) {
118+
unboundFunction = (UnboundFunction) super.visitUnboundFunction(unboundFunction, env);
119+
118120
// FunctionRegistry can't support boolean arg now, tricky here.
119121
if (unboundFunction.getName().equalsIgnoreCase("count")) {
120122
List<Expression> arguments = unboundFunction.getArguments();
@@ -141,6 +143,8 @@ public BoundFunction visitUnboundFunction(UnboundFunction unboundFunction, Env e
141143
*/
142144
@Override
143145
public Expression visitTimestampArithmetic(TimestampArithmetic arithmetic, Env context) {
146+
arithmetic = (TimestampArithmetic) super.visitTimestampArithmetic(arithmetic, context);
147+
144148
String funcOpName;
145149
if (arithmetic.getFuncName() == null) {
146150
// e.g. YEARS_ADD, MONTHS_SUB

‎fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/PushdownFilterThroughProject.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ public Rule build() {
4444
project.child()
4545
)
4646
);
47-
}).toRule(RuleType.PUSHDOWN_FILTER_THROUGH_PROJET);
47+
}).toRule(RuleType.PUSHDOWN_FILTER_THROUGH_PROJECT);
4848
}
4949
}

‎fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/ReorderJoin.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,15 @@ private Set<Slot> getJoinOutput(Plan left, Plan right) {
351351
}
352352
// All { left -> one in [candidates] } is CrossJoin
353353
// Generate a CrossJoin
354-
for (int j = candidates.size() - 1; j >= 0; j--) {
355-
if (usedPlansIndex.contains(j)) {
354+
for (int i = 0; i < candidates.size(); i++) {
355+
if (usedPlansIndex.contains(i)) {
356356
continue;
357357
}
358-
usedPlansIndex.add(j);
358+
usedPlansIndex.add(i);
359359
return new LogicalJoin<>(JoinType.CROSS_JOIN,
360360
ExpressionUtils.EMPTY_CONDITION,
361361
otherJoinConditions,
362-
left, candidates.get(j));
362+
left, candidates.get(i));
363363
}
364364

365365
throw new RuntimeException("findInnerJoin: can't reach here");

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ExplicitlyCastableSignature.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
public interface ExplicitlyCastableSignature extends ComputeSignature {
3131
static boolean isExplicitlyCastable(AbstractDataType signatureType, AbstractDataType realType) {
3232
// TODO: copy canCastTo method to DataType
33-
return Type.canCastTo(signatureType.toCatalogDataType(), realType.toCatalogDataType());
33+
return Type.canCastTo(realType.toCatalogDataType(), signatureType.toCatalogDataType());
3434
}
3535

3636
@Override

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/IdenticalSignature.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
public interface IdenticalSignature extends ComputeSignature {
3030
static boolean isIdentical(AbstractDataType signatureType, AbstractDataType realType) {
3131
// TODO: copy matchesType to DataType
32-
return signatureType.toCatalogDataType().matchesType(realType.toCatalogDataType());
32+
return realType.toCatalogDataType().matchesType(signatureType.toCatalogDataType());
3333
}
3434

3535
@Override

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/ImplicitlyCastableSignature.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
public interface ImplicitlyCastableSignature extends ComputeSignature {
3131
static boolean isImplicitlyCastable(AbstractDataType signatureType, AbstractDataType realType) {
3232
// TODO: copy isImplicitlyCastable method to DataType
33-
return Type.isImplicitlyCastable(signatureType.toCatalogDataType(), realType.toCatalogDataType(), true);
33+
return Type.isImplicitlyCastable(realType.toCatalogDataType(), signatureType.toCatalogDataType(), true);
3434
}
3535

3636
@Override

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/NullOrIdenticalSignature.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public interface NullOrIdenticalSignature extends ComputeSignature {
3131
static boolean isNullOrIdentical(AbstractDataType signatureType, AbstractDataType realType) {
3232
// TODO: copy matchesType to DataType
3333
return realType instanceof NullType
34-
|| signatureType.toCatalogDataType().matchesType(realType.toCatalogDataType());
34+
|| realType.toCatalogDataType().matchesType(signatureType.toCatalogDataType());
3535
}
3636

3737
@Override

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/Avg.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,21 @@ public Avg(AggregateParam aggregateParam, Expression child) {
5454

5555
@Override
5656
public DataType getFinalType() {
57-
if (child().getDataType() instanceof DecimalType) {
58-
return child().getDataType();
59-
} else if (child().getDataType().isDate()) {
57+
DataType argumentType = inputTypesBeforeDissemble()
58+
.map(types -> types.get(0))
59+
.orElse(child().getDataType());
60+
if (argumentType instanceof DecimalType) {
61+
return argumentType;
62+
} else if (argumentType.isDate()) {
6063
return DateType.INSTANCE;
61-
} else if (child().getDataType().isDateTime()) {
64+
} else if (argumentType.isDateTime()) {
6265
return DateTimeType.INSTANCE;
6366
} else {
6467
return DoubleType.INSTANCE;
6568
}
6669
}
6770

68-
// TODO: We should return a complex type: PartialAggType(bufferTypes=[Double, Int], inputType=Int)
71+
// TODO: We should return a complex type: PartialAggType(bufferTypes=[Double, Int], inputTypes=[Int])
6972
// to denote sum(double) and count(int)
7073
@Override
7174
public DataType getIntermediateType() {

‎fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Year.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public class Year extends ScalarFunction
4040
implements UnaryExpression, ExplicitlyCastableSignature, AlwaysNullable {
4141

4242
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
43+
FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE),
4344
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeType.INSTANCE),
44-
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeV2Type.INSTANCE),
45-
FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE)
45+
FunctionSignature.ret(IntegerType.INSTANCE).args(DateTimeV2Type.INSTANCE)
4646
);
4747

4848
/**

‎fe/fe-core/src/main/java/org/apache/doris/nereids/types/DecimalType.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.doris.nereids.types;
1919

20+
import org.apache.doris.catalog.ScalarType;
2021
import org.apache.doris.catalog.Type;
2122
import org.apache.doris.nereids.types.coercion.AbstractDataType;
2223
import org.apache.doris.nereids.types.coercion.FractionalType;
@@ -99,7 +100,7 @@ private static DecimalType widerDecimalType(int leftPrecision, int rightPrecisio
99100

100101
@Override
101102
public Type toCatalogDataType() {
102-
return Type.MAX_DECIMALV2_TYPE;
103+
return ScalarType.createDecimalType(precision, scale);
103104
}
104105

105106
public int getPrecision() {

‎fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ public class SessionVariable implements Serializable, Writable {
517517
private boolean nereidsStarSchemaSupport = true;
518518

519519
@VariableMgr.VarAttr(name = ENABLE_NEREIDS_TRACE)
520-
private boolean enableNereidsTrace = true;
520+
private boolean enableNereidsTrace = false;
521521

522522
@VariableMgr.VarAttr(name = ENABLE_NEREIDS_RUNTIME_FILTER)
523523
private boolean enableNereidsRuntimeFilter = true;

‎fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ public void analyze(TQueryOptions tQueryOptions) throws UserException {
724724
} catch (UserException e) {
725725
throw e;
726726
} catch (Exception e) {
727-
LOG.warn("Analyze failed. {}", context.getQueryIdentifier(), e);
727+
LOG.error("Analyze failed. {}", context.getQueryIdentifier(), e);
728728
if (parsedStmt instanceof LogicalPlanAdapter) {
729729
throw new NereidsException(new AnalysisException("Unexpected exception: " + e.getMessage(), e));
730730
}

‎fe/fe-core/src/test/java/org/apache/doris/nereids/datasets/tpch/AnalyzeTPCHTest.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
package org.apache.doris.nereids.datasets.tpch;
1919

20+
import org.junit.jupiter.api.Test;
21+
2022
/**
2123
* There are still many functions that have not been implemented,
2224
* so the tpch cannot be fully parsed, and the interface is only reserved here.
2325
* When the related functions of tpch are supported, the comments will be deleted and the analyze of tpch will be verified.
2426
*/
2527
public class AnalyzeTPCHTest extends TPCHTestBase {
26-
/*
28+
2729
@Test
2830
public void q1() {
2931
checkAnalyze(TPCHUtils.Q1);
@@ -139,10 +141,11 @@ public void q17() {
139141
checkAnalyze(TPCHUtils.Q17);
140142
}
141143

142-
@Test
144+
// TODO: support [broadcast] hint
145+
/*@Test
143146
public void q17_rewrite() {
144147
checkAnalyze(TPCHUtils.Q17_rewrite);
145-
}
148+
}*/
146149

147150
@Test
148151
public void q18() {
@@ -179,13 +182,14 @@ public void q21_rewrite() {
179182
checkAnalyze(TPCHUtils.Q21_rewrite);
180183
}
181184

182-
@Test
185+
// NOTE: not support '1 for 2' syntax
186+
/*@Test
183187
public void q22() {
184188
checkAnalyze(TPCHUtils.Q22);
185-
}
189+
}*/
186190

187191
@Test
188192
public void q22_rewrite() {
189193
checkAnalyze(TPCHUtils.Q22_rewrite);
190-
}*/
194+
}
191195
}

‎fe/fe-core/src/test/java/org/apache/doris/nereids/parser/LimitClauseTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void testLimitExceptionCase() {
5454
parsePlan("SELECT b FROM test limit 3 offset 100")
5555
.assertThrowsExactly(ParseException.class)
5656
.assertMessageContains("\n"
57-
+ "OFFSET requires an ORDER BY clause(line 1, pos19)\n"
57+
+ "OFFSET requires an ORDER BY clause(line 1, pos 19)\n"
5858
+ "\n"
5959
+ "== SQL ==\n"
6060
+ "SELECT b FROM test limit 3 offset 100\n"
@@ -63,7 +63,7 @@ public void testLimitExceptionCase() {
6363
parsePlan("SELECT b FROM test limit 100, 3")
6464
.assertThrowsExactly(ParseException.class)
6565
.assertMessageContains("\n"
66-
+ "OFFSET requires an ORDER BY clause(line 1, pos19)\n"
66+
+ "OFFSET requires an ORDER BY clause(line 1, pos 19)\n"
6767
+ "\n"
6868
+ "== SQL ==\n"
6969
+ "SELECT b FROM test limit 100, 3\n"

‎fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public void testSingle() {
6969
public void testErrorListener() {
7070
parsePlan("select * from t1 where a = 1 illegal_symbol")
7171
.assertThrowsExactly(ParseException.class)
72-
.assertMessageEquals("\nextraneous input 'illegal_symbol' expecting {<EOF>, ';'}(line 1, pos29)\n");
72+
.assertMessageEquals("\nextraneous input 'illegal_symbol' expecting {<EOF>, ';'}(line 1, pos 29)\n");
7373
}
7474

7575
@Test

‎regression-test/suites/nereids_syntax_p0/function.groovy

+11
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,16 @@ suite("function") {
5252
order_qt_avg """
5353
SELECT avg(lo_tax), avg(lo_extendedprice) AS avg_extendedprice FROM lineorder;
5454
"""
55+
56+
// nested function
57+
test {
58+
sql "select cast(date('1994-01-01') + interval '1' YEAR as varchar)"
59+
result([["1995-01-01 00:00:00"]])
60+
}
61+
62+
test {
63+
sql "select substring(substring('1994-01-01', 5), 3)"
64+
result([["1-01"]])
65+
}
5566
}
5667

0 commit comments

Comments
 (0)
Please sign in to comment.