Skip to content

Commit 5738026

Browse files
committed
fix comments
1 parent 00bf4ba commit 5738026

3 files changed

Lines changed: 158 additions & 19 deletions

File tree

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

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -219,18 +219,7 @@ public Expression visit(Expression expr, ExpressionRewriteContext context) {
219219
* ******************************************************************************************** */
220220
@Override
221221
public Expression visitUnboundVariable(UnboundVariable unboundVariable, ExpressionRewriteContext context) {
222-
Variable variable = resolveUnboundVariable(unboundVariable);
223-
// Record used variable for SQL cache when context is available.
224-
// Defensive null-check: some callers may invoke analysis without a full
225-
// ExpressionRewriteContext (e.g. in isolated tests), so guard access.
226-
if (context != null && context.cascadesContext != null) {
227-
Optional<SqlCacheContext> sqlCacheContext = context.cascadesContext.getStatementContext()
228-
.getSqlCacheContext();
229-
if (sqlCacheContext.isPresent()) {
230-
sqlCacheContext.get().addUsedVariable(variable);
231-
}
232-
}
233-
return variable.getRealExpression();
222+
return resolveUnboundVariable(unboundVariable);
234223
}
235224

236225
/** resolveUnboundVariable */

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

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.doris.nereids.exceptions.UnboundException;
2222
import org.apache.doris.nereids.trees.TreeNode;
2323
import org.apache.doris.nereids.trees.expressions.Expression;
24+
import org.apache.doris.nereids.trees.expressions.Variable;
2425
import org.apache.doris.nereids.types.DataType;
2526

2627
import com.google.common.collect.ImmutableList;
@@ -46,23 +47,58 @@ default void checkLegalityBeforeTypeCoercion() {}
4647
@Developing
4748
default void checkLegalityAfterRewrite() {}
4849

50+
/**
51+
* getArguments.
52+
*/
4953
default List<Expression> getArguments() {
50-
return children();
54+
ImmutableList.Builder<Expression> arguments = ImmutableList.builder();
55+
for (Expression arg : children()) {
56+
if (arg instanceof Variable && ((Variable) arg).getRealExpression() != null) {
57+
arguments.add(((Variable) arg).getRealExpression());
58+
} else {
59+
arguments.add(arg);
60+
}
61+
}
62+
return arguments.build();
5163
}
5264

65+
/**
66+
* getArgument.
67+
*/
5368
default Expression getArgument(int index) {
54-
return child(index);
69+
Expression arg = child(index);
70+
if (arg instanceof Variable && ((Variable) arg).getRealExpression() != null) {
71+
return ((Variable) arg).getRealExpression();
72+
} else {
73+
return arg;
74+
}
5575
}
5676

77+
/**
78+
* getArgumentsTypes.
79+
*/
5780
default List<DataType> getArgumentsTypes() {
58-
return getArguments()
59-
.stream()
60-
.map(Expression::getDataType)
61-
.collect(ImmutableList.toImmutableList());
81+
ImmutableList.Builder<DataType> dataTypes = ImmutableList.builder();
82+
for (Expression arg : children()) {
83+
if (arg instanceof Variable && ((Variable) arg).getRealExpression() != null) {
84+
dataTypes.add(((Variable) arg).getRealExpression().getDataType());
85+
} else {
86+
dataTypes.add(arg.getDataType());
87+
}
88+
}
89+
return dataTypes.build();
6290
}
6391

92+
/**
93+
* getArgumentType.
94+
*/
6495
default DataType getArgumentType(int index) {
65-
return child(index).getDataType();
96+
Expression arg = child(index);
97+
if (arg instanceof Variable && ((Variable) arg).getRealExpression() != null) {
98+
return ((Variable) arg).getRealExpression().getDataType();
99+
} else {
100+
return arg.getDataType();
101+
}
66102
}
67103

68104
default DataType getDataType() throws UnboundException {
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.doris.nereids.trees.expressions.functions;
19+
20+
import org.apache.doris.nereids.analyzer.UnboundVariable.VariableType;
21+
import org.apache.doris.nereids.trees.expressions.Expression;
22+
import org.apache.doris.nereids.trees.expressions.Variable;
23+
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
24+
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
25+
import org.apache.doris.nereids.types.DataType;
26+
27+
import org.junit.jupiter.api.Assertions;
28+
import org.junit.jupiter.api.Test;
29+
30+
import java.util.List;
31+
32+
/**
33+
* Tests for ExpressionTrait behaviors when children are `Variable`.
34+
*/
35+
public class ExpressionTraitTest {
36+
37+
static class DummyFunction extends Expression {
38+
protected DummyFunction(List<Expression> children) {
39+
super(children);
40+
}
41+
42+
protected DummyFunction(Expression... children) {
43+
super(children);
44+
}
45+
46+
@Override
47+
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
48+
return null;
49+
}
50+
51+
@Override
52+
public Expression withChildren(List<Expression> children) {
53+
return new DummyFunction(children);
54+
}
55+
56+
@Override
57+
protected String computeToSql() {
58+
return "dummy";
59+
}
60+
61+
@Override
62+
public boolean nullable() {
63+
return false;
64+
}
65+
}
66+
67+
@Test
68+
public void testVariableWithRealExpression() {
69+
IntegerLiteral lit = new IntegerLiteral(42);
70+
Variable var = new Variable("v", VariableType.USER, lit);
71+
72+
DummyFunction func = new DummyFunction(var);
73+
74+
List<Expression> args = func.getArguments();
75+
Assertions.assertEquals(1, args.size());
76+
Assertions.assertEquals(lit, args.get(0));
77+
78+
Assertions.assertEquals(lit, func.getArgument(0));
79+
80+
List<DataType> types = func.getArgumentsTypes();
81+
Assertions.assertEquals(1, types.size());
82+
Assertions.assertEquals(lit.getDataType(), types.get(0));
83+
84+
Assertions.assertEquals(lit.getDataType(), func.getArgumentType(0));
85+
}
86+
87+
@Test
88+
public void testVariableWithoutRealExpression() {
89+
IntegerLiteral lit = new IntegerLiteral(100);
90+
// create a Variable but override getRealExpression to simulate a missing real expression
91+
Variable var = new Variable("v", VariableType.USER, lit) {
92+
@Override
93+
public Expression getRealExpression() {
94+
return null;
95+
}
96+
};
97+
98+
DummyFunction func = new DummyFunction(var);
99+
100+
List<Expression> args = func.getArguments();
101+
Assertions.assertEquals(1, args.size());
102+
// when Variable.getRealExpression() returns null, ExpressionTrait should return the Variable itself
103+
Assertions.assertSame(var, args.get(0));
104+
105+
Assertions.assertSame(var, func.getArgument(0));
106+
107+
List<DataType> types = func.getArgumentsTypes();
108+
Assertions.assertEquals(1, types.size());
109+
// fallback to variable.getDataType()
110+
Assertions.assertEquals(var.getDataType(), types.get(0));
111+
112+
Assertions.assertEquals(var.getDataType(), func.getArgumentType(0));
113+
}
114+
}

0 commit comments

Comments
 (0)