diff --git a/babel/src/test/resources/sql/big-query.iq b/babel/src/test/resources/sql/big-query.iq
index 5ffa0bdf66d1..a158bd16eed0 100755
--- a/babel/src/test/resources/sql/big-query.iq
+++ b/babel/src/test/resources/sql/big-query.iq
@@ -660,6 +660,7 @@ SELECT SAFE_ADD(CAST(1.7e308 as DOUBLE), CAST(1.7e308 as DOUBLE)) as double_over
!ok
+!if (fixed.calcite6328) {
SELECT SAFE_ADD(9, cast(9.999999999999999999e75 as DECIMAL(38, 19))) as decimal_overflow;
+------------------+
| decimal_overflow |
@@ -669,6 +670,7 @@ SELECT SAFE_ADD(9, cast(9.999999999999999999e75 as DECIMAL(38, 19))) as decimal_
(1 row)
!ok
+!}
# NaN arguments should return NaN
SELECT SAFE_ADD(CAST('NaN' AS DOUBLE), CAST(3 as BIGINT)) as NaN_result;
@@ -720,6 +722,7 @@ SELECT SAFE_DIVIDE(CAST(1.7e308 as DOUBLE),
!ok
+!if (fixed.calcite6328) {
SELECT SAFE_DIVIDE(CAST(-3.5e75 AS DECIMAL(76, 0)),
CAST(3.5e-75 AS DECIMAL(76, 0))) as decimal_overflow;
+------------------+
@@ -730,6 +733,7 @@ SELECT SAFE_DIVIDE(CAST(-3.5e75 AS DECIMAL(76, 0)),
(1 row)
!ok
+!}
# NaN arguments should return NaN
SELECT SAFE_DIVIDE(CAST('NaN' AS DOUBLE), CAST(3 as BIGINT)) as NaN_result;
@@ -801,6 +805,7 @@ SELECT SAFE_MULTIPLY(CAST(1.7e308 as DOUBLE), CAST(3 as BIGINT)) as double_overf
!ok
+!if (fixed.calcite6328) {
SELECT SAFE_MULTIPLY(CAST(-3.5e75 AS DECIMAL(76, 0)), CAST(10 AS BIGINT)) as decimal_overflow;
+------------------+
| decimal_overflow |
@@ -810,6 +815,7 @@ SELECT SAFE_MULTIPLY(CAST(-3.5e75 AS DECIMAL(76, 0)), CAST(10 AS BIGINT)) as dec
(1 row)
!ok
+!}
# NaN arguments should return NaN
SELECT SAFE_MULTIPLY(CAST('NaN' AS DOUBLE), CAST(3 as BIGINT)) as NaN_result;
@@ -916,6 +922,7 @@ SELECT SAFE_SUBTRACT(CAST(1.7e308 as DOUBLE), CAST(-1.7e308 as DOUBLE)) as doubl
!ok
+!if (fixed.calcite6328) {
SELECT SAFE_SUBTRACT(9, cast(-9.999999999999999999e75 as DECIMAL(38, 19))) as decimal_overflow;
+------------------+
| decimal_overflow |
@@ -925,6 +932,7 @@ SELECT SAFE_SUBTRACT(9, cast(-9.999999999999999999e75 as DECIMAL(38, 19))) as de
(1 row)
!ok
+!}
# NaN arguments should return NaN
SELECT SAFE_SUBTRACT(CAST('NaN' AS DOUBLE), CAST(3 as BIGINT)) as NaN_result;
diff --git a/babel/src/test/resources/sql/redshift.iq b/babel/src/test/resources/sql/redshift.iq
index e0ef58abd133..517a87c22408 100755
--- a/babel/src/test/resources/sql/redshift.iq
+++ b/babel/src/test/resources/sql/redshift.iq
@@ -184,7 +184,7 @@ select approximate percentile_disc(0.5) within group (order by sal) from emp gro
# AVG
select avg(sal) from emp;
EXPR$0
-2073.214285714286
+2073.21
!ok
# COUNT
@@ -288,12 +288,12 @@ select percentile_disc(0.6) within group (order by sal) from emp group by deptno
# STDDEV_SAMP and STDDEV_POP
select stddev_samp(sal) from emp;
EXPR$0
-1182.503223516271873450023122131824493408203125
+1182.50
!ok
select stddev_pop(sal) from emp;
EXPR$0
-1139.488618295281639802851714193820953369140625
+1139.48
!ok
# SUM
@@ -308,24 +308,24 @@ EXPR$0
!ok
# VAR_SAMP and VAR_POP
-select var_samp(sal) from emp;
+select var_samp(CAST(sal AS DECIMAL(12, 4))) from emp;
EXPR$0
-1398313.873626374
+1398313.8736
!ok
-select var_samp(distinct sal) from emp;
+select var_samp(distinct CAST(sal AS DECIMAL(12, 4))) from emp;
EXPR$0
-1512779.356060606
+1512779.3560
!ok
-select var_samp(all sal) from emp;
+select var_samp(all CAST(sal AS DECIMAL(12, 4))) from emp;
EXPR$0
-1398313.873626374
+1398313.8736
!ok
-select var_pop(sal) from emp;
+select var_pop(CAST(sal AS DECIMAL(12, 4))) from emp;
EXPR$0
-1298434.31122449
+1298434.3112
!ok
# 4 Bit-Wise Aggregate Functions
@@ -378,10 +378,10 @@ select empno, avg(sal) over (order by empno rows unbounded preceding) from emp w
EMPNO, EXPR$1
7499, 1600.00
7521, 1425.00
-7654, 1366.666666666667
+7654, 1366.66
7698, 1737.50
7844, 1690.00
-7900, 1566.666666666667
+7900, 1566.66
!ok
# COUNT
@@ -523,78 +523,78 @@ select deptno, ratio_to_report(sal) over (partition by deptno) from emp;
!}
# STDDEV_POP
-select empno, stddev_pop(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, stddev_pop(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
-7499, 0
-7521, 100
-7654, 478.42333648024424519462627358734607696533203125
-7698, 478.42333648024424519462627358734607696533203125
-7844, 522.0153254455275373402400873601436614990234375
-7900, 522.0153254455275373402400873601436614990234375
+7499, 0.0000
+7521, 100.0000
+7654, 478.4233
+7698, 478.4233
+7844, 522.0153
+7900, 522.0153
!ok
# STDDEV_SAMP (synonym for STDDEV)
-select empno, stddev_samp(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, stddev_samp(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
7499, null
-7521, 141.421356237309510106570087373256683349609375
-7654, 585.9465277082316561063635163009166717529296875
-7698, 585.9465277082316561063635163009166717529296875
-7844, 602.7713773341707792496890760958194732666015625
-7900, 602.7713773341707792496890760958194732666015625
+7521, 141.4213
+7654, 585.9465
+7698, 585.9465
+7844, 602.7713
+7900, 602.7713
!ok
-select empno, stddev(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, stddev(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
7499, null
-7521, 141.421356237309510106570087373256683349609375
-7654, 585.9465277082316561063635163009166717529296875
-7698, 585.9465277082316561063635163009166717529296875
-7844, 602.7713773341707792496890760958194732666015625
-7900, 602.7713773341707792496890760958194732666015625
+7521, 141.4213
+7654, 585.9465
+7698, 585.9465
+7844, 602.7713
+7900, 602.7713
!ok
# SUM
-select empno, sum(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, sum(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
-7499, 300.00
-7521, 800.00
-7654, 2200.00
-7698, 2200.00
-7844, 2200.00
-7900, 2200.00
+7499, 300.0000
+7521, 800.0000
+7654, 2200.0000
+7698, 2200.0000
+7844, 2200.0000
+7900, 2200.0000
!ok
# VAR_POP
-select empno, var_pop(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, var_pop(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
7499, 0.0000
7521, 10000.0000
-7654, 228888.888888889
-7698, 228888.888888889
+7654, 228888.8889
+7698, 228888.8889
7844, 272500.0000
7900, 272500.0000
!ok
# VAR_SAMP (synonym for VARIANCE)
-select empno, var_samp(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, var_samp(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
7499, null
7521, 20000.0000
-7654, 343333.3333333335
-7698, 343333.3333333335
-7844, 363333.3333333333
-7900, 363333.3333333333
+7654, 343333.3333
+7698, 343333.3333
+7844, 363333.3333
+7900, 363333.3333
!ok
-select empno, variance(comm) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
+select empno, variance(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) from emp where deptno = 30 order by 1;
EMPNO, EXPR$1
7499, null
7521, 20000.0000
-7654, 343333.3333333335
-7698, 343333.3333333335
-7844, 363333.3333333333
-7900, 363333.3333333333
+7654, 343333.3333
+7698, 343333.3333
+7844, 363333.3333
+7900, 363333.3333
!ok
# 5.2 Ranking functions
@@ -2013,7 +2013,7 @@ SELECT "JSON_EXTRACT_PATH_TEXT"('{"f2":{"f3":1},"f4":{"f5":99,"f6":"star"}}', 'f
# CAST and CONVERT
select cast(stddev_samp(sal) as dec(14, 2)) from emp;
EXPR$0
-1182.503223516271873450023122131824493408203125
+1182.50
!ok
select 123.456::decimal(8,4);
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
index e49788c5945a..fcdf6ba3705b 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java
@@ -442,6 +442,36 @@ private Expression getConvertExpression(
return defaultExpression.get();
}
+ case DECIMAL: {
+ int precision = targetType.getPrecision();
+ int scale = targetType.getScale();
+ if (precision != RelDataType.PRECISION_NOT_SPECIFIED
+ && scale != RelDataType.SCALE_NOT_SPECIFIED) {
+ if (sourceType.getSqlTypeName() == SqlTypeName.DECIMAL) {
+ // Cast from DECIMAL to DECIMAL, may adjust scale and precision.
+ return Expressions.call(
+ BuiltInMethod.DECIMAL_DECIMAL_CAST.method,
+ operand,
+ Expressions.constant(precision),
+ Expressions.constant(scale));
+ } else if (SqlTypeName.INT_TYPES.contains(sourceType.getSqlTypeName())) {
+ // Cast from INTEGER to DECIMAL, check for overflow
+ return Expressions.call(
+ BuiltInMethod.INTEGER_DECIMAL_CAST.method,
+ operand,
+ Expressions.constant(precision),
+ Expressions.constant(scale));
+ } else if (SqlTypeName.APPROX_TYPES.contains(sourceType.getSqlTypeName())) {
+ // Cast from FLOAT/DOUBLE to DECIMAL
+ return Expressions.call(
+ BuiltInMethod.FP_DECIMAL_CAST.method,
+ operand,
+ Expressions.constant(precision),
+ Expressions.constant(scale));
+ }
+ }
+ return defaultExpression.get();
+ }
case BIGINT:
case INTEGER:
case TINYINT:
diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
index 8149b22dad5d..04b00774facf 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java
@@ -1836,7 +1836,7 @@ public static boolean isValidDecimalValue(@Nullable BigDecimal value, RelDataTyp
case DECIMAL:
final int intDigits = value.precision() - value.scale();
final int maxIntDigits = toType.getPrecision() - toType.getScale();
- return intDigits <= maxIntDigits;
+ return (intDigits <= maxIntDigits) && (value.scale() <= toType.getScale());
default:
return true;
}
diff --git a/core/src/main/java/org/apache/calcite/util/Bug.java b/core/src/main/java/org/apache/calcite/util/Bug.java
index e0eaa97a3ec9..32e99038d672 100644
--- a/core/src/main/java/org/apache/calcite/util/Bug.java
+++ b/core/src/main/java/org/apache/calcite/util/Bug.java
@@ -215,6 +215,12 @@ public abstract class Bug {
* Fix failing quidem tests for FORMAT in CAST is fixed. */
public static final boolean CALCITE_6375_FIXED = false;
+ /** Whether
+ * [CALCITE-6328]
+ * The BigQuery functions SAFE_* do not match the BigQuery specification
+ * is fixed. */
+ public static final boolean CALCITE_6328_FIXED = false;
+
/**
* Use this to flag temporary code.
*/
diff --git a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
index 2e72df1be651..903aaf34b590 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -292,6 +292,12 @@ public enum BuiltInMethod {
ENUMERABLE_TO_LIST(ExtendedEnumerable.class, "toList"),
ENUMERABLE_TO_MAP(ExtendedEnumerable.class, "toMap", Function1.class, Function1.class),
AS_LIST(Primitive.class, "asList", Object.class),
+ DECIMAL_DECIMAL_CAST(Primitive.class, "decimalDecimalCast",
+ BigDecimal.class, int.class, int.class),
+ INTEGER_DECIMAL_CAST(Primitive.class, "integerDecimalCast",
+ Object.class, int.class, int.class),
+ FP_DECIMAL_CAST(Primitive.class, "fpDecimalCast",
+ Object.class, int.class, int.class),
INTEGER_CAST(Primitive.class, "integerCast", Primitive.class, Object.class),
MEMORY_GET0(MemoryFactory.Memory.class, "get"),
MEMORY_GET1(MemoryFactory.Memory.class, "get", int.class),
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
index ba7e4f18bf53..89b6854d9d05 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
@@ -3814,7 +3814,8 @@ private SqlSpecialOperatorWithPolicy(String name, SqlKind kind, int prec, boolea
RexNode one = literal(1);
RexNode b = vDecimalNotNull(2);
- RexNode half = literal(new BigDecimal(0.5), b.getType());
+ RelDataType decimal = typeFactory.createSqlType(SqlTypeName.DECIMAL, 2, 1);
+ RexNode half = literal(new BigDecimal("0.5"), decimal);
checkSimplify(add(a, zero), "?0.notNullInt1");
checkSimplify(add(zero, a), "?0.notNullInt1");
diff --git a/core/src/test/java/org/apache/calcite/test/InterpreterTest.java b/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
index a98a19625b7f..d241b2a1168b 100644
--- a/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/InterpreterTest.java
@@ -579,7 +579,7 @@ private static void assertRows(Interpreter interpreter,
final String sql = "select x, min(y), max(y), sum(y), avg(y)\n"
+ "from (values ('a', -1.2), ('a', 2.3), ('a', 15)) as t(x, y)\n"
+ "group by x";
- sql(sql).returnsRows("[a, -1.2, 15.0, 16.1, 5.366666666666667]");
+ sql(sql).returnsRows("[a, -1.2, 15.0, 16.1, 5.3]");
}
@Test void testInterpretUnnest() {
diff --git a/core/src/test/resources/sql/agg.iq b/core/src/test/resources/sql/agg.iq
index 8541f46ba5f4..feeaf9035e66 100644
--- a/core/src/test/resources/sql/agg.iq
+++ b/core/src/test/resources/sql/agg.iq
@@ -1888,11 +1888,11 @@ from "scott".emp;
# Previously threw "java.lang.ArithmeticException: Non-terminating decimal
# expansion; no exact representable decimal result"
select avg(comm) as a, count(comm) as c from "scott".emp where empno < 7844;
-+-------------------+---+
-| A | C |
-+-------------------+---+
-| 733.3333333333333 | 3 |
-+-------------------+---+
++--------+---+
+| A | C |
++--------+---+
+| 733.33 | 3 |
++--------+---+
(1 row)
!ok
@@ -2913,10 +2913,10 @@ EnumerableAggregate(group=[{}], REGR_COUNT(COMM, SAL)=[REGR_COUNT($6, $5)], REGR
# [CALCITE-1776, CALCITE-2402] REGR_SXX, REGR_SXY, REGR_SYY
SELECT
- regr_sxx(COMM, SAL) as "REGR_SXX(COMM, SAL)",
- regr_syy(COMM, SAL) as "REGR_SYY(COMM, SAL)",
- regr_sxx(SAL, COMM) as "REGR_SXX(SAL, COMM)",
- regr_syy(SAL, COMM) as "REGR_SYY(SAL, COMM)"
+ regr_sxx(CAST(COMM AS DECIMAL(12, 4)), CAST(SAL AS DECIMAL(12, 4))) as "REGR_SXX(COMM, SAL)",
+ regr_syy(CAST(COMM AS DECIMAL(12, 4)), CAST(SAL AS DECIMAL(12, 4))) as "REGR_SYY(COMM, SAL)",
+ regr_sxx(CAST(SAL AS DECIMAL(12, 4)), CAST(COMM AS DECIMAL(12, 4))) as "REGR_SXX(SAL, COMM)",
+ regr_syy(CAST(SAL AS DECIMAL(12, 4)), CAST(COMM AS DECIMAL(12, 4))) as "REGR_SYY(SAL, COMM)"
from "scott".emp;
+---------------------+---------------------+---------------------+---------------------+
| REGR_SXX(COMM, SAL) | REGR_SYY(COMM, SAL) | REGR_SXX(SAL, COMM) | REGR_SYY(SAL, COMM) |
@@ -2929,16 +2929,16 @@ from "scott".emp;
# [CALCITE-1776, CALCITE-2402] COVAR_POP, COVAR_SAMP, VAR_SAMP, VAR_POP
SELECT
- covar_pop(COMM, COMM) as "COVAR_POP(COMM, COMM)",
- covar_samp(SAL, SAL) as "COVAR_SAMP(SAL, SAL)",
- var_pop(COMM) as "VAR_POP(COMM)",
- var_samp(SAL) as "VAR_SAMP(SAL)"
+ covar_pop(CAST(COMM AS DECIMAL(12, 4)), CAST(COMM AS DECIMAL(12, 4))) as "COVAR_POP(COMM, COMM)",
+ covar_samp(CAST(SAL AS DECIMAL(12, 4)), CAST(SAL AS DECIMAL(12, 4))) as "COVAR_SAMP(SAL, SAL)",
+ var_pop(CAST(COMM AS DECIMAL(12, 4))) as "VAR_POP(COMM)",
+ var_samp(CAST(SAL AS DECIMAL(12, 4))) as "VAR_SAMP(SAL)"
from "scott".emp;
-+-----------------------+----------------------+---------------+-------------------+
-| COVAR_POP(COMM, COMM) | COVAR_SAMP(SAL, SAL) | VAR_POP(COMM) | VAR_SAMP(SAL) |
-+-----------------------+----------------------+---------------+-------------------+
-| 272500.0000 | 1398313.873626374 | 272500.0000 | 1398313.873626374 |
-+-----------------------+----------------------+---------------+-------------------+
++-----------------------+----------------------+---------------+---------------+
+| COVAR_POP(COMM, COMM) | COVAR_SAMP(SAL, SAL) | VAR_POP(COMM) | VAR_SAMP(SAL) |
++-----------------------+----------------------+---------------+---------------+
+| 272500.0000 | 1398313.8736 | 272500.0000 | 1398313.8736 |
++-----------------------+----------------------+---------------+---------------+
(1 row)
!ok
@@ -2970,23 +2970,23 @@ from "scott".emp group by SAL;
# [CALCITE-1776, CALCITE-2402] COVAR_POP, COVAR_SAMP, VAR_SAMP, VAR_POP with group by
SELECT
MONTH(HIREDATE) as "MONTH",
- covar_samp(SAL, COMM) as "COVAR_SAMP(SAL, COMM)",
- var_pop(COMM) as "VAR_POP(COMM)",
- var_samp(SAL) as "VAR_SAMP(SAL)"
+ covar_samp(CAST(SAL AS DECIMAL(12, 4)), CAST(COMM AS DECIMAL(12, 4))) as "COVAR_SAMP(SAL, COMM)",
+ var_pop(CAST(COMM AS DECIMAL(12, 4))) as "VAR_POP(COMM)",
+ var_samp(CAST(SAL AS DECIMAL(12, 4))) as "VAR_SAMP(SAL)"
from "scott".emp
group by MONTH(HIREDATE);
-+-------+-----------------------+---------------+-------------------+
-| MONTH | COVAR_SAMP(SAL, COMM) | VAR_POP(COMM) | VAR_SAMP(SAL) |
-+-------+-----------------------+---------------+-------------------+
-| 1 | | | 1201250.0000 |
-| 11 | | | |
-| 12 | | | 1510833.333333334 |
-| 2 | -35000.0000 | 10000.0000 | 831458.333333335 |
-| 4 | | | |
-| 5 | | | |
-| 6 | | | |
-| 9 | -175000.0000 | 490000.0000 | 31250.0000 |
-+-------+-----------------------+---------------+-------------------+
++-------+-----------------------+---------------+---------------+
+| MONTH | COVAR_SAMP(SAL, COMM) | VAR_POP(COMM) | VAR_SAMP(SAL) |
++-------+-----------------------+---------------+---------------+
+| 1 | | | 1201250.0000 |
+| 11 | | | |
+| 12 | | | 1510833.3333 |
+| 2 | -35000.0000 | 10000.0000 | 831458.3333 |
+| 4 | | | |
+| 5 | | | |
+| 6 | | | |
+| 9 | -175000.0000 | 490000.0000 | 31250.0000 |
++-------+-----------------------+---------------+---------------+
(8 rows)
!ok
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index fd60c24693a5..3ef2cc8e2a30 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -2422,13 +2422,13 @@ FROM (VALUES (0, 2, 4, 8),
(1, 2, 4, 8),
(CAST(null as int), CAST(null as int), CAST(null as int), CAST(null as int))) AS T(A,B,C,D);
V
-13.0
-9.5
-1.75
-1.875
+13.00000000
+9.50000000
+1.75000000
+1.87500000
null
-0
-14
+0E-8
+14.00000000
!ok
# TIMESTAMP literals without a time part are OK.
diff --git a/core/src/test/resources/sql/winagg.iq b/core/src/test/resources/sql/winagg.iq
index ed02f556f40c..a2a66effa757 100644
--- a/core/src/test/resources/sql/winagg.iq
+++ b/core/src/test/resources/sql/winagg.iq
@@ -80,41 +80,41 @@ from emp;
# STDDEV applied to nullable column
select empno,
- stddev(comm) over (order by empno rows unbounded preceding) as stdev
+ stddev(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows unbounded preceding) as stdev
from emp
where deptno = 30
order by 1;
-+-------+-------------------------------------------------+
-| EMPNO | STDEV |
-+-------+-------------------------------------------------+
-| 7499 | |
-| 7521 | 141.421356237309510106570087373256683349609375 |
-| 7654 | 585.9465277082316561063635163009166717529296875 |
-| 7698 | 585.9465277082316561063635163009166717529296875 |
-| 7844 | 602.7713773341707792496890760958194732666015625 |
-| 7900 | 602.7713773341707792496890760958194732666015625 |
-+-------+-------------------------------------------------+
++-------+----------+
+| EMPNO | STDEV |
++-------+----------+
+| 7499 | |
+| 7521 | 141.4213 |
+| 7654 | 585.9465 |
+| 7698 | 585.9465 |
+| 7844 | 602.7713 |
+| 7900 | 602.7713 |
++-------+----------+
(6 rows)
!ok
# [CALCITE-5931] Allow integers like 1.00 in window frame
select empno,
- stddev(comm) over (order by empno rows 2 preceding) as stdev_2int,
- stddev(comm) over (order by empno rows 2.00 preceding) as stdev_2double
+ stddev(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows 2 preceding) as stdev_2int,
+ stddev(CAST(comm AS DECIMAL(12, 4))) over (order by empno rows 2.00 preceding) as stdev_2double
from emp
where deptno = 30
order by 1;
-+-------+-------------------------------------------------+-------------------------------------------------+
-| EMPNO | STDEV_2INT | STDEV_2DOUBLE |
-+-------+-------------------------------------------------+-------------------------------------------------+
-| 7499 | | |
-| 7521 | 141.421356237309510106570087373256683349609375 | 141.421356237309510106570087373256683349609375 |
-| 7654 | 585.9465277082316561063635163009166717529296875 | 585.9465277082316561063635163009166717529296875 |
-| 7698 | 636.3961030678927954795653931796550750732421875 | 636.3961030678927954795653931796550750732421875 |
-| 7844 | 989.949493661166570745990611612796783447265625 | 989.949493661166570745990611612796783447265625 |
-| 7900 | | |
-+-------+-------------------------------------------------+-------------------------------------------------+
++-------+------------+---------------+
+| EMPNO | STDEV_2INT | STDEV_2DOUBLE |
++-------+------------+---------------+
+| 7499 | | |
+| 7521 | 141.4213 | 141.4213 |
+| 7654 | 585.9465 | 585.9465 |
+| 7698 | 636.3961 | 636.3961 |
+| 7844 | 989.9494 | 989.9494 |
+| 7900 | | |
++-------+------------+---------------+
(6 rows)
!ok
diff --git a/core/src/test/resources/sql/within-distinct.iq b/core/src/test/resources/sql/within-distinct.iq
index ea8c5ec554f1..a8109004450a 100644
--- a/core/src/test/resources/sql/within-distinct.iq
+++ b/core/src/test/resources/sql/within-distinct.iq
@@ -304,18 +304,18 @@ ORDER BY 1, 2;
!}
SELECT deptno,
- avg(sal) AS avg_sal,
- avg(sal) WITHIN DISTINCT (job) AS avg_job_sal
+ avg(CAST(sal AS DECIMAL(10, 2))) AS avg_sal,
+ avg(CAST(sal AS DECIMAL(10, 2))) WITHIN DISTINCT (job) AS avg_job_sal
from emp3
group by deptno
order by deptno;
-+--------+---------+-------------------+
-| DEPTNO | AVG_SAL | AVG_JOB_SAL |
-+--------+---------+-------------------+
-| 10 | 2750.00 | 2750.00 |
-| 20 | 2010.00 | 2083.333333333333 |
-| 30 | 1375.00 | 1500.00 |
-+--------+---------+-------------------+
++--------+---------+-------------+
+| DEPTNO | AVG_SAL | AVG_JOB_SAL |
++--------+---------+-------------+
+| 10 | 2750.00 | 2750.00 |
+| 20 | 2010.00 | 2083.33 |
+| 30 | 1375.00 | 1500.00 |
++--------+---------+-------------+
(3 rows)
!ok
@@ -344,17 +344,18 @@ select * from job_salary order by job;
# Query on the normalized (emp, job_salary) tables give same result as the query on the
# denormalized emp table. Of course.
-select e.deptno, avg(j.sal) as avg_sal, avg(j.sal) within distinct (j.job) as avg_job_sal
+select e.deptno, avg(CAST(j.sal AS DECIMAL(10, 2))) as avg_sal,
+ avg(CAST(j.sal AS DECIMAL(10, 2))) within distinct (j.job) as avg_job_sal
from emp as e join job_salary as j on e.job = j.job
group by deptno
order by deptno;
-+--------+---------+-------------------+
-| DEPTNO | AVG_SAL | AVG_JOB_SAL |
-+--------+---------+-------------------+
-| 10 | 2750.00 | 2750.00 |
-| 20 | 2010.00 | 2083.333333333333 |
-| 30 | 1375.00 | 1500.00 |
-+--------+---------+-------------------+
++--------+---------+-------------+
+| DEPTNO | AVG_SAL | AVG_JOB_SAL |
++--------+---------+-------------+
+| 10 | 2750.00 | 2750.00 |
+| 20 | 2010.00 | 2083.33 |
+| 30 | 1375.00 | 1500.00 |
++--------+---------+-------------+
(3 rows)
!ok
@@ -558,8 +559,8 @@ order by payment;
+---------+-------+-------------+--------------+-----------+
| PAYMENT | count | order_count | sum_shipping | sum_units |
+---------+-------+-------------+--------------+-----------+
-| cash | 3 | 2 | 32 | 11 |
-| visa | 3 | 1 | 60 | 13 |
+| cash | 3 | 2 | 32.00 | 11 |
+| visa | 3 | 1 | 60.00 | 13 |
+---------+-------+-------------+--------------+-----------+
(2 rows)
@@ -792,8 +793,8 @@ order by o.payment;
+---------+----------------+-------------+------------------+---------+--------------+-----------+
| PAYMENT | customer_count | order_count | order_item_count | sum_age | sum_shipping | sum_units |
+---------+----------------+-------------+------------------+---------+--------------+-----------+
-| cash | 2 | 2 | 3 | 67 | 32 | 11 |
-| visa | 1 | 1 | 3 | 75 | 60 | 13 |
+| cash | 2 | 2 | 3 | 67 | 32.00 | 11 |
+| visa | 1 | 1 | 3 | 75 | 60.00 | 13 |
+---------+----------------+-------------+------------------+---------+--------------+-----------+
(2 rows)
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java b/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
index 4beddd31ee60..61030d391f35 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapter2IT.java
@@ -1909,10 +1909,14 @@ private void checkGroupBySingleSortLimit(boolean approx) {
+ "end as b from \"foodmart\" group by \"store_state\" order by a desc";
final String postAggString = "'postAggregations':[{'type':'expression','name':'A',"
+ "'expression':'(\\'$f1\\' / \\'$f2\\')'},{'type':'expression','name':'B',"
- + "'expression':'case_searched((\\'$f3\\' == 0),1.0,CAST(\\'$f3\\'";
+ + "'expression':'case_searched((\\'$f3\\' == 0),1,CAST(\\'$f3\\'";
final String plan = "PLAN="
+ "EnumerableInterpreter\n"
- + " DruidQuery(table=[[foodmart, foodmart]], intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91, $89]], groups=[{0}], aggs=[[SUM($1), SUM($2), SUM($3)]], post_projects=[[$0, /($1, $2), CASE(=($3, 0), 1.0:DECIMAL(19, 0), CAST($3):DECIMAL(19, 0))]], sort0=[1], dir0=[DESC])\n";
+ + " DruidQuery(table=[[foodmart, foodmart]],"
+ + " intervals=[[1900-01-09T00:00:00.000Z/2992-01-10T00:00:00.000Z]],"
+ + " projects=[[$63, $90, $91, $89]], groups=[{0}], aggs=[[SUM($1), SUM($2), SUM($3)]],"
+ + " post_projects=[[$0, /($1, $2), CASE(=($3, 0), CAST(1:DECIMAL(19, 0)):DECIMAL(19, 0),"
+ + " CAST($3):DECIMAL(19, 0))]], sort0=[1], dir0=[DESC])\n";
CalciteAssert.AssertQuery q = sql(sqlQuery)
.explainContains(plan)
.queryContains(new DruidChecker(postAggString));
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
index b03f3e19e86a..a318747f46b3 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -2215,12 +2215,13 @@ private void checkGroupBySingleSortLimit(boolean approx) {
+ "from \"foodmart\" group by \"store_state\" order by a desc";
final String postAggString = "'postAggregations':[{'type':'expression','name':'A',"
+ "'expression':'(\\'$f1\\' / \\'$f2\\')'},{'type':'expression','name':'B',"
- + "'expression':'case_searched((\\'$f3\\' == 0),1.0,CAST(\\'$f3\\'";
+ + "'expression':'case_searched((\\'$f3\\' == 0),1,CAST(\\'$f3\\'";
final String plan =
"DruidQuery(table=[[foodmart, foodmart]], intervals=[[1900-01-09T00:00:00.000Z/"
+ "2992-01-10T00:00:00.000Z]], projects=[[$63, $90, $91, $89]], groups=[{0}], "
+ "aggs=[[SUM($1), SUM($2), SUM($3)]], post_projects=[[$0, /($1, $2), "
- + "CASE(=($3, 0), 1.0:DECIMAL(19, 0), CAST($3):DECIMAL(19, 0))]], sort0=[1], dir0=[DESC])";
+ + "CASE(=($3, 0), CAST(1:DECIMAL(19, 0)):DECIMAL(19, 0), "
+ + "CAST($3):DECIMAL(19, 0))]], sort0=[1], dir0=[DESC])";
CalciteAssert.AssertQuery q = sql(sqlQuery, FOODMART)
.explainContains(plan)
.queryContains(new DruidChecker(postAggString));
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java
index 6aa575c795cf..45b568ffa19b 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java
@@ -384,10 +384,57 @@ static void checkRoundedRange(Number value, double min, double max) {
}
}
+ /** Called from BuiltInMethod.INTEGER_CAST */
public static @Nullable Object integerCast(Primitive primitive, final Object value) {
return requireNonNull(primitive, "primitive").numberValue((Number) value);
}
+ static BigDecimal checkOverflow(BigDecimal value, int precision, int scale) {
+ BigDecimal result = value.setScale(scale, RoundingMode.FLOOR);
+ result = result.stripTrailingZeros();
+ if (result.scale() < scale) {
+ // stripTrailingZeros also removes zeros if there is no
+ // decimal point, converting 1000 to 1e+3, using a negative scale.
+ // Here we undo this change.
+ result = result.setScale(scale, RoundingMode.FLOOR);
+ }
+ int actualPrecision = result.precision();
+ if (actualPrecision > precision) {
+ throw new ArithmeticException("Value " + value
+ + " cannot be represented as a DECIMAL(" + precision + ", " + scale + ")");
+ }
+ return result;
+ }
+
+ /** Called from BuiltInMethod.DECIMAL_DECIMAL_CAST */
+ public static @Nullable Object decimalDecimalCast(
+ @Nullable BigDecimal value, int precision, int scale) {
+ if (value == null) {
+ return null;
+ }
+ return checkOverflow(value, precision, scale);
+ }
+
+ /** Called from BuiltInMethod.INTEGER_DECIMAL_CAST */
+ public static @Nullable Object integerDecimalCast(
+ @Nullable Object value, int precision, int scale) {
+ if (value == null) {
+ return null;
+ }
+ final BigDecimal decimal = new BigDecimal(((Number) value).longValue());
+ return checkOverflow(decimal, precision, scale);
+ }
+
+ /** Called from BuiltInMethod.FP_DECIMAL_CAST */
+ public static @Nullable Object fpDecimalCast(
+ @Nullable Object value, int precision, int scale) {
+ if (value == null) {
+ return null;
+ }
+ final BigDecimal decimal = BigDecimal.valueOf(((Number) value).doubleValue());
+ return checkOverflow(decimal, precision, scale);
+ }
+
/**
* Converts a number into a value of the type specified by this primitive
* using the SQL CAST rules. If the value conversion causes loss of significant digits,
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index d0e529944d2b..c6bef6d9d8c0 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -598,6 +598,13 @@ void testCastBooleanToNumeric(CastType castType, SqlOperatorFixture f) {
"Cast function cannot convert value of type BOOLEAN to type DECIMAL\\(19, 0\\)", false);
}
+ /** Test case for
+ * [CALCITE-6322] Casts to DECIMAL types are ignored. */
+ @Test void testDecimalDecimalCast() {
+ final SqlOperatorFixture f = fixture();
+ f.checkScalar("CAST(1.123 AS DECIMAL(4, 0))", "1", "DECIMAL(4, 0) NOT NULL");
+ }
+
@ParameterizedTest
@MethodSource("safeParameters")
void testCastExactNumericLimits(CastType castType, SqlOperatorFixture f) {
@@ -754,6 +761,7 @@ void testCastStringToDecimal(CastType castType, SqlOperatorFixture f) {
"-1.2");
f.checkFails("cast(' -1.21e' as decimal(2,1))", INVALID_CHAR_MESSAGE,
true);
+ f.checkFails("cast(''100' as decimal(2, 1))", "Value .* out of range", true);
}
@ParameterizedTest
@@ -8226,7 +8234,7 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
f.checkType("atanh('abc')", "DOUBLE NOT NULL");
f.checkScalarApprox("atanh(0.76159416)", "DOUBLE NOT NULL",
isWithin(1d, 0.0001d));
- f.checkScalarApprox("atanh(cast(-0.1 as decimal))", "DOUBLE NOT NULL",
+ f.checkScalarApprox("atanh(cast(-0.1 as decimal(2,1)))", "DOUBLE NOT NULL",
isWithin(-0.1003d, 0.0001d));
f.checkNull("atanh(cast(null as integer))");
f.checkNull("atanh(cast(null as double))");
@@ -8568,18 +8576,18 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
false);
f.checkType("round('abc', 'def')", "DECIMAL(19, 9) NOT NULL");
f.checkScalar("round(42, -1)", 40, "INTEGER NOT NULL");
- f.checkScalar("round(cast(42.346 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(4235, 2), "DECIMAL(2, 3) NOT NULL");
- f.checkScalar("round(cast(-42.346 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(-4235, 2), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("round(cast(42.346 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(4235, 2), "DECIMAL(5, 3) NOT NULL");
+ f.checkScalar("round(cast(-42.346 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(-4235, 2), "DECIMAL(5, 3) NOT NULL");
f.checkNull("round(cast(null as integer), 1)");
f.checkNull("round(cast(null as double), 1)");
f.checkNull("round(43.21, cast(null as integer))");
f.checkNull("round(cast(null as double))");
f.checkScalar("round(42)", 42, "INTEGER NOT NULL");
- f.checkScalar("round(cast(42.346 as decimal(2, 3)))",
- BigDecimal.valueOf(42, 0), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("round(cast(42.346 as decimal(5, 3)))",
+ BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkScalar("round(42.324)",
BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkScalar("round(42.724)",
@@ -8755,10 +8763,10 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
false);
f.checkType("trunc('abc', 'def')", "DECIMAL(19, 9) NOT NULL");
f.checkScalar("trunc(42, -1)", 40.0, "DOUBLE NOT NULL");
- f.checkScalar("trunc(cast(42.345 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(4234, 2), "DECIMAL(2, 3) NOT NULL");
- f.checkScalar("trunc(cast(-42.345 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(-4234, 2), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("trunc(cast(42.345 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(4234, 2), "DECIMAL(5, 3) NOT NULL");
+ f.checkScalar("trunc(cast(-42.345 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(-4234, 2), "DECIMAL(5, 3) NOT NULL");
f.checkNull("trunc(cast(null as integer), 1)");
f.checkNull("trunc(cast(null as double), 1)");
f.checkNull("trunc(43.21, cast(null as integer))");
@@ -8768,8 +8776,8 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkScalar("trunc(cast(42.324 as float))", 42F,
"FLOAT NOT NULL");
- f.checkScalar("trunc(cast(42.345 as decimal(2, 3)))",
- BigDecimal.valueOf(42, 0), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("trunc(cast(42.345 as decimal(5, 3)))",
+ BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkNull("trunc(cast(null as integer))");
f.checkNull("trunc(cast(null as double))");
}
@@ -8790,10 +8798,10 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
false);
f.checkType("truncate('abc', 'def')", "DECIMAL(19, 9) NOT NULL");
f.checkScalar("truncate(42, -1)", 40, "INTEGER NOT NULL");
- f.checkScalar("truncate(cast(42.345 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(4234, 2), "DECIMAL(2, 3) NOT NULL");
- f.checkScalar("truncate(cast(-42.345 as decimal(2, 3)), 2)",
- BigDecimal.valueOf(-4234, 2), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("truncate(cast(42.345 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(4234, 2), "DECIMAL(5, 3) NOT NULL");
+ f.checkScalar("truncate(cast(-42.345 as decimal(5, 3)), 2)",
+ BigDecimal.valueOf(-4234, 2), "DECIMAL(5, 3) NOT NULL");
f.checkNull("truncate(cast(null as integer), 1)");
f.checkNull("truncate(cast(null as double), 1)");
f.checkNull("truncate(43.21, cast(null as integer))");
@@ -8803,8 +8811,8 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkScalar("truncate(cast(42.324 as float))", 42F,
"FLOAT NOT NULL");
- f.checkScalar("truncate(cast(42.345 as decimal(2, 3)))",
- BigDecimal.valueOf(42, 0), "DECIMAL(2, 3) NOT NULL");
+ f.checkScalar("truncate(cast(42.345 as decimal(5, 3)))",
+ BigDecimal.valueOf(42, 0), "DECIMAL(5, 3) NOT NULL");
f.checkNull("truncate(cast(null as integer))");
f.checkNull("truncate(cast(null as double))");
}
@@ -8857,14 +8865,16 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
+ "cast(9223372036854775807 as bigint))");
f.checkNull("safe_add(cast(-20 as bigint), "
+ "cast(-9223372036854775807 as bigint))");
- f.checkNull("safe_add(9, cast(9.999999999999999999e75 as DECIMAL(38, 19)))");
- f.checkNull("safe_add(-9, cast(-9.999999999999999999e75 as DECIMAL(38, 19)))");
- f.checkNull("safe_add(cast(9.999999999999999999e75 as DECIMAL(38, 19)), 9)");
- f.checkNull("safe_add(cast(-9.999999999999999999e75 as DECIMAL(38, 19)), -9)");
- f.checkNull("safe_add(cast(9.9e75 as DECIMAL(76, 0)), "
- + "cast(9.9e75 as DECIMAL(76, 0)))");
- f.checkNull("safe_add(cast(-9.9e75 as DECIMAL(76, 0)), "
- + "cast(-9.9e75 as DECIMAL(76, 0)))");
+ if (Bug.CALCITE_6328_FIXED) {
+ f.checkNull("safe_add(9, cast(9.999999999999999999e75 as DECIMAL(38, 19)))");
+ f.checkNull("safe_add(-9, cast(-9.999999999999999999e75 as DECIMAL(38, 19)))");
+ f.checkNull("safe_add(cast(9.999999999999999999e75 as DECIMAL(38, 19)), 9)");
+ f.checkNull("safe_add(cast(-9.999999999999999999e75 as DECIMAL(38, 19)), -9)");
+ f.checkNull("safe_add(cast(9.9e75 as DECIMAL(76, 0)), "
+ + "cast(9.9e75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_add(cast(-9.9e75 as DECIMAL(76, 0)), "
+ + "cast(-9.9e75 as DECIMAL(76, 0)))");
+ }
f.checkNull("safe_add(cast(1.7976931348623157e308 as double), "
+ "cast(9.9e7 as decimal(76, 0)))");
f.checkNull("safe_add(cast(-1.7976931348623157e308 as double), "
@@ -8936,20 +8946,22 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
f.checkNull("safe_divide(cast(0 as double), cast(0 as bigint))");
f.checkNull("safe_divide(cast(0 as double), cast(0 as double))");
f.checkNull("safe_divide(cast(0 as double), cast(0 as decimal(1, 0)))");
- f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as bigint))");
- f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as double))");
- f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as decimal(1, 0)))");
- // Overflow test for each pairing
- f.checkNull("safe_divide(cast(10 as bigint), cast(3.5e-75 as DECIMAL(76, 0)))");
- f.checkNull("safe_divide(cast(10 as bigint), cast(-3.5e75 as DECIMAL(76, 0)))");
- f.checkNull("safe_divide(cast(3.5e75 as DECIMAL(76, 0)), "
- + "cast(1.5 as DECIMAL(2, 1)))");
- f.checkNull("safe_divide(cast(-3.5e75 as DECIMAL(76, 0)), "
- + "cast(1.5 as DECIMAL(2, 1)))");
+ if (Bug.CALCITE_6328_FIXED) {
+ f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as bigint))");
+ f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as double))");
+ f.checkNull("safe_divide(cast(1.5 as decimal(2, 1)), cast(0 as decimal(1, 0)))");
+ // Overflow test for each pairing
+ f.checkNull("safe_divide(cast(10 as bigint), cast(3.5e-75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_divide(cast(10 as bigint), cast(-3.5e75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_divide(cast(3.5e75 as DECIMAL(76, 0)), "
+ + "cast(1.5 as DECIMAL(2, 1)))");
+ f.checkNull("safe_divide(cast(-3.5e75 as DECIMAL(76, 0)), "
+ + "cast(1.5 as DECIMAL(2, 1)))");
+ f.checkNull("safe_divide(cast(5e20 as decimal(1, 0)), cast(1.7e-309 as double))");
+ f.checkNull("safe_divide(cast(5e20 as decimal(1, 0)), cast(-1.7e-309 as double))");
+ }
f.checkNull("safe_divide(cast(1.7e308 as double), cast(0.5 as decimal(3, 2)))");
f.checkNull("safe_divide(cast(-1.7e308 as double), cast(0.5 as decimal(2, 1)))");
- f.checkNull("safe_divide(cast(5e20 as decimal(1, 0)), cast(1.7e-309 as double))");
- f.checkNull("safe_divide(cast(5e20 as decimal(1, 0)), cast(-1.7e-309 as double))");
f.checkNull("safe_divide(cast(3 as bigint), cast(1.7e-309 as double))");
f.checkNull("safe_divide(cast(3 as bigint), cast(-1.7e-309 as double))");
f.checkNull("safe_divide(cast(3 as double), cast(1.7e-309 as double))");
@@ -9007,14 +9019,16 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
+ "cast(9223372036854775807 as bigint))");
f.checkNull("safe_multiply(cast(20 as bigint), "
+ "cast(-9223372036854775807 as bigint))");
- f.checkNull("safe_multiply(cast(10 as bigint), cast(3.5e75 as DECIMAL(76, 0)))");
- f.checkNull("safe_multiply(cast(10 as bigint), cast(-3.5e75 as DECIMAL(76, 0)))");
- f.checkNull("safe_multiply(cast(3.5e75 as DECIMAL(76, 0)), cast(10 as bigint))");
- f.checkNull("safe_multiply(cast(-3.5e75 as DECIMAL(76, 0)), cast(10 as bigint))");
- f.checkNull("safe_multiply(cast(3.5e75 as DECIMAL(76, 0)), "
- + "cast(1.5 as DECIMAL(2, 1)))");
- f.checkNull("safe_multiply(cast(-3.5e75 as DECIMAL(76, 0)), "
- + "cast(1.5 as DECIMAL(2, 1)))");
+ if (Bug.CALCITE_6328_FIXED) {
+ f.checkNull("safe_multiply(cast(10 as bigint), cast(3.5e75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_multiply(cast(10 as bigint), cast(-3.5e75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_multiply(cast(3.5e75 as DECIMAL(76, 0)), cast(10 as bigint))");
+ f.checkNull("safe_multiply(cast(-3.5e75 as DECIMAL(76, 0)), cast(10 as bigint))");
+ f.checkNull("safe_multiply(cast(3.5e75 as DECIMAL(76, 0)), "
+ + "cast(1.5 as DECIMAL(2, 1)))");
+ f.checkNull("safe_multiply(cast(-3.5e75 as DECIMAL(76, 0)), "
+ + "cast(1.5 as DECIMAL(2, 1)))");
+ }
f.checkNull("safe_multiply(cast(1.7e308 as double), cast(1.23 as decimal(3, 2)))");
f.checkNull("safe_multiply(cast(-1.7e308 as double), cast(1.2 as decimal(2, 1)))");
f.checkNull("safe_multiply(cast(1.2 as decimal(2, 1)), cast(1.7e308 as double))");
@@ -9117,14 +9131,16 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) {
+ "cast(-9223372036854775807 as bigint))");
f.checkNull("safe_subtract(cast(-20 as bigint), "
+ "cast(9223372036854775807 as bigint))");
- f.checkNull("safe_subtract(9, cast(-9.999999999999999999e75 as DECIMAL(38, 19)))");
- f.checkNull("safe_subtract(-9, cast(9.999999999999999999e75 as DECIMAL(38, 19)))");
- f.checkNull("safe_subtract(cast(-9.999999999999999999e75 as DECIMAL(38, 19)), 9)");
- f.checkNull("safe_subtract(cast(9.999999999999999999e75 as DECIMAL(38, 19)), -9)");
- f.checkNull("safe_subtract(cast(-9.9e75 as DECIMAL(76, 0)), "
- + "cast(9.9e75 as DECIMAL(76, 0)))");
- f.checkNull("safe_subtract(cast(9.9e75 as DECIMAL(76, 0)), "
- + "cast(-9.9e75 as DECIMAL(76, 0)))");
+ if (Bug.CALCITE_6328_FIXED) {
+ f.checkNull("safe_subtract(9, cast(-9.999999999999999999e75 as DECIMAL(38, 19)))");
+ f.checkNull("safe_subtract(-9, cast(9.999999999999999999e75 as DECIMAL(38, 19)))");
+ f.checkNull("safe_subtract(cast(-9.999999999999999999e75 as DECIMAL(38, 19)), 9)");
+ f.checkNull("safe_subtract(cast(9.999999999999999999e75 as DECIMAL(38, 19)), -9)");
+ f.checkNull("safe_subtract(cast(-9.9e75 as DECIMAL(76, 0)), "
+ + "cast(9.9e75 as DECIMAL(76, 0)))");
+ f.checkNull("safe_subtract(cast(9.9e75 as DECIMAL(76, 0)), "
+ + "cast(-9.9e75 as DECIMAL(76, 0)))");
+ }
f.checkNull("safe_subtract(cast(1.7976931348623157e308 as double), "
+ "cast(-9.9e7 as decimal(76, 0)))");
f.checkNull("safe_subtract(cast(-1.7976931348623157e308 as double), "
@@ -11851,8 +11867,8 @@ private static void checkArrayConcatAggFuncFails(SqlOperatorFixture t) {
f.checkScalarExact("ceil(cast(3 as integer))", "DOUBLE NOT NULL", "3.0");
f.checkScalarExact("ceil(cast(3 as bigint))", "DOUBLE NOT NULL", "3.0");
f.checkScalarExact("ceil(cast(3.5 as double))", "DOUBLE NOT NULL", "4.0");
- f.checkScalarExact("ceil(cast(3.45 as decimal))",
- "DECIMAL(19, 0) NOT NULL", "4");
+ f.checkScalarExact("ceil(cast(3.45 as decimal(19, 1)))",
+ "DECIMAL(19, 1) NOT NULL", "4");
f.checkScalarExact("ceil(cast(3.45 as float))", "FLOAT NOT NULL", "4.0");
f.checkNull("ceil(cast(null as tinyint))");
}
@@ -14533,14 +14549,13 @@ void checkBitOr(SqlOperatorFixture f0, FunctionAlias functionAlias) {
} else {
// Value outside legal bound should fail at runtime (not
// validate time).
- //
- // NOTE: Because Java and Fennel calcs give
- // different errors, the pattern hedges its bets.
- if (Bug.CALCITE_2539_FIXED) {
- f.checkFails("CAST(" + literalString + " AS " + type + ")",
- "(?s).*(Overflow during calculation or cast\\.|Code=22003).*",
- true);
+ String expected;
+ if (type.getSqlTypeName() == SqlTypeName.DECIMAL) {
+ expected = "Value .* cannot be represented as .*";
+ } else {
+ expected = "Value .* out of range";
}
+ f.checkFails("CAST(" + literalString + " AS " + type + ")", expected, true);
}
}
}