Skip to content

Commit 4c00cbf

Browse files
scarlin-clouderajoemcdonnell
authored andcommitted
IMPALA-13136: Refactor AnalyzedFunctionCallExpr (for Calcite)
The analyze method is now called after the Expr is constructed. This code is more in line with the existing way that Impala constructs the Expr object. Change-Id: Ideb662d9c7536659cb558bf62baec29c82217aa2 Reviewed-on: http://gerrit.cloudera.org:8080/21525 Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com> Reviewed-by: Joe McDonnell <joemcdonnell@cloudera.com>
1 parent 1ecc43f commit 4c00cbf

File tree

5 files changed

+38
-74
lines changed

5 files changed

+38
-74
lines changed

java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/AnalyzedFunctionCallExpr.java

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,12 @@
3131
import java.util.List;
3232

3333
/**
34-
* A FunctionCallExpr that is always in an analyzed state
34+
* A FunctionCallExpr specialized for Calcite.
3535
*
36-
* The analysis for Calcite expressions can be done in the constructor
37-
* rather than issuing a separate call to "analyze" after the object
38-
* is constructed.
39-
*
40-
* For this class, we also want to override the "analyzeImpl" call since
41-
* the "fn_" member is passed in rather than deduced at analysis time.
36+
* The analysis for Calcite expressions is done through Calcite and
37+
* does not need the analysis provided through the Impala expression.
38+
* The analyzeImpl is overridden for FunctionCallExpr and only does
39+
* the minimal analysis needed.
4240
*
4341
*/
4442
public class AnalyzedFunctionCallExpr extends FunctionCallExpr {
@@ -49,40 +47,27 @@ public class AnalyzedFunctionCallExpr extends FunctionCallExpr {
4947
// variable so it can be properly set in analyzeImpl()
5048
private final Function savedFunction_;
5149

52-
private final Analyzer analyzer_;
53-
5450
// c'tor that takes a list of Exprs that eventually get converted to FunctionParams
5551
public AnalyzedFunctionCallExpr(Function fn, List<Expr> params,
56-
RexCall rexCall, Type retType, Analyzer analyzer) throws ImpalaException {
52+
RexCall rexCall, Type retType) {
5753
super(fn.getFunctionName(), params);
5854
this.savedFunction_ = fn;
5955
this.type_ = retType;
60-
this.analyze(analyzer);
61-
this.analyzer_ = analyzer;
6256
}
6357

6458
// c'tor which does not depend on Calcite's RexCall but is used when Impala's
6559
// FunctionParams are created or there is some modifications to it
6660
public AnalyzedFunctionCallExpr(Function fn, FunctionParams funcParams,
67-
Type retType, Analyzer analyzer) throws ImpalaException {
61+
Type retType) {
6862
super(fn.getFunctionName(), funcParams);
6963
this.savedFunction_ = fn;
7064
this.type_ = retType;
71-
this.analyze(analyzer);
72-
this.analyzer_ = analyzer;
7365
}
7466

7567
public AnalyzedFunctionCallExpr(AnalyzedFunctionCallExpr other) {
7668
super(other);
7769
this.savedFunction_ = other.savedFunction_;
7870
this.type_ = other.type_;
79-
this.analyzer_ = other.analyzer_;
80-
try {
81-
this.analyze(this.analyzer_);
82-
} catch (ImpalaException e) {
83-
//TODO: IMPALA-13097: Don't throw runtime exception
84-
throw new RuntimeException(e);
85-
}
8671
}
8772

8873
@Override
@@ -106,12 +91,8 @@ protected float computeEvalCost() {
10691

10792
@Override
10893
public FunctionCallExpr cloneWithNewParams(FunctionParams params) {
109-
try {
110-
return new AnalyzedFunctionCallExpr(this.getFn(), params,
111-
this.type_, analyzer_);
112-
} catch (ImpalaException e) {
113-
throw new IllegalStateException(e);
114-
}
94+
return new AnalyzedFunctionCallExpr(this.getFn(), params,
95+
this.type_);
11596
}
11697

11798
}

java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/AnalyzedNullLiteral.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,21 @@
2525
import org.apache.impala.common.ImpalaException;
2626

2727
/**
28-
* A NulLLiteral that is always in analyzed state
28+
* A NulLLiteral specialized for Calcite
29+
*
30+
* The analysisImpl is overriden for Calcite so that the NullLiteral
31+
* can be cast to the type that was determined by Calcite.
2932
*/
3033
public class AnalyzedNullLiteral extends NullLiteral {
31-
private final Analyzer analyzer_;
3234

3335
private final Type savedType_;
3436

35-
public AnalyzedNullLiteral(Analyzer analyzer, Type type) throws ImpalaException {
36-
this.analyzer_ = analyzer;
37+
public AnalyzedNullLiteral(Type type) {
3738
savedType_ = type;
38-
this.analyze(analyzer);
3939
}
4040

4141
public AnalyzedNullLiteral(AnalyzedNullLiteral other) {
4242
super(other);
43-
this.analyzer_ = other.analyzer_;
4443
this.savedType_ = other.savedType_;
4544
}
4645

java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexCallConverter.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717

1818
package org.apache.impala.calcite.functions;
1919

20+
import com.google.common.base.Preconditions;
2021
import com.google.common.collect.Lists;
2122
import org.apache.calcite.rel.type.RelDataType;
2223
import org.apache.calcite.rex.RexBuilder;
2324
import org.apache.calcite.rex.RexCall;
2425
import org.apache.calcite.rex.RexNode;
25-
import org.apache.impala.analysis.Analyzer;
2626
import org.apache.impala.analysis.Expr;
2727
import org.apache.impala.calcite.type.ImpalaTypeConverter;
2828
import org.apache.impala.catalog.Function;
@@ -32,6 +32,7 @@
3232
import org.slf4j.Logger;
3333
import org.slf4j.LoggerFactory;
3434

35+
3536
import java.util.List;
3637

3738
/**
@@ -44,8 +45,7 @@ public class RexCallConverter {
4445
/*
4546
* Returns the Impala Expr object for RexCallConverter.
4647
*/
47-
public static Expr getExpr(RexCall rexCall, List<Expr> params,
48-
RexBuilder rexBuilder, Analyzer analyzer) throws ImpalaException {
48+
public static Expr getExpr(RexCall rexCall, List<Expr> params, RexBuilder rexBuilder) {
4949

5050
String funcName = rexCall.getOperator().getName().toLowerCase();
5151

@@ -54,17 +54,15 @@ public static Expr getExpr(RexCall rexCall, List<Expr> params,
5454
Type impalaRetType = ImpalaTypeConverter.createImpalaType(fn.getReturnType(),
5555
rexCall.getType().getPrecision(), rexCall.getType().getScale());
5656

57-
return new AnalyzedFunctionCallExpr(fn, params, rexCall, impalaRetType, analyzer);
57+
return new AnalyzedFunctionCallExpr(fn, params, rexCall, impalaRetType);
5858
}
5959

60-
private static Function getFunction(RexCall call) throws ImpalaException {
60+
private static Function getFunction(RexCall call) {
6161
List<RelDataType> argTypes = Lists.transform(call.getOperands(), RexNode::getType);
6262
String name = call.getOperator().getName();
6363
Function fn = FunctionResolver.getFunction(name, call.getKind(), argTypes);
64-
if (fn == null) {
65-
throw new AnalysisException("Could not find function \"" + name + "\" in Impala "
64+
Preconditions.checkNotNull(fn, "Could not find function \"" + name + "\" in Impala "
6665
+ "with args " + argTypes + " and return type " + call.getType());
67-
}
6866
return fn;
6967
}
7068
}

java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexLiteralConverter.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.apache.calcite.sql.type.SqlTypeName;
2525
import org.apache.calcite.util.DateString;
2626
import org.apache.calcite.util.TimestampString;
27-
import org.apache.impala.analysis.Analyzer;
2827
import org.apache.impala.analysis.Expr;
2928
import org.apache.impala.analysis.BoolLiteral;
3029
import org.apache.impala.analysis.DateLiteral;
@@ -55,26 +54,23 @@ public class RexLiteralConverter {
5554
/*
5655
* Returns Expr object for ImpalaRexLiteral
5756
*/
58-
public static Expr getExpr(RexLiteral rexLiteral, Analyzer analyzer)
59-
throws ImpalaException {
57+
public static Expr getExpr(RexLiteral rexLiteral) {
6058
if (SqlTypeName.INTERVAL_TYPES.contains(rexLiteral.getTypeName())) {
61-
return new NumericLiteral(
59+
return NumericLiteral.create(
6260
new BigDecimal(rexLiteral.getValueAs(Long.class)), Type.BIGINT);
6361
}
6462
switch (rexLiteral.getTypeName()) {
6563
case NULL:
6664
Type type = ImpalaTypeConverter.createImpalaType(rexLiteral.getType());
67-
return new AnalyzedNullLiteral(null, type);
65+
return new AnalyzedNullLiteral(type);
6866
case BOOLEAN:
69-
Expr boolExpr = new BoolLiteral(rexLiteral.getValueAs(Boolean.class));
70-
boolExpr.analyze(null);
67+
Expr boolExpr = new BoolLiteral((Boolean) rexLiteral.getValueAs(Boolean.class));
7168
return boolExpr;
7269
case BIGINT:
7370
case DECIMAL:
7471
case DOUBLE:
75-
Expr numericExpr = new NumericLiteral(rexLiteral.getValueAs(BigDecimal.class),
72+
Expr numericExpr = NumericLiteral.create(rexLiteral.getValueAs(BigDecimal.class),
7673
ImpalaTypeConverter.createImpalaType(rexLiteral.getType()));
77-
numericExpr.analyze(null);
7874
return numericExpr;
7975
case CHAR:
8076
case VARCHAR:
@@ -87,19 +83,18 @@ public static Expr getExpr(RexLiteral rexLiteral, Analyzer analyzer)
8783
}
8884
Expr charExpr = new StringLiteral(rexLiteral.getValueAs(String.class),
8985
charType, false);
90-
charExpr.analyze(null);
9186
return charExpr;
9287
case DATE:
9388
DateString dateStringClass = rexLiteral.getValueAs(DateString.class);
9489
String dateString = (dateStringClass == null) ? null : dateStringClass.toString();
9590
Expr dateExpr = new DateLiteral(rexLiteral.getValueAs(Integer.class), dateString);
96-
dateExpr.analyze(null);
9791
return dateExpr;
9892
case TIMESTAMP:
99-
return createCastTimestampExpr(rexLiteral, analyzer);
93+
return createCastTimestampExpr(rexLiteral);
10094
default:
101-
throw new AnalysisException("Unsupported RexLiteral: "
95+
Preconditions.checkState(false, "Unsupported RexLiteral: "
10296
+ rexLiteral.getTypeName());
97+
return null;
10398
}
10499
}
105100

@@ -110,17 +105,14 @@ public static Expr getExpr(RexLiteral rexLiteral, Analyzer analyzer)
110105
* If constant folding was not allowed, it means we did not have access to the backend
111106
* and thus need to do a cast in order to support conversion to a Timestamp.
112107
*/
113-
private static Expr createCastTimestampExpr(RexLiteral rexLiteral,
114-
Analyzer analyzer)
115-
throws ImpalaException {
108+
private static Expr createCastTimestampExpr(RexLiteral rexLiteral) {
116109
List<RelDataType> typeNames =
117110
ImmutableList.of(ImpalaTypeConverter.getRelDataType(Type.STRING));
118111

119112
String timestamp = rexLiteral.getValueAs(TimestampString.class).toString();
120113
List<Expr> argList =
121114
Lists.newArrayList(new StringLiteral(timestamp, Type.STRING, false));
122115
Function castFunc = FunctionResolver.getFunction("casttotimestamp", typeNames);
123-
return new AnalyzedFunctionCallExpr(castFunc, argList, null, Type.TIMESTAMP,
124-
analyzer);
116+
return new AnalyzedFunctionCallExpr(castFunc, argList, null, Type.TIMESTAMP);
125117
}
126118
}

java/calcite-planner/src/main/java/org/apache/impala/calcite/rel/util/CreateExprVisitor.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,16 @@ public Expr visitInputRef(RexInputRef rexInputRef) {
7070

7171
@Override
7272
public Expr visitCall(RexCall rexCall) {
73-
try {
74-
List<Expr> params = Lists.newArrayList();
75-
for (RexNode operand : rexCall.getOperands()) {
76-
params.add(operand.accept(this));
77-
}
78-
return RexCallConverter.getExpr(rexCall, params, rexBuilder_, analyzer_);
79-
} catch (ImpalaException e) {
80-
throw new RuntimeException(e);
73+
List<Expr> params = Lists.newArrayList();
74+
for (RexNode operand : rexCall.getOperands()) {
75+
params.add(operand.accept(this));
8176
}
77+
return RexCallConverter.getExpr(rexCall, params, rexBuilder_);
8278
}
8379

8480
@Override
8581
public Expr visitLiteral(RexLiteral rexLiteral) {
86-
try {
87-
return RexLiteralConverter.getExpr(rexLiteral, analyzer_);
88-
} catch (ImpalaException e) {
89-
throw new RuntimeException(e);
90-
}
82+
return RexLiteralConverter.getExpr(rexLiteral);
9183
}
9284

9385
@Override
@@ -142,7 +134,9 @@ public Expr visitPatternFieldRef(RexPatternFieldRef fieldRef) {
142134
public static Expr getExpr(CreateExprVisitor visitor, RexNode operand)
143135
throws ImpalaException {
144136
try {
145-
return operand.accept(visitor);
137+
Expr expr = operand.accept(visitor);
138+
expr.analyze(visitor.analyzer_);
139+
return expr;
146140
} catch (Exception e) {
147141
throw new AnalysisException(e);
148142
}

0 commit comments

Comments
 (0)