Better error message for unsupported double values (#11409)

A constant expression may evaluate to Double.NEGATIVE_INFINITY/Double.POSITIVE_INFINITY/Double.NAN e.g. log10(0). When using such an expression in native queries, the user will get the corresponding value without any error. In SQL, however, the user will run into NumberFormatException because we convert the double to big-decimal while constructing a literal numeric expression. This probably should be fixed in calcite - see https://issues.apache.org/jira/browse/CALCITE-2067. This PR adds a verbose error message so that users can take corrective action without scratching their heads.
This commit is contained in:
Abhishek Agarwal 2021-07-08 16:55:17 +05:30 committed by GitHub
parent d5e8d4d680
commit 3481bb0440
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 0 deletions

View File

@ -126,6 +126,15 @@ public class DruidRexExecutor implements RexExecutor
// if exprResult evaluates to Nan or infinity, this will throw a NumberFormatException.
// If you find yourself in such a position, consider casting the literal to a BIGINT so that
// the query can execute.
double exprResultDouble = exprResult.asDouble();
if (Double.isNaN(exprResultDouble) || Double.isInfinite(exprResultDouble)) {
String expression = druidExpression.getExpression();
throw new IAE("'%s' evaluates to '%s' that is not supported in SQL. You can either cast the expression as bigint ('cast(%s as bigint)') or char ('cast(%s as char)') or change the expression itself",
expression,
Double.toString(exprResultDouble),
expression,
expression);
}
bigDecimal = BigDecimal.valueOf(exprResult.asDouble());
}
literal = rexBuilder.makeLiteral(bigDecimal, constExp.getType(), true);

View File

@ -283,6 +283,28 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
);
}
@Test
public void testSelectConstantExpressionEquivalentToNaN() throws Exception
{
expectedException.expectMessage("'(log10(0) - log10(0))' evaluates to 'NaN' that is not supported in SQL. You can either cast the expression as bigint ('cast((log10(0) - log10(0)) as bigint)') or char ('cast((log10(0) - log10(0)) as char)') or change the expression itself");
testQuery(
"SELECT log10(0) - log10(0), dim1 FROM foo LIMIT 1",
ImmutableList.of(),
ImmutableList.of()
);
}
@Test
public void testSelectConstantExpressionEquivalentToInfinity() throws Exception
{
expectedException.expectMessage("'log10(0)' evaluates to '-Infinity' that is not supported in SQL. You can either cast the expression as bigint ('cast(log10(0) as bigint)') or char ('cast(log10(0) as char)') or change the expression itself");
testQuery(
"SELECT log10(0), dim1 FROM foo LIMIT 1",
ImmutableList.of(),
ImmutableList.of()
);
}
@Test
public void testGroupByWithPostAggregatorReferencingTimeFloorColumnOnTimeseries() throws Exception
{