This is an automated email from the ASF dual-hosted git repository. michaelsmith pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/impala.git
commit 62bf60994211731d8e1b5b7edba517972e2fbbca Author: Steve Carlin <[email protected]> AuthorDate: Fri Sep 5 13:09:01 2025 -0700 IMPALA-14414: Calcite planner: Added new code to handle nan/inf The current code works for NaN and Inf, but it breaks when upgrading to v1.40. This commit changes the code to handle these when we do the upgrade to 1.40 and adds a basic test into the calcite.test to ensure that when the upgrade happens, it does not break. Change-Id: I8593a4942a2fe785a0c77134b78a9d97257225fc Reviewed-on: http://gerrit.cloudera.org:8080/23561 Reviewed-by: Impala Public Jenkins <[email protected]> Tested-by: Impala Public Jenkins <[email protected]> --- .../calcite/functions/RexLiteralConverter.java | 46 +++++++++++++++++++--- .../queries/QueryTest/calcite.test | 7 ++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexLiteralConverter.java b/java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexLiteralConverter.java index b1a03c2bd..1b768c1ca 100644 --- a/java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexLiteralConverter.java +++ b/java/calcite-planner/src/main/java/org/apache/impala/calcite/functions/RexLiteralConverter.java @@ -35,6 +35,7 @@ import org.apache.impala.catalog.Function; import org.apache.impala.catalog.PrimitiveType; import org.apache.impala.catalog.ScalarType; import org.apache.impala.catalog.Type; +import org.apache.impala.common.AnalysisException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,16 +57,39 @@ public class RexLiteralConverter { return NumericLiteral.create( new BigDecimal(rexLiteral.getValueAs(Long.class)), Type.BIGINT); } - switch (rexLiteral.getTypeName()) { - case NULL: - Type type = ImpalaTypeConverter.createImpalaType(rexLiteral.getType()); - return new AnalyzedNullLiteral(type); + + if (rexLiteral.isNull()) { + Type type = ImpalaTypeConverter.createImpalaType(rexLiteral.getType()); + return new AnalyzedNullLiteral(type); + } + + switch (rexLiteral.getType().getSqlTypeName()) { case BOOLEAN: Expr boolExpr = new BoolLiteral((Boolean) rexLiteral.getValueAs(Boolean.class)); return boolExpr; + case DOUBLE: + Double d = rexLiteral.getValueAs(Double.class); + // NumericLiteral will throw an exception if it is a Nan or Inf, so create + // a cast around it. + if (!NumericLiteral.isImpalaDouble(d)) { + return createCastNanOrInf(d, Type.DOUBLE); + } + return NumericLiteral.create(rexLiteral.getValueAs(BigDecimal.class), + Type.DOUBLE); + case FLOAT: + Float f = rexLiteral.getValueAs(Float.class); + // NumericLiteral will throw an exception if it is a Nan or Inf, so create + // a cast around it. + if (!NumericLiteral.isImpalaDouble(f)) { + return createCastNanOrInf(f, Type.FLOAT); + } + return NumericLiteral.create(rexLiteral.getValueAs(BigDecimal.class), + Type.FLOAT); + case TINYINT: + case SMALLINT: + case INTEGER: case BIGINT: case DECIMAL: - case DOUBLE: Expr numericExpr = NumericLiteral.create(rexLiteral.getValueAs(BigDecimal.class), ImpalaTypeConverter.createImpalaType(rexLiteral.getType())); return numericExpr; @@ -108,4 +132,16 @@ public class RexLiteralConverter { Function castFunc = FunctionResolver.getExactFunction("casttotimestamp", typeNames); return new AnalyzedFunctionCallExpr(castFunc, argList, Type.TIMESTAMP); } + + private static Expr createCastNanOrInf(Object o, Type t) { + List<RelDataType> typeNames = + ImmutableList.of(ImpalaTypeConverter.getRelDataType(Type.STRING)); + String nanOrInf = o.toString(); + List<Expr> argList = + Lists.newArrayList(new StringLiteral(nanOrInf, Type.STRING, false)); + Preconditions.checkState(t.equals(Type.DOUBLE) || t.equals(Type.FLOAT)); + String fnName = t.equals(Type.DOUBLE) ? "casttodouble" : "casttofloat"; + Function castFunc = FunctionResolver.getExactFunction(fnName, typeNames); + return new AnalyzedFunctionCallExpr(castFunc, argList, t); + } } diff --git a/testdata/workloads/functional-query/queries/QueryTest/calcite.test b/testdata/workloads/functional-query/queries/QueryTest/calcite.test index a514be751..db57ca70c 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/calcite.test +++ b/testdata/workloads/functional-query/queries/QueryTest/calcite.test @@ -1121,3 +1121,10 @@ int ---- RUNTIME_PROFILE row_regex: .*PlannerType: CalcitePlanner.* ==== +---- QUERY +select cast('nan' as double), cast('inf' as float); +---- RESULTS +NaN,Inf +---- TYPES +DOUBLE, FLOAT +====
