From dac7a41cbda35904644a4d562d938d59719297f4 Mon Sep 17 00:00:00 2001 From: Wei <15172118655@163.com> Date: Mon, 4 Dec 2023 19:22:38 +0800 Subject: [PATCH] feat: sqlness for decimal128 (#2822) --- .../types/decimal/decimal_aggregates.result | 104 ++++ .../types/decimal/decimal_aggregates.sql | 59 +++ .../types/decimal/decimal_arithmetic.result | 267 ++++++++++ .../types/decimal/decimal_arithmetic.sql | 127 +++++ .../common/types/decimal/decimal_cast.result | 496 ++++++++++++++++++ .../common/types/decimal/decimal_cast.sql | 203 +++++++ .../common/types/decimal/decimal_ops.result | 436 +++++++++++++++ .../common/types/decimal/decimal_ops.sql | 203 +++++++ .../decimal_small_precision_behavior.result | 66 +++ .../decimal_small_precision_behavior.sql | 17 + .../common/types/decimal/decimal_table.result | 60 +++ .../common/types/decimal/decimal_table.sql | 17 + 12 files changed, 2055 insertions(+) create mode 100644 tests/cases/standalone/common/types/decimal/decimal_aggregates.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_aggregates.sql create mode 100644 tests/cases/standalone/common/types/decimal/decimal_arithmetic.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_arithmetic.sql create mode 100644 tests/cases/standalone/common/types/decimal/decimal_cast.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_cast.sql create mode 100644 tests/cases/standalone/common/types/decimal/decimal_ops.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_ops.sql create mode 100644 tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.sql create mode 100644 tests/cases/standalone/common/types/decimal/decimal_table.result create mode 100644 tests/cases/standalone/common/types/decimal/decimal_table.sql diff --git a/tests/cases/standalone/common/types/decimal/decimal_aggregates.result b/tests/cases/standalone/common/types/decimal/decimal_aggregates.result new file mode 100644 index 000000000000..d246cc1d5947 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_aggregates.result @@ -0,0 +1,104 @@ +-- Test aggregation functions with decimal +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/decimal_aggregates.test +SELECT arrow_typeof(FIRST_VALUE('0.1'::DECIMAL(4,1))); + ++----------------------------------------+ +| arrow_typeof(FIRST_VALUE(Utf8("0.1"))) | ++----------------------------------------+ +| Decimal128(4, 1) | ++----------------------------------------+ + +-- first_value +SELECT FIRST_VALUE(NULL::DECIMAL), + FIRST_VALUE('0.1'::DECIMAL(4,1))::VARCHAR, + FIRST_VALUE('4938245.1'::DECIMAL(9,1))::VARCHAR, + FIRST_VALUE('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + FIRST_VALUE('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + ++-------------------+--------------------------+--------------------------------+------------------------------------------+--------------------------------------------------------------+ +| FIRST_VALUE(NULL) | FIRST_VALUE(Utf8("0.1")) | FIRST_VALUE(Utf8("4938245.1")) | FIRST_VALUE(Utf8("45672564564938245.1")) | FIRST_VALUE(Utf8("4567645908450368043562342564564938245.1")) | ++-------------------+--------------------------+--------------------------------+------------------------------------------+--------------------------------------------------------------+ +| | 0.1 | 4938245.1 | 45672564564938245.1 | 4567645908450368043562342564564938245.1 | ++-------------------+--------------------------+--------------------------------+------------------------------------------+--------------------------------------------------------------+ + +-- min +SELECT MIN(NULL::DECIMAL), + MIN('0.1'::DECIMAL(4,1))::VARCHAR, + MIN('4938245.1'::DECIMAL(9,1))::VARCHAR, + MIN('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + MIN('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| MIN(NULL) | MIN(Utf8("0.1")) | MIN(Utf8("4938245.1")) | MIN(Utf8("45672564564938245.1")) | MIN(Utf8("4567645908450368043562342564564938245.1")) | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| | 0.1 | 4938245.1 | 45672564564938245.1 | 4567645908450368043562342564564938245.1 | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ + +-- max +SELECT MAX(NULL::DECIMAL), + MAX('0.1'::DECIMAL(4,1))::VARCHAR, + MAX('4938245.1'::DECIMAL(9,1))::VARCHAR, + MAX('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + MAX('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| MAX(NULL) | MAX(Utf8("0.1")) | MAX(Utf8("4938245.1")) | MAX(Utf8("45672564564938245.1")) | MAX(Utf8("4567645908450368043562342564564938245.1")) | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| | 0.1 | 4938245.1 | 45672564564938245.1 | 4567645908450368043562342564564938245.1 | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ + +-- sum +SELECT SUM(NULL::DECIMAL), + SUM('0.1'::DECIMAL(4,1))::VARCHAR, + SUM('4938245.1'::DECIMAL(9,1))::VARCHAR, + SUM('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + SUM('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| SUM(NULL) | SUM(Utf8("0.1")) | SUM(Utf8("4938245.1")) | SUM(Utf8("45672564564938245.1")) | SUM(Utf8("4567645908450368043562342564564938245.1")) | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ +| | 0.1 | 4938245.1 | 45672564564938245.1 | 4567645908450368043562342564564938245.1 | ++-----------+------------------+------------------------+----------------------------------+------------------------------------------------------+ + +-- decimal aggregates over a table +CREATE TABLE decimals ( + d1 DECIMAL(4,1), + d2 DECIMAL(9,1), + d3 DECIMAL(18,1), + d4 DECIMAL(38,1), + ts timestamp time index, +); + +Affected Rows: 0 + +INSERT INTO decimals values +(123,123*123,123*123*123,123*123*123*123,1000), +(456,456*456,456*456*456,456*456*456*456,2000), +(789,789*789,789*789*789,789*789*789*789,3000); + +Affected Rows: 3 + +SELECT SUM(d1)::VARCHAR, SUM(d2)::VARCHAR, SUM(d3)::VARCHAR, SUM(d4)::VARCHAR FROM decimals; + ++------------------+------------------+------------------+------------------+ +| SUM(decimals.d1) | SUM(decimals.d2) | SUM(decimals.d3) | SUM(decimals.d4) | ++------------------+------------------+------------------+------------------+ +| 1368.0 | 845586.0 | 587848752.0 | 430998662178.0 | ++------------------+------------------+------------------+------------------+ + +INSERT INTO decimals VALUES ('0.1', '0.1', '0.1', '0.1', 4000), ('0.2', '0.2', '0.2', '0.2', 5000); + +Affected Rows: 2 + +SELECT SUM(d1)::VARCHAR, SUM(d2)::VARCHAR, SUM(d3)::VARCHAR, SUM(d4)::VARCHAR FROM decimals; + ++------------------+------------------+------------------+------------------+ +| SUM(decimals.d1) | SUM(decimals.d2) | SUM(decimals.d3) | SUM(decimals.d4) | ++------------------+------------------+------------------+------------------+ +| 1368.3 | 845586.3 | 587848752.3 | 430998662178.3 | ++------------------+------------------+------------------+------------------+ + +DROP TABLE decimals; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/types/decimal/decimal_aggregates.sql b/tests/cases/standalone/common/types/decimal/decimal_aggregates.sql new file mode 100644 index 000000000000..bcc15bdb8b33 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_aggregates.sql @@ -0,0 +1,59 @@ +-- Test aggregation functions with decimal +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/decimal_aggregates.test + +SELECT arrow_typeof(FIRST_VALUE('0.1'::DECIMAL(4,1))); + +-- first_value + +SELECT FIRST_VALUE(NULL::DECIMAL), + FIRST_VALUE('0.1'::DECIMAL(4,1))::VARCHAR, + FIRST_VALUE('4938245.1'::DECIMAL(9,1))::VARCHAR, + FIRST_VALUE('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + FIRST_VALUE('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + +-- min + +SELECT MIN(NULL::DECIMAL), + MIN('0.1'::DECIMAL(4,1))::VARCHAR, + MIN('4938245.1'::DECIMAL(9,1))::VARCHAR, + MIN('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + MIN('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + +-- max + +SELECT MAX(NULL::DECIMAL), + MAX('0.1'::DECIMAL(4,1))::VARCHAR, + MAX('4938245.1'::DECIMAL(9,1))::VARCHAR, + MAX('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + MAX('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + +-- sum + +SELECT SUM(NULL::DECIMAL), + SUM('0.1'::DECIMAL(4,1))::VARCHAR, + SUM('4938245.1'::DECIMAL(9,1))::VARCHAR, + SUM('45672564564938245.1'::DECIMAL(18,1))::VARCHAR, + SUM('4567645908450368043562342564564938245.1'::DECIMAL(38,1))::VARCHAR; + +-- decimal aggregates over a table + +CREATE TABLE decimals ( + d1 DECIMAL(4,1), + d2 DECIMAL(9,1), + d3 DECIMAL(18,1), + d4 DECIMAL(38,1), + ts timestamp time index, +); + +INSERT INTO decimals values +(123,123*123,123*123*123,123*123*123*123,1000), +(456,456*456,456*456*456,456*456*456*456,2000), +(789,789*789,789*789*789,789*789*789*789,3000); + +SELECT SUM(d1)::VARCHAR, SUM(d2)::VARCHAR, SUM(d3)::VARCHAR, SUM(d4)::VARCHAR FROM decimals; + +INSERT INTO decimals VALUES ('0.1', '0.1', '0.1', '0.1', 4000), ('0.2', '0.2', '0.2', '0.2', 5000); + +SELECT SUM(d1)::VARCHAR, SUM(d2)::VARCHAR, SUM(d3)::VARCHAR, SUM(d4)::VARCHAR FROM decimals; + +DROP TABLE decimals; diff --git a/tests/cases/standalone/common/types/decimal/decimal_arithmetic.result b/tests/cases/standalone/common/types/decimal/decimal_arithmetic.result new file mode 100644 index 000000000000..9be450cc7f00 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_arithmetic.result @@ -0,0 +1,267 @@ +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/decimal_arithmetic.test +-- negate +SELECT -('0.1'::DECIMAL), -('-0.1'::DECIMAL); + ++-----------------+------------------+ +| (- Utf8("0.1")) | (- Utf8("-0.1")) | ++-----------------+------------------+ +| -0.1000000000 | 0.1000000000 | ++-----------------+------------------+ + +-- unary + +SELECT +('0.1'::DECIMAL), +('-0.1'::DECIMAL); + ++--------------+---------------+ +| Utf8("0.1") | Utf8("-0.1") | ++--------------+---------------+ +| 0.1000000000 | -0.1000000000 | ++--------------+---------------+ + +-- addition +SELECT '0.1'::DECIMAL + '0.1'::DECIMAL; + ++---------------------------+ +| Utf8("0.1") + Utf8("0.1") | ++---------------------------+ +| 0.2000000000 | ++---------------------------+ + +-- addition with non-decimal +SELECT '0.1'::DECIMAL + 1::INTEGER; + ++------------------------+ +| Utf8("0.1") + Int64(1) | ++------------------------+ +| 1.1000000000 | ++------------------------+ + +SELECT '0.5'::DECIMAL(4,4) + '0.5'::DECIMAL(4,4); + ++---------------------------+ +| Utf8("0.5") + Utf8("0.5") | ++---------------------------+ +| 1.0000 | ++---------------------------+ + +-- addition between different decimal types +SELECT '0.5'::DECIMAL(1,1) + '100.0'::DECIMAL(3,0); + ++-----------------------------+ +| Utf8("0.5") + Utf8("100.0") | ++-----------------------------+ +| 100.5 | ++-----------------------------+ + +-- test decimals and integers with big decimals +SELECT ('0.5'::DECIMAL(1,1) + 10000)::VARCHAR, + ('0.54321'::DECIMAL(5,5) + 10000)::VARCHAR, + ('0.5432154321'::DECIMAL(10,10) + 10000)::VARCHAR, + ('0.543215432154321'::DECIMAL(15,15) + 10000::DECIMAL(20,15))::VARCHAR, + ('0.54321543215432154321'::DECIMAL(20,20) + 10000)::VARCHAR, + ('0.5432154321543215432154321'::DECIMAL(25,25) + 10000)::VARCHAR; + ++----------------------------+--------------------------------+-------------------------------------+------------------------------------------+-----------------------------------------------+----------------------------------------------------+ +| Utf8("0.5") + Int64(10000) | Utf8("0.54321") + Int64(10000) | Utf8("0.5432154321") + Int64(10000) | Utf8("0.543215432154321") + Int64(10000) | Utf8("0.54321543215432154321") + Int64(10000) | Utf8("0.5432154321543215432154321") + Int64(10000) | ++----------------------------+--------------------------------+-------------------------------------+------------------------------------------+-----------------------------------------------+----------------------------------------------------+ +| 10000.5 | 10000.54321 | 10000.5432154321 | 10000.543215432154321 | 10000.54321543215432154321 | 10000.5432154321543215432154321 | ++----------------------------+--------------------------------+-------------------------------------+------------------------------------------+-----------------------------------------------+----------------------------------------------------+ + +-- out of range +SELECT ('0.54321543215432154321543215432154321'::DECIMAL(35,35) + 10000)::VARCHAR; + +Error: 3001(EngineExecuteQuery), DataFusion error: Compute error: Overflow happened on: 10000 * 100000000000000000000000000000000000 + +-- different types +SELECT '0.5'::DECIMAL(1,1) + 1::TINYINT, + '0.5'::DECIMAL(1,1) + 2::SMALLINT, + '0.5'::DECIMAL(1,1) + 3::INTEGER, + '0.5'::DECIMAL(1,1) + 4::BIGINT; + ++------------------------+------------------------+------------------------+------------------------+ +| Utf8("0.5") + Int64(1) | Utf8("0.5") + Int64(2) | Utf8("0.5") + Int64(3) | Utf8("0.5") + Int64(4) | ++------------------------+------------------------+------------------------+------------------------+ +| 1.5 | 2.5 | 3.5 | 4.5 | ++------------------------+------------------------+------------------------+------------------------+ + +-- negative numbers +SELECT '0.5'::DECIMAL(1,1) + -1::TINYINT, + '0.5'::DECIMAL(1,1) + -2::SMALLINT, + '0.5'::DECIMAL(1,1) + -3::INTEGER, + '0.5'::DECIMAL(1,1) + -4::BIGINT; + ++----------------------------+----------------------------+----------------------------+----------------------------+ +| Utf8("0.5") + (- Int64(1)) | Utf8("0.5") + (- Int64(2)) | Utf8("0.5") + (- Int64(3)) | Utf8("0.5") + (- Int64(4)) | ++----------------------------+----------------------------+----------------------------+----------------------------+ +| -0.5 | -1.5 | -2.5 | -3.5 | ++----------------------------+----------------------------+----------------------------+----------------------------+ + +-- subtract +SELECT '0.5'::DECIMAL(1,1) - 1::TINYINT, + '0.5'::DECIMAL(1,1) - 2::SMALLINT, + '0.5'::DECIMAL(1,1) - 3::INTEGER, + '0.5'::DECIMAL(1,1) - 4::BIGINT; + ++------------------------+------------------------+------------------------+------------------------+ +| Utf8("0.5") - Int64(1) | Utf8("0.5") - Int64(2) | Utf8("0.5") - Int64(3) | Utf8("0.5") - Int64(4) | ++------------------------+------------------------+------------------------+------------------------+ +| -0.5 | -1.5 | -2.5 | -3.5 | ++------------------------+------------------------+------------------------+------------------------+ + +-- negative numbers +SELECT '0.5'::DECIMAL(1,1) - -1::TINYINT, + '0.5'::DECIMAL(1,1) - -2::SMALLINT, + '0.5'::DECIMAL(1,1) - -3::INTEGER, + '0.5'::DECIMAL(1,1) - -4::BIGINT; + ++----------------------------+----------------------------+----------------------------+----------------------------+ +| Utf8("0.5") - (- Int64(1)) | Utf8("0.5") - (- Int64(2)) | Utf8("0.5") - (- Int64(3)) | Utf8("0.5") - (- Int64(4)) | ++----------------------------+----------------------------+----------------------------+----------------------------+ +| 1.5 | 2.5 | 3.5 | 4.5 | ++----------------------------+----------------------------+----------------------------+----------------------------+ + +-- now with a table +CREATE TABLE decimals(d DECIMAL(3, 2), ts timestamp time index); + +Affected Rows: 0 + +INSERT INTO decimals VALUES ('0.1',1000), ('0.2',1000); + +Affected Rows: 2 + +SELECT * FROM decimals; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.20 | 1970-01-01T00:00:01 | ++------+---------------------+ + +SELECT d + 10000 FROM decimals; + ++---------------------------+ +| decimals.d + Int64(10000) | ++---------------------------+ +| 10000.20 | ++---------------------------+ + +SELECT d + '0.1'::DECIMAL, d + 10000 FROM decimals; + ++--------------------------+---------------------------+ +| decimals.d + Utf8("0.1") | decimals.d + Int64(10000) | ++--------------------------+---------------------------+ +| 0.3000000000 | 10000.20 | ++--------------------------+---------------------------+ + +DROP TABLE decimals; + +Affected Rows: 0 + +-- multiplication +SELECT '0.1'::DECIMAL * '10.0'::DECIMAL; + ++----------------------------+ +| Utf8("0.1") * Utf8("10.0") | ++----------------------------+ +| 1.00000000000000000000 | ++----------------------------+ + +SELECT arrow_typeof('0.1'::DECIMAL(2,1) * '10.0'::DECIMAL(3,1)); + ++------------------------------------------+ +| arrow_typeof(Utf8("0.1") * Utf8("10.0")) | ++------------------------------------------+ +| Decimal128(6, 2) | ++------------------------------------------+ + +SELECT '0.1'::DECIMAL * '0.1'::DECIMAL; + ++---------------------------+ +| Utf8("0.1") * Utf8("0.1") | ++---------------------------+ +| 0.01000000000000000000 | ++---------------------------+ + +-- multiplication with non-decimal +SELECT '0.1'::DECIMAL * 10::INTEGER; + ++-------------------------+ +| Utf8("0.1") * Int64(10) | ++-------------------------+ +| 1.0000000000 | ++-------------------------+ + +SELECT '5.0'::DECIMAL(4,3) * '5.0'::DECIMAL(4,3); + ++---------------------------+ +| Utf8("5.0") * Utf8("5.0") | ++---------------------------+ +| 25.000000 | ++---------------------------+ + +-- negative multiplication +SELECT '-5.0'::DECIMAL(4,3) * '5.0'::DECIMAL(4,3); + ++----------------------------+ +| Utf8("-5.0") * Utf8("5.0") | ++----------------------------+ +| -25.000000 | ++----------------------------+ + +-- no precision is lost +SELECT ('18.25'::DECIMAL(4,2) * '17.25'::DECIMAL(4,2))::VARCHAR; + ++-------------------------------+ +| Utf8("18.25") * Utf8("17.25") | ++-------------------------------+ +| 314.8125 | ++-------------------------------+ + +-- different types +SELECT '0.001'::DECIMAL * 100::TINYINT, + '0.001'::DECIMAL * 10000::SMALLINT, + '0.001'::DECIMAL * 1000000::INTEGER, + '0.001'::DECIMAL * 100000000::BIGINT; + ++----------------------------+------------------------------+--------------------------------+----------------------------------+ +| Utf8("0.001") * Int64(100) | Utf8("0.001") * Int64(10000) | Utf8("0.001") * Int64(1000000) | Utf8("0.001") * Int64(100000000) | ++----------------------------+------------------------------+--------------------------------+----------------------------------+ +| 0.1000000000 | 10.0000000000 | 1000.0000000000 | 100000.0000000000 | ++----------------------------+------------------------------+--------------------------------+----------------------------------+ + +-- multiplication could not be performed exactly: throw error +SELECT '0.000000000000000000000000000001'::DECIMAL(38,30) * '0.000000000000000000000000000001'::DECIMAL(38,30); + +Error: 3000(PlanQuery), Failed to plan SQL: Error during planning: Cannot get result type for decimal operation Decimal128(38, 30) * Decimal128(38, 30): Invalid argument error: Output scale of Decimal128(38, 30) * Decimal128(38, 30) would exceed max scale of 38 + +-- test addition, subtraction and multiplication with various scales and precisions +SELECT 2.0 + 1.0 as col1, + 2.0000 + 1.0000 as col2, + 2.000000000000 + 1.000000000000 as col3, + 2.00000000000000000000 + 1.00000000000000000000 as col4; + ++------+------+------+------+ +| col1 | col2 | col3 | col4 | ++------+------+------+------+ +| 3.0 | 3.0 | 3.0 | 3.0 | ++------+------+------+------+ + +SELECT 2.0 - 1.0 as col1, + 2.0000 - 1.0000 as col2, + 2.000000000000 - 1.000000000000 as col3, + 2.00000000000000000000 - 1.00000000000000000000 as col4; + ++------+------+------+------+ +| col1 | col2 | col3 | col4 | ++------+------+------+------+ +| 1.0 | 1.0 | 1.0 | 1.0 | ++------+------+------+------+ + +SELECT 2.0 * 1.0 as col1, + 2.0000 * 1.0000 as col2; + ++------+------+ +| col1 | col2 | ++------+------+ +| 2.0 | 2.0 | ++------+------+ + diff --git a/tests/cases/standalone/common/types/decimal/decimal_arithmetic.sql b/tests/cases/standalone/common/types/decimal/decimal_arithmetic.sql new file mode 100644 index 000000000000..f8afe63efe3d --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_arithmetic.sql @@ -0,0 +1,127 @@ +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/decimal_arithmetic.test + +-- negate + +SELECT -('0.1'::DECIMAL), -('-0.1'::DECIMAL); + +-- unary + + +SELECT +('0.1'::DECIMAL), +('-0.1'::DECIMAL); + +-- addition + +SELECT '0.1'::DECIMAL + '0.1'::DECIMAL; + +-- addition with non-decimal + +SELECT '0.1'::DECIMAL + 1::INTEGER; + +SELECT '0.5'::DECIMAL(4,4) + '0.5'::DECIMAL(4,4); + +-- addition between different decimal types + +SELECT '0.5'::DECIMAL(1,1) + '100.0'::DECIMAL(3,0); + +-- test decimals and integers with big decimals + +SELECT ('0.5'::DECIMAL(1,1) + 10000)::VARCHAR, + ('0.54321'::DECIMAL(5,5) + 10000)::VARCHAR, + ('0.5432154321'::DECIMAL(10,10) + 10000)::VARCHAR, + ('0.543215432154321'::DECIMAL(15,15) + 10000::DECIMAL(20,15))::VARCHAR, + ('0.54321543215432154321'::DECIMAL(20,20) + 10000)::VARCHAR, + ('0.5432154321543215432154321'::DECIMAL(25,25) + 10000)::VARCHAR; + +-- out of range + +SELECT ('0.54321543215432154321543215432154321'::DECIMAL(35,35) + 10000)::VARCHAR; + +-- different types + +SELECT '0.5'::DECIMAL(1,1) + 1::TINYINT, + '0.5'::DECIMAL(1,1) + 2::SMALLINT, + '0.5'::DECIMAL(1,1) + 3::INTEGER, + '0.5'::DECIMAL(1,1) + 4::BIGINT; + +-- negative numbers + +SELECT '0.5'::DECIMAL(1,1) + -1::TINYINT, + '0.5'::DECIMAL(1,1) + -2::SMALLINT, + '0.5'::DECIMAL(1,1) + -3::INTEGER, + '0.5'::DECIMAL(1,1) + -4::BIGINT; + +-- subtract + +SELECT '0.5'::DECIMAL(1,1) - 1::TINYINT, + '0.5'::DECIMAL(1,1) - 2::SMALLINT, + '0.5'::DECIMAL(1,1) - 3::INTEGER, + '0.5'::DECIMAL(1,1) - 4::BIGINT; + +-- negative numbers + +SELECT '0.5'::DECIMAL(1,1) - -1::TINYINT, + '0.5'::DECIMAL(1,1) - -2::SMALLINT, + '0.5'::DECIMAL(1,1) - -3::INTEGER, + '0.5'::DECIMAL(1,1) - -4::BIGINT; + + +-- now with a table + +CREATE TABLE decimals(d DECIMAL(3, 2), ts timestamp time index); + +INSERT INTO decimals VALUES ('0.1',1000), ('0.2',1000); + +SELECT * FROM decimals; + +SELECT d + 10000 FROM decimals; + +SELECT d + '0.1'::DECIMAL, d + 10000 FROM decimals; + +DROP TABLE decimals; + +-- multiplication + +SELECT '0.1'::DECIMAL * '10.0'::DECIMAL; + +SELECT arrow_typeof('0.1'::DECIMAL(2,1) * '10.0'::DECIMAL(3,1)); + +SELECT '0.1'::DECIMAL * '0.1'::DECIMAL; + +-- multiplication with non-decimal + +SELECT '0.1'::DECIMAL * 10::INTEGER; + +SELECT '5.0'::DECIMAL(4,3) * '5.0'::DECIMAL(4,3); + +-- negative multiplication + +SELECT '-5.0'::DECIMAL(4,3) * '5.0'::DECIMAL(4,3); + +-- no precision is lost + +SELECT ('18.25'::DECIMAL(4,2) * '17.25'::DECIMAL(4,2))::VARCHAR; + +-- different types + +SELECT '0.001'::DECIMAL * 100::TINYINT, + '0.001'::DECIMAL * 10000::SMALLINT, + '0.001'::DECIMAL * 1000000::INTEGER, + '0.001'::DECIMAL * 100000000::BIGINT; + +-- multiplication could not be performed exactly: throw error + +SELECT '0.000000000000000000000000000001'::DECIMAL(38,30) * '0.000000000000000000000000000001'::DECIMAL(38,30); + +-- test addition, subtraction and multiplication with various scales and precisions + +SELECT 2.0 + 1.0 as col1, + 2.0000 + 1.0000 as col2, + 2.000000000000 + 1.000000000000 as col3, + 2.00000000000000000000 + 1.00000000000000000000 as col4; + +SELECT 2.0 - 1.0 as col1, + 2.0000 - 1.0000 as col2, + 2.000000000000 - 1.000000000000 as col3, + 2.00000000000000000000 - 1.00000000000000000000 as col4; + +SELECT 2.0 * 1.0 as col1, + 2.0000 * 1.0000 as col2; diff --git a/tests/cases/standalone/common/types/decimal/decimal_cast.result b/tests/cases/standalone/common/types/decimal/decimal_cast.result new file mode 100644 index 000000000000..0e8de7db6700 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_cast.result @@ -0,0 +1,496 @@ +-- Test casting from decimal to other types +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/cast_from_decimal.test +-- and https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/cast_to_decimal.test +-- tinyint +SELECT 127::DECIMAL(3,0)::TINYINT, -127::DECIMAL(3,0)::TINYINT, -7::DECIMAL(9,1)::TINYINT, 27::DECIMAL(18,1)::TINYINT, 33::DECIMAL(38,1)::TINYINT; + ++------------+----------------+--------------+-----------+-----------+ +| Int64(127) | (- Int64(127)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+----------------+--------------+-----------+-----------+ +| 127 | -127 | -7 | 27 | 33 | ++------------+----------------+--------------+-----------+-----------+ + +SELECT 128::DECIMAL(3,0)::TINYINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 128 is out of range Int8 + +SELECT -128::DECIMAL(9,0)::TINYINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 128 is out of range Int8 + +SELECT 128::DECIMAL(18,0)::TINYINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 128 is out of range Int8 + +SELECT 14751947891758972421513::DECIMAL(38,0)::TINYINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 14751947891758971486208 is out of range Int8 + +-- smallint +SELECT 127::DECIMAL(3,0)::SMALLINT, -32767::DECIMAL(5,0)::SMALLINT, -7::DECIMAL(9,1)::SMALLINT, 27::DECIMAL(18,1)::SMALLINT, 33::DECIMAL(38,1)::SMALLINT; + ++------------+------------------+--------------+-----------+-----------+ +| Int64(127) | (- Int64(32767)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+------------------+--------------+-----------+-----------+ +| 127 | -32767 | -7 | 27 | 33 | ++------------+------------------+--------------+-----------+-----------+ + +SELECT -32768::DECIMAL(9,0)::SMALLINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 32768 is out of range Int16 + +SELECT 32768::DECIMAL(18,0)::SMALLINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 32768 is out of range Int16 + +SELECT 14751947891758972421513::DECIMAL(38,0)::SMALLINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 14751947891758971486208 is out of range Int16 + +-- integer +SELECT 127::DECIMAL(3,0)::INTEGER, -2147483647::DECIMAL(10,0)::INTEGER, -7::DECIMAL(9,1)::INTEGER, 27::DECIMAL(18,1)::INTEGER, 33::DECIMAL(38,1)::INTEGER; + ++------------+-----------------------+--------------+-----------+-----------+ +| Int64(127) | (- Int64(2147483647)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+-----------------------+--------------+-----------+-----------+ +| 127 | -2147483647 | -7 | 27 | 33 | ++------------+-----------------------+--------------+-----------+-----------+ + +SELECT 2147483648::DECIMAL(18,0)::INTEGER; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 2147483648 is out of range Int32 + +SELECT 14751947891758972421513::DECIMAL(38,0)::INTEGER; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 14751947891758971486208 is out of range Int32 + +-- bigint +SELECT 127::DECIMAL(3,0)::BIGINT, -9223372036854775807::DECIMAL(19,0)::BIGINT, -7::DECIMAL(9,1)::BIGINT, 27::DECIMAL(18,1)::BIGINT, 33::DECIMAL(38,1)::BIGINT; + ++------------+--------------------------------+--------------+-----------+-----------+ +| Int64(127) | (- Int64(9223372036854775807)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+--------------------------------+--------------+-----------+-----------+ +| 127 | -9223372036854775807 | -7 | 27 | 33 | ++------------+--------------------------------+--------------+-----------+-----------+ + +SELECT 14751947891758972421513::DECIMAL(38,0)::BIGINT; + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: value of 14751947891758971486208 is out of range Int64 + +-- float +SELECT 127::DECIMAL(3,0)::FLOAT, -17014118346046923173168730371588410572::DECIMAL(38,0)::FLOAT, -7::DECIMAL(9,1)::FLOAT, 27::DECIMAL(18,1)::FLOAT, 33::DECIMAL(38,1)::FLOAT; + ++------------+-----------------------------------------------------+--------------+-----------+-----------+ +| Int64(127) | (- Float64(17014118346046924000000000000000000000)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+-----------------------------------------------------+--------------+-----------+-----------+ +| 127.0 | -1.7014119e37 | -7.0 | 27.0 | 33.0 | ++------------+-----------------------------------------------------+--------------+-----------+-----------+ + +-- double +SELECT 127::DECIMAL(3,0)::DOUBLE, -17014118346046923173168730371588410572::DECIMAL(38,0)::DOUBLE, -7::DECIMAL(9,1)::DOUBLE, 27::DECIMAL(18,1)::DOUBLE, 33::DECIMAL(38,1)::DOUBLE; + ++------------+-----------------------------------------------------+--------------+-----------+-----------+ +| Int64(127) | (- Float64(17014118346046924000000000000000000000)) | (- Int64(7)) | Int64(27) | Int64(33) | ++------------+-----------------------------------------------------+--------------+-----------+-----------+ +| 127.0 | -1.7014118346046924e37 | -7.0 | 27.0 | 33.0 | ++------------+-----------------------------------------------------+--------------+-----------+-----------+ + +-- Test casting from other types to decimal +-- tinyint +SELECT 100::TINYINT::DECIMAL(18,3), 200::TINYINT::DECIMAL(3,0), (-300)::TINYINT::DECIMAL(3,0), 0::TINYINT::DECIMAL(3,3); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Can't cast value 200 to type Int8 + +SELECT 100::TINYINT::DECIMAL(38,35), 200::TINYINT::DECIMAL(9,6); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Can't cast value 200 to type Int8 + +-- overflow +SELECT 100::TINYINT::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 1::TINYINT::DECIMAL(3,3); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 100::TINYINT::DECIMAL(18,17); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 10000000000000000000 is too large to store in a Decimal128 of precision 18. Max is 999999999999999999 + +SELECT 100::TINYINT::DECIMAL(9,7); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000000000 is too large to store in a Decimal128 of precision 9. Max is 999999999 + +SELECT 100::TINYINT::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Compute error: Overflow happened on: 100 * 10000000000000000000000000000000000000 + +-- smallint +SELECT 100::SMALLINT::DECIMAL(18,3), 200::SMALLINT::DECIMAL(3,0), (-300)::SMALLINT::DECIMAL(3,0), 0::SMALLINT::DECIMAL(3,3); + ++------------+------------+-------------+----------+ +| Int64(100) | Int64(200) | Int64(-300) | Int64(0) | ++------------+------------+-------------+----------+ +| 100.000 | 200 | -300 | 0.000 | ++------------+------------+-------------+----------+ + +SELECT 100::SMALLINT::DECIMAL(38,35), 200::SMALLINT::DECIMAL(9,6); + ++-----------------------------------------+------------+ +| Int64(100) | Int64(200) | ++-----------------------------------------+------------+ +| 100.00000000000000000000000000000000000 | 200.000000 | ++-----------------------------------------+------------+ + +-- overflow +SELECT 100::SMALLINT::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 1::SMALLINT::DECIMAL(3,3); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 100::SMALLINT::DECIMAL(18,17); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 10000000000000000000 is too large to store in a Decimal128 of precision 18. Max is 999999999999999999 + +SELECT 100::SMALLINT::DECIMAL(9,7); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000000000 is too large to store in a Decimal128 of precision 9. Max is 999999999 + +SELECT 100::SMALLINT::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Compute error: Overflow happened on: 100 * 10000000000000000000000000000000000000 + +-- integer +SELECT 100::INTEGER::DECIMAL(18,3), 200::INTEGER::DECIMAL(3,0), (-300)::INTEGER::DECIMAL(3,0), 0::INTEGER::DECIMAL(3,3); + ++------------+------------+-------------+----------+ +| Int64(100) | Int64(200) | Int64(-300) | Int64(0) | ++------------+------------+-------------+----------+ +| 100.000 | 200 | -300 | 0.000 | ++------------+------------+-------------+----------+ + +SELECT 100::INTEGER::DECIMAL(38,35), 200::INTEGER::DECIMAL(9,6), 2147483647::INTEGER::DECIMAL(10,0), (-2147483647)::INTEGER::DECIMAL(10,0); + ++-----------------------------------------+------------+-------------------+--------------------+ +| Int64(100) | Int64(200) | Int64(2147483647) | Int64(-2147483647) | ++-----------------------------------------+------------+-------------------+--------------------+ +| 100.00000000000000000000000000000000000 | 200.000000 | 2147483647 | -2147483647 | ++-----------------------------------------+------------+-------------------+--------------------+ + +-- overflow +SELECT 100::INTEGER::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 10000000::INTEGER::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 100000000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT -10000000::INTEGER::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 100000000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 1::INTEGER::DECIMAL(3,3); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 100::INTEGER::DECIMAL(18,17); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 10000000000000000000 is too large to store in a Decimal128 of precision 18. Max is 999999999999999999 + +SELECT 100::INTEGER::DECIMAL(9,7); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000000000 is too large to store in a Decimal128 of precision 9. Max is 999999999 + +SELECT 100::INTEGER::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Compute error: Overflow happened on: 100 * 10000000000000000000000000000000000000 + +-- bigint +SELECT 100::BIGINT::DECIMAL(18,3), 200::BIGINT::DECIMAL(3,0), (-100)::BIGINT::DECIMAL(3,0), 0::BIGINT::DECIMAL(3,3); + ++------------+------------+-------------+----------+ +| Int64(100) | Int64(200) | Int64(-100) | Int64(0) | ++------------+------------+-------------+----------+ +| 100.000 | 200 | -100 | 0.000 | ++------------+------------+-------------+----------+ + +SELECT 100::BIGINT::DECIMAL(38,35), 200::BIGINT::DECIMAL(9,6), 9223372036854775807::BIGINT::DECIMAL(19,0), (-9223372036854775807)::BIGINT::DECIMAL(19,0); + ++-----------------------------------------+------------+----------------------------+-----------------------------+ +| Int64(100) | Int64(200) | Int64(9223372036854775807) | Int64(-9223372036854775807) | ++-----------------------------------------+------------+----------------------------+-----------------------------+ +| 100.00000000000000000000000000000000000 | 200.000000 | 9223372036854775807 | -9223372036854775807 | ++-----------------------------------------+------------+----------------------------+-----------------------------+ + +SELECT 922337203685477580::BIGINT::DECIMAL(18,0), (-922337203685477580)::BIGINT::DECIMAL(18,0); + ++---------------------------+----------------------------+ +| Int64(922337203685477580) | Int64(-922337203685477580) | ++---------------------------+----------------------------+ +| 922337203685477580 | -922337203685477580 | ++---------------------------+----------------------------+ + +-- overflow +SELECT 100::BIGINT::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 10000000::BIGINT::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 100000000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT -10000000::BIGINT::DECIMAL(3,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 100000000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 1::BIGINT::DECIMAL(3,3); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000 is too large to store in a Decimal128 of precision 3. Max is 999 + +SELECT 100::BIGINT::DECIMAL(18,17); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 10000000000000000000 is too large to store in a Decimal128 of precision 18. Max is 999999999999999999 + +SELECT 100::BIGINT::DECIMAL(9,7); + +Error: 3001(EngineExecuteQuery), DataFusion error: Invalid argument error: 1000000000 is too large to store in a Decimal128 of precision 9. Max is 999999999 + +SELECT 100::BIGINT::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Compute error: Overflow happened on: 100 * 10000000000000000000000000000000000000 + +-- float +SELECT 100::FLOAT::DECIMAL(18,3), 200::FLOAT::DECIMAL(3,0), (-300)::FLOAT::DECIMAL(3,0), 0::FLOAT::DECIMAL(3,3); + ++------------+------------+-------------+----------+ +| Int64(100) | Int64(200) | Int64(-300) | Int64(0) | ++------------+------------+-------------+----------+ +| 100.000 | 200 | -300 | 0.000 | ++------------+------------+-------------+----------+ + +SELECT 100::FLOAT::DECIMAL(38,35)::FLOAT, 200::FLOAT::DECIMAL(9,6)::FLOAT, 17014118346046923173168730371588410572::FLOAT::DECIMAL(38,0)::FLOAT, (-17014118346046923173168730371588410572)::FLOAT::DECIMAL(38,0)::FLOAT; + ++------------+------------+-------------------------------------------------+--------------------------------------------------+ +| Int64(100) | Int64(200) | Float64(17014118346046924000000000000000000000) | Float64(-17014118346046924000000000000000000000) | ++------------+------------+-------------------------------------------------+--------------------------------------------------+ +| 100.0 | 200.0 | 1.7014119e37 | -1.7014119e37 | ++------------+------------+-------------------------------------------------+--------------------------------------------------+ + +SELECT 1.25::FLOAT::DECIMAL(3,2); + ++---------------+ +| Float64(1.25) | ++---------------+ +| 1.25 | ++---------------+ + +-- overflow +SELECT 100::FLOAT::DECIMAL(3,1); + ++------------+ +| Int64(100) | ++------------+ +| 10.0 | ++------------+ + +SELECT 10000000::FLOAT::DECIMAL(3,1); + ++-----------------+ +| Int64(10000000) | ++-----------------+ +| 10.0 | ++-----------------+ + +SELECT -10000000::FLOAT::DECIMAL(3,1); + ++---------------------+ +| (- Int64(10000000)) | ++---------------------+ +| -10.0 | ++---------------------+ + +SELECT 1::FLOAT::DECIMAL(3,3); + ++----------+ +| Int64(1) | ++----------+ +| .100 | ++----------+ + +SELECT 100::FLOAT::DECIMAL(18,17); + ++---------------------+ +| Int64(100) | ++---------------------+ +| 1.00000000000000000 | ++---------------------+ + +SELECT 100::FLOAT::DECIMAL(9,7); + ++------------+ +| Int64(100) | ++------------+ +| 10.0000000 | ++------------+ + +SELECT 100::FLOAT::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Cannot cast to Decimal128(38, 37). Overflowing on 100.0 + +-- Some controversial cases +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(38,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Cannot cast to Decimal128(38, 1). Overflowing on 1.7014119e37 + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(37,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 1701411859957704321881461067092905164 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(18,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 170141185995770432 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(9,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 170141185 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(4,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 1701 | ++-------------------------------------------------+ + +-- double +SELECT 100::DOUBLE::DECIMAL(18,3), 200::DOUBLE::DECIMAL(3,0), (-300)::DOUBLE::DECIMAL(3,0), 0::DOUBLE::DECIMAL(3,3); + ++------------+------------+-------------+----------+ +| Int64(100) | Int64(200) | Int64(-300) | Int64(0) | ++------------+------------+-------------+----------+ +| 100.000 | 200 | -300 | 0.000 | ++------------+------------+-------------+----------+ + +SELECT 100::DOUBLE::DECIMAL(38,35)::DOUBLE, 200::DOUBLE::DECIMAL(9,6)::DOUBLE, 17014118346046923173168730371588410572::DOUBLE::DECIMAL(38,0)::DOUBLE, (-17014118346046923173168730371588410572)::DOUBLE::DECIMAL(38,0)::DOUBLE; + ++------------+------------+-------------------------------------------------+--------------------------------------------------+ +| Int64(100) | Int64(200) | Float64(17014118346046924000000000000000000000) | Float64(-17014118346046924000000000000000000000) | ++------------+------------+-------------------------------------------------+--------------------------------------------------+ +| 100.0 | 200.0 | 1.7014118346046924e37 | -1.7014118346046924e37 | ++------------+------------+-------------------------------------------------+--------------------------------------------------+ + +SELECT 1.25::DOUBLE::DECIMAL(3,2); + ++---------------+ +| Float64(1.25) | ++---------------+ +| 1.25 | ++---------------+ + +-- overflow +SELECT 100::DOUBLE::DECIMAL(3,1); + ++------------+ +| Int64(100) | ++------------+ +| 10.0 | ++------------+ + +SELECT 10000000::DOUBLE::DECIMAL(3,1); + ++-----------------+ +| Int64(10000000) | ++-----------------+ +| 10.0 | ++-----------------+ + +SELECT -10000000::DOUBLE::DECIMAL(3,1); + ++---------------------+ +| (- Int64(10000000)) | ++---------------------+ +| -10.0 | ++---------------------+ + +SELECT 1::DOUBLE::DECIMAL(3,3); + ++----------+ +| Int64(1) | ++----------+ +| .100 | ++----------+ + +SELECT 100::DOUBLE::DECIMAL(18,17); + ++---------------------+ +| Int64(100) | ++---------------------+ +| 1.00000000000000000 | ++---------------------+ + +SELECT 100::DOUBLE::DECIMAL(9,7); + ++------------+ +| Int64(100) | ++------------+ +| 10.0000000 | ++------------+ + +SELECT 100::DOUBLE::DECIMAL(38,37); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Cannot cast to Decimal128(38, 37). Overflowing on 100.0 + +-- Some controversial cases +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(38,1); + +Error: 3001(EngineExecuteQuery), DataFusion error: Cast error: Cannot cast to Decimal128(38, 1). Overflowing on 1.7014118346046924e37 + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(37,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 1701411834604692411764202694551745331 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(18,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 170141183460469241 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(9,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 170141183 | ++-------------------------------------------------+ + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(4,0); + ++-------------------------------------------------+ +| Float64(17014118346046924000000000000000000000) | ++-------------------------------------------------+ +| 1701 | ++-------------------------------------------------+ + diff --git a/tests/cases/standalone/common/types/decimal/decimal_cast.sql b/tests/cases/standalone/common/types/decimal/decimal_cast.sql new file mode 100644 index 000000000000..90d846b1c42a --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_cast.sql @@ -0,0 +1,203 @@ +-- Test casting from decimal to other types +-- Port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/cast_from_decimal.test +-- and https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/cast_to_decimal.test + +-- tinyint +SELECT 127::DECIMAL(3,0)::TINYINT, -127::DECIMAL(3,0)::TINYINT, -7::DECIMAL(9,1)::TINYINT, 27::DECIMAL(18,1)::TINYINT, 33::DECIMAL(38,1)::TINYINT; + +SELECT 128::DECIMAL(3,0)::TINYINT; + +SELECT -128::DECIMAL(9,0)::TINYINT; + +SELECT 128::DECIMAL(18,0)::TINYINT; + +SELECT 14751947891758972421513::DECIMAL(38,0)::TINYINT; + +-- smallint + +SELECT 127::DECIMAL(3,0)::SMALLINT, -32767::DECIMAL(5,0)::SMALLINT, -7::DECIMAL(9,1)::SMALLINT, 27::DECIMAL(18,1)::SMALLINT, 33::DECIMAL(38,1)::SMALLINT; + +SELECT -32768::DECIMAL(9,0)::SMALLINT; + +SELECT 32768::DECIMAL(18,0)::SMALLINT; + +SELECT 14751947891758972421513::DECIMAL(38,0)::SMALLINT; + +-- integer + +SELECT 127::DECIMAL(3,0)::INTEGER, -2147483647::DECIMAL(10,0)::INTEGER, -7::DECIMAL(9,1)::INTEGER, 27::DECIMAL(18,1)::INTEGER, 33::DECIMAL(38,1)::INTEGER; + +SELECT 2147483648::DECIMAL(18,0)::INTEGER; + +SELECT 14751947891758972421513::DECIMAL(38,0)::INTEGER; + +-- bigint + +SELECT 127::DECIMAL(3,0)::BIGINT, -9223372036854775807::DECIMAL(19,0)::BIGINT, -7::DECIMAL(9,1)::BIGINT, 27::DECIMAL(18,1)::BIGINT, 33::DECIMAL(38,1)::BIGINT; + +SELECT 14751947891758972421513::DECIMAL(38,0)::BIGINT; + +-- float + +SELECT 127::DECIMAL(3,0)::FLOAT, -17014118346046923173168730371588410572::DECIMAL(38,0)::FLOAT, -7::DECIMAL(9,1)::FLOAT, 27::DECIMAL(18,1)::FLOAT, 33::DECIMAL(38,1)::FLOAT; + +-- double + +SELECT 127::DECIMAL(3,0)::DOUBLE, -17014118346046923173168730371588410572::DECIMAL(38,0)::DOUBLE, -7::DECIMAL(9,1)::DOUBLE, 27::DECIMAL(18,1)::DOUBLE, 33::DECIMAL(38,1)::DOUBLE; + + +-- Test casting from other types to decimal + +-- tinyint + +SELECT 100::TINYINT::DECIMAL(18,3), 200::TINYINT::DECIMAL(3,0), (-300)::TINYINT::DECIMAL(3,0), 0::TINYINT::DECIMAL(3,3); + +SELECT 100::TINYINT::DECIMAL(38,35), 200::TINYINT::DECIMAL(9,6); + +-- overflow + +SELECT 100::TINYINT::DECIMAL(3,1); + +SELECT 1::TINYINT::DECIMAL(3,3); + +SELECT 100::TINYINT::DECIMAL(18,17); + +SELECT 100::TINYINT::DECIMAL(9,7); + +SELECT 100::TINYINT::DECIMAL(38,37); + +-- smallint + +SELECT 100::SMALLINT::DECIMAL(18,3), 200::SMALLINT::DECIMAL(3,0), (-300)::SMALLINT::DECIMAL(3,0), 0::SMALLINT::DECIMAL(3,3); + +SELECT 100::SMALLINT::DECIMAL(38,35), 200::SMALLINT::DECIMAL(9,6); + +-- overflow + +SELECT 100::SMALLINT::DECIMAL(3,1); + +SELECT 1::SMALLINT::DECIMAL(3,3); + +SELECT 100::SMALLINT::DECIMAL(18,17); + +SELECT 100::SMALLINT::DECIMAL(9,7); + +SELECT 100::SMALLINT::DECIMAL(38,37); + +-- integer + +SELECT 100::INTEGER::DECIMAL(18,3), 200::INTEGER::DECIMAL(3,0), (-300)::INTEGER::DECIMAL(3,0), 0::INTEGER::DECIMAL(3,3); + +SELECT 100::INTEGER::DECIMAL(38,35), 200::INTEGER::DECIMAL(9,6), 2147483647::INTEGER::DECIMAL(10,0), (-2147483647)::INTEGER::DECIMAL(10,0); + +-- overflow + +SELECT 100::INTEGER::DECIMAL(3,1); + +SELECT 10000000::INTEGER::DECIMAL(3,1); + +SELECT -10000000::INTEGER::DECIMAL(3,1); + +SELECT 1::INTEGER::DECIMAL(3,3); + +SELECT 100::INTEGER::DECIMAL(18,17); + +SELECT 100::INTEGER::DECIMAL(9,7); + +SELECT 100::INTEGER::DECIMAL(38,37); + +-- bigint + +SELECT 100::BIGINT::DECIMAL(18,3), 200::BIGINT::DECIMAL(3,0), (-100)::BIGINT::DECIMAL(3,0), 0::BIGINT::DECIMAL(3,3); + +SELECT 100::BIGINT::DECIMAL(38,35), 200::BIGINT::DECIMAL(9,6), 9223372036854775807::BIGINT::DECIMAL(19,0), (-9223372036854775807)::BIGINT::DECIMAL(19,0); + +SELECT 922337203685477580::BIGINT::DECIMAL(18,0), (-922337203685477580)::BIGINT::DECIMAL(18,0); + +-- overflow + +SELECT 100::BIGINT::DECIMAL(3,1); + +SELECT 10000000::BIGINT::DECIMAL(3,1); + +SELECT -10000000::BIGINT::DECIMAL(3,1); + +SELECT 1::BIGINT::DECIMAL(3,3); + +SELECT 100::BIGINT::DECIMAL(18,17); + +SELECT 100::BIGINT::DECIMAL(9,7); + +SELECT 100::BIGINT::DECIMAL(38,37); + +-- float + +SELECT 100::FLOAT::DECIMAL(18,3), 200::FLOAT::DECIMAL(3,0), (-300)::FLOAT::DECIMAL(3,0), 0::FLOAT::DECIMAL(3,3); + +SELECT 100::FLOAT::DECIMAL(38,35)::FLOAT, 200::FLOAT::DECIMAL(9,6)::FLOAT, 17014118346046923173168730371588410572::FLOAT::DECIMAL(38,0)::FLOAT, (-17014118346046923173168730371588410572)::FLOAT::DECIMAL(38,0)::FLOAT; + +SELECT 1.25::FLOAT::DECIMAL(3,2); + +-- overflow + +SELECT 100::FLOAT::DECIMAL(3,1); + +SELECT 10000000::FLOAT::DECIMAL(3,1); + +SELECT -10000000::FLOAT::DECIMAL(3,1); + +SELECT 1::FLOAT::DECIMAL(3,3); + +SELECT 100::FLOAT::DECIMAL(18,17); + +SELECT 100::FLOAT::DECIMAL(9,7); + +SELECT 100::FLOAT::DECIMAL(38,37); + +-- Some controversial cases + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(38,1); + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(37,0); + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(18,0); + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(9,0); + +SELECT 17014118346046923173168730371588410572::FLOAT::DECIMAL(4,0); + +-- double + +SELECT 100::DOUBLE::DECIMAL(18,3), 200::DOUBLE::DECIMAL(3,0), (-300)::DOUBLE::DECIMAL(3,0), 0::DOUBLE::DECIMAL(3,3); + +SELECT 100::DOUBLE::DECIMAL(38,35)::DOUBLE, 200::DOUBLE::DECIMAL(9,6)::DOUBLE, 17014118346046923173168730371588410572::DOUBLE::DECIMAL(38,0)::DOUBLE, (-17014118346046923173168730371588410572)::DOUBLE::DECIMAL(38,0)::DOUBLE; + +SELECT 1.25::DOUBLE::DECIMAL(3,2); + +-- overflow + +SELECT 100::DOUBLE::DECIMAL(3,1); + +SELECT 10000000::DOUBLE::DECIMAL(3,1); + +SELECT -10000000::DOUBLE::DECIMAL(3,1); + +SELECT 1::DOUBLE::DECIMAL(3,3); + +SELECT 100::DOUBLE::DECIMAL(18,17); + +SELECT 100::DOUBLE::DECIMAL(9,7); + +SELECT 100::DOUBLE::DECIMAL(38,37); + +-- Some controversial cases + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(38,1); + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(37,0); + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(18,0); + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(9,0); + +SELECT 17014118346046923173168730371588410572::DOUBLE::DECIMAL(4,0); diff --git a/tests/cases/standalone/common/types/decimal/decimal_ops.result b/tests/cases/standalone/common/types/decimal/decimal_ops.result new file mode 100644 index 000000000000..c1bc4a082eaa --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_ops.result @@ -0,0 +1,436 @@ +-- Some cases port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/test_decimal_ops.test +CREATE TABLE decimals(d DECIMAL(3, 2), ts timestamp time index); + +Affected Rows: 0 + +INSERT INTO decimals VALUES ('0.1',1000), ('0.2',2000); + +Affected Rows: 2 + +SELECT * FROM decimals; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | +| 0.20 | 1970-01-01T00:00:02 | ++------+---------------------+ + +-- ORDER BY +SELECT * FROM decimals ORDER BY d DESC; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.20 | 1970-01-01T00:00:02 | +| 0.10 | 1970-01-01T00:00:01 | ++------+---------------------+ + +-- equality +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(3,2); + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | ++------+---------------------+ + +-- greater than equals +SELECT * FROM decimals WHERE d >= '0.1'::DECIMAL(3,2); + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | +| 0.20 | 1970-01-01T00:00:02 | ++------+---------------------+ + +-- what about if we use different decimal scales? +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(9,5); + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | ++------+---------------------+ + +SELECT * FROM decimals WHERE d >= '0.1'::DECIMAL(9,5) ORDER BY 1; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | +| 0.20 | 1970-01-01T00:00:02 | ++------+---------------------+ + +-- what if we compare decimals with different scales and width (3,2) vs (9,1) +INSERT INTO decimals VALUES ('0.11',3000), ('0.21',4000); + +Affected Rows: 2 + +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(9,1); + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | ++------+---------------------+ + +SELECT * FROM decimals WHERE d > '0.1'::DECIMAL(9,1) ORDER BY 1; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.11 | 1970-01-01T00:00:03 | +| 0.20 | 1970-01-01T00:00:02 | +| 0.21 | 1970-01-01T00:00:04 | ++------+---------------------+ + +DELETE FROM decimals WHERE d <> d::DECIMAL(9,1); + +Affected Rows: 2 + +SELECT * FROM decimals; + ++------+---------------------+ +| d | ts | ++------+---------------------+ +| 0.10 | 1970-01-01T00:00:01 | +| 0.20 | 1970-01-01T00:00:02 | ++------+---------------------+ + +-- test ABS function +SELECT ABS('-0.1'::DECIMAL), ABS('0.1'::DECIMAL), ABS(NULL::DECIMAL); + ++-------------------+------------------+-----------+ +| abs(Utf8("-0.1")) | abs(Utf8("0.1")) | abs(NULL) | ++-------------------+------------------+-----------+ +| 0.1000000000 | 0.1000000000 | | ++-------------------+------------------+-----------+ + +SELECT ABS('-0.1'::DECIMAL(4,3)) AS col1, ABS('-0.1'::DECIMAL(9,3)) AS col2, ABS('-0.1'::DECIMAL(18,3)) AS col3, ABS('-0.1'::DECIMAL(38,3)) AS col4; + ++-------+-------+-------+-------+ +| col1 | col2 | col3 | col4 | ++-------+-------+-------+-------+ +| 0.100 | 0.100 | 0.100 | 0.100 | ++-------+-------+-------+-------+ + +-- test CEIL function +SELECT CEIL('0.1'::DECIMAL), CEIL('-0.1'::DECIMAL), CEIL(NULL::DECIMAL); + ++-------------------+--------------------+------------+ +| ceil(Utf8("0.1")) | ceil(Utf8("-0.1")) | ceil(NULL) | ++-------------------+--------------------+------------+ +| 1.0 | 0.0 | | ++-------------------+--------------------+------------+ + +SELECT CEIL('100.3'::DECIMAL), CEIL('-127012.3'::DECIMAL); + ++---------------------+-------------------------+ +| ceil(Utf8("100.3")) | ceil(Utf8("-127012.3")) | ++---------------------+-------------------------+ +| 101.0 | -127012.0 | ++---------------------+-------------------------+ + +SELECT CEIL('10.5'::DECIMAL), CEIL('-10.5'::DECIMAL); + ++--------------------+---------------------+ +| ceil(Utf8("10.5")) | ceil(Utf8("-10.5")) | ++--------------------+---------------------+ +| 11.0 | -10.0 | ++--------------------+---------------------+ + +-- ceil function on the boundaries +SELECT CEIL('999.9'::DECIMAL(4,1)), CEIL('99999999.9'::DECIMAL(9,1)), CEIL('99999999999999999.9'::DECIMAL(18,1)), CEIL('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++---------------------+--------------------------+-----------------------------------+-------------------------------------------------------+ +| ceil(Utf8("999.9")) | ceil(Utf8("99999999.9")) | ceil(Utf8("99999999999999999.9")) | ceil(Utf8("9999999999999999999999999999999999999.9")) | ++---------------------+--------------------------+-----------------------------------+-------------------------------------------------------+ +| 1000.0 | 100000000.0 | 1.0e17 | 1.0e37 | ++---------------------+--------------------------+-----------------------------------+-------------------------------------------------------+ + +SELECT CEIL('-999.9'::DECIMAL(4,1)), CEIL('-99999999.9'::DECIMAL(9,1)), CEIL('-99999999999999999.9'::DECIMAL(18,1)), CEIL('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| ceil(Utf8("-999.9")) | ceil(Utf8("-99999999.9")) | ceil(Utf8("-99999999999999999.9")) | ceil(Utf8("-9999999999999999999999999999999999999.9")) | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| -999.0 | -99999999.0 | -1.0e17 | -1.0e37 | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ + +-- test FLOOR function +SELECT FLOOR('0.1'::DECIMAL), FLOOR('-0.1'::DECIMAL), FLOOR(NULL::DECIMAL); + ++--------------------+---------------------+-------------+ +| floor(Utf8("0.1")) | floor(Utf8("-0.1")) | floor(NULL) | ++--------------------+---------------------+-------------+ +| 0.0 | -1.0 | | ++--------------------+---------------------+-------------+ + +SELECT FLOOR('100.3'::DECIMAL), FLOOR('-127012.3'::DECIMAL); + ++----------------------+--------------------------+ +| floor(Utf8("100.3")) | floor(Utf8("-127012.3")) | ++----------------------+--------------------------+ +| 100.0 | -127013.0 | ++----------------------+--------------------------+ + +SELECT FLOOR('10.5'::DECIMAL), FLOOR('-10.5'::DECIMAL); + ++---------------------+----------------------+ +| floor(Utf8("10.5")) | floor(Utf8("-10.5")) | ++---------------------+----------------------+ +| 10.0 | -11.0 | ++---------------------+----------------------+ + +-- floor function on the boundaries +SELECT FLOOR('999.9'::DECIMAL(4,1)), FLOOR('99999999.9'::DECIMAL(9,1)), FLOOR('99999999999999999.9'::DECIMAL(18,1)), FLOOR('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| floor(Utf8("999.9")) | floor(Utf8("99999999.9")) | floor(Utf8("99999999999999999.9")) | floor(Utf8("9999999999999999999999999999999999999.9")) | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| 999.0 | 99999999.0 | 1.0e17 | 1.0e37 | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ + +SELECT FLOOR('-999.9'::DECIMAL(4,1)), FLOOR('-99999999.9'::DECIMAL(9,1)), FLOOR('-99999999999999999.9'::DECIMAL(18,1)), FLOOR('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ +| floor(Utf8("-999.9")) | floor(Utf8("-99999999.9")) | floor(Utf8("-99999999999999999.9")) | floor(Utf8("-9999999999999999999999999999999999999.9")) | ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ +| -1000.0 | -100000000.0 | -1.0e17 | -1.0e37 | ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ + +-- test unary ROUND function +SELECT ROUND('0.1'::DECIMAL), ROUND('-0.1'::DECIMAL), ROUND(NULL::DECIMAL); + ++--------------------+---------------------+-------------+ +| round(Utf8("0.1")) | round(Utf8("-0.1")) | round(NULL) | ++--------------------+---------------------+-------------+ +| 0.0 | 0.0 | | ++--------------------+---------------------+-------------+ + +SELECT ROUND('100.3'::DECIMAL), ROUND('-127012.3'::DECIMAL); + ++----------------------+--------------------------+ +| round(Utf8("100.3")) | round(Utf8("-127012.3")) | ++----------------------+--------------------------+ +| 100.0 | -127012.0 | ++----------------------+--------------------------+ + +SELECT ROUND('10.5'::DECIMAL), ROUND('-10.5'::DECIMAL); + ++---------------------+----------------------+ +| round(Utf8("10.5")) | round(Utf8("-10.5")) | ++---------------------+----------------------+ +| 11.0 | -11.0 | ++---------------------+----------------------+ + +-- round function on the boundaries +SELECT ROUND('999.9'::DECIMAL(4,1)), ROUND('99999999.9'::DECIMAL(9,1)), ROUND('99999999999999999.9'::DECIMAL(18,1)), ROUND('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| round(Utf8("999.9")) | round(Utf8("99999999.9")) | round(Utf8("99999999999999999.9")) | round(Utf8("9999999999999999999999999999999999999.9")) | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ +| 1000.0 | 100000000.0 | 1.0e17 | 1.0e37 | ++----------------------+---------------------------+------------------------------------+--------------------------------------------------------+ + +SELECT ROUND('-999.9'::DECIMAL(4,1)), ROUND('-99999999.9'::DECIMAL(9,1)), ROUND('-99999999999999999.9'::DECIMAL(18,1)), ROUND('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ +| round(Utf8("-999.9")) | round(Utf8("-99999999.9")) | round(Utf8("-99999999999999999.9")) | round(Utf8("-9999999999999999999999999999999999999.9")) | ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ +| -1000.0 | -100000000.0 | -1.0e17 | -1.0e37 | ++-----------------------+----------------------------+-------------------------------------+---------------------------------------------------------+ + +-- round with precision +SELECT ROUND('100.3908147521'::DECIMAL(18,10), 0)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 1)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 2)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 3)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 4)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 5)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 6)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 7)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 8)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 9)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 10)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 100000)::VARCHAR, + ROUND(NULL::DECIMAL, 0); + ++----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+-----------------------------------------+---------------------------------------------+----------------------+ +| round(Utf8("100.3908147521"),Int64(0)) | round(Utf8("100.3908147521"),Int64(1)) | round(Utf8("100.3908147521"),Int64(2)) | round(Utf8("100.3908147521"),Int64(3)) | round(Utf8("100.3908147521"),Int64(4)) | round(Utf8("100.3908147521"),Int64(5)) | round(Utf8("100.3908147521"),Int64(6)) | round(Utf8("100.3908147521"),Int64(7)) | round(Utf8("100.3908147521"),Int64(8)) | round(Utf8("100.3908147521"),Int64(9)) | round(Utf8("100.3908147521"),Int64(10)) | round(Utf8("100.3908147521"),Int64(100000)) | round(NULL,Int64(0)) | ++----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+-----------------------------------------+---------------------------------------------+----------------------+ +| 100.0 | 100.4 | 100.39 | 100.391 | 100.3908 | 100.39081 | 100.390815 | 100.3908148 | 100.39081475 | 100.390814752 | 100.3908147521 | NaN | | ++----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+-----------------------------------------+---------------------------------------------+----------------------+ + +-- negative precision +SELECT ROUND('1049578239572094512.32415'::DECIMAL(30,10), 0)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -1)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -2)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -3)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -4)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -5)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -6)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -7)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -8)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -9)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -10)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -11)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -12)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -13)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -14)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -15)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -16)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -18)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -19)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -20)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -19842)::VARCHAR; + ++---------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------------+ +| round(Utf8("1049578239572094512.32415"),Int64(0)) | round(Utf8("1049578239572094512.32415"),Int64(-1)) | round(Utf8("1049578239572094512.32415"),Int64(-2)) | round(Utf8("1049578239572094512.32415"),Int64(-3)) | round(Utf8("1049578239572094512.32415"),Int64(-4)) | round(Utf8("1049578239572094512.32415"),Int64(-5)) | round(Utf8("1049578239572094512.32415"),Int64(-6)) | round(Utf8("1049578239572094512.32415"),Int64(-7)) | round(Utf8("1049578239572094512.32415"),Int64(-8)) | round(Utf8("1049578239572094512.32415"),Int64(-9)) | round(Utf8("1049578239572094512.32415"),Int64(-10)) | round(Utf8("1049578239572094512.32415"),Int64(-11)) | round(Utf8("1049578239572094512.32415"),Int64(-12)) | round(Utf8("1049578239572094512.32415"),Int64(-13)) | round(Utf8("1049578239572094512.32415"),Int64(-14)) | round(Utf8("1049578239572094512.32415"),Int64(-15)) | round(Utf8("1049578239572094512.32415"),Int64(-16)) | round(Utf8("1049578239572094512.32415"),Int64(-18)) | round(Utf8("1049578239572094512.32415"),Int64(-19)) | round(Utf8("1049578239572094512.32415"),Int64(-20)) | round(Utf8("1049578239572094512.32415"),Int64(-19842)) | ++---------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------------+ +| 1.0495782395720946e18 | 1.0495782395720947e18 | 1.0495782395720946e18 | 1.049578239572095e18 | 1.04957823957209e18 | 1.0495782395721e18 | 1.049578239572e18 | 1.04957823957e18 | 1.0495782396e18 | 1.0495782399999999e18 | 1.04957824e18 | 1.0495782e18 | 1.049578e18 | 1.04958e18 | 1.0496e18 | 1.0499999999999999e18 | 1.05e18 | 9.999999999999999e17 | 0.0 | 0.0 | NaN | ++---------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------------------------------------------------+ + +-- negative values +SELECT ROUND('-100.3908147521'::DECIMAL(18,10), 0)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 1)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 2)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 3)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 4)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 5)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 6)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 7)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 8)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 9)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 10)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 100000)::VARCHAR, + ROUND(NULL::DECIMAL, 0); + ++-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+------------------------------------------+----------------------------------------------+----------------------+ +| round(Utf8("-100.3908147521"),Int64(0)) | round(Utf8("-100.3908147521"),Int64(1)) | round(Utf8("-100.3908147521"),Int64(2)) | round(Utf8("-100.3908147521"),Int64(3)) | round(Utf8("-100.3908147521"),Int64(4)) | round(Utf8("-100.3908147521"),Int64(5)) | round(Utf8("-100.3908147521"),Int64(6)) | round(Utf8("-100.3908147521"),Int64(7)) | round(Utf8("-100.3908147521"),Int64(8)) | round(Utf8("-100.3908147521"),Int64(9)) | round(Utf8("-100.3908147521"),Int64(10)) | round(Utf8("-100.3908147521"),Int64(100000)) | round(NULL,Int64(0)) | ++-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+------------------------------------------+----------------------------------------------+----------------------+ +| -100.0 | -100.4 | -100.39 | -100.391 | -100.3908 | -100.39081 | -100.390815 | -100.3908148 | -100.39081475 | -100.390814752 | -100.3908147521 | NaN | | ++-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+-----------------------------------------+------------------------------------------+----------------------------------------------+----------------------+ + +SELECT ROUND('-1049578239572094512.32415'::DECIMAL(30,10), 0)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -1)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -2)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -3)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -4)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -5)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -6)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -7)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -8)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -9)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -10)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -11)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -12)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -13)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -14)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -15)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -16)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -18)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -19)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -20)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -19842)::VARCHAR; + ++----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+---------------------------------------------------------+ +| round(Utf8("-1049578239572094512.32415"),Int64(0)) | round(Utf8("-1049578239572094512.32415"),Int64(-1)) | round(Utf8("-1049578239572094512.32415"),Int64(-2)) | round(Utf8("-1049578239572094512.32415"),Int64(-3)) | round(Utf8("-1049578239572094512.32415"),Int64(-4)) | round(Utf8("-1049578239572094512.32415"),Int64(-5)) | round(Utf8("-1049578239572094512.32415"),Int64(-6)) | round(Utf8("-1049578239572094512.32415"),Int64(-7)) | round(Utf8("-1049578239572094512.32415"),Int64(-8)) | round(Utf8("-1049578239572094512.32415"),Int64(-9)) | round(Utf8("-1049578239572094512.32415"),Int64(-10)) | round(Utf8("-1049578239572094512.32415"),Int64(-11)) | round(Utf8("-1049578239572094512.32415"),Int64(-12)) | round(Utf8("-1049578239572094512.32415"),Int64(-13)) | round(Utf8("-1049578239572094512.32415"),Int64(-14)) | round(Utf8("-1049578239572094512.32415"),Int64(-15)) | round(Utf8("-1049578239572094512.32415"),Int64(-16)) | round(Utf8("-1049578239572094512.32415"),Int64(-18)) | round(Utf8("-1049578239572094512.32415"),Int64(-19)) | round(Utf8("-1049578239572094512.32415"),Int64(-20)) | round(Utf8("-1049578239572094512.32415"),Int64(-19842)) | ++----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+---------------------------------------------------------+ +| -1.0495782395720946e18 | -1.0495782395720947e18 | -1.0495782395720946e18 | -1.049578239572095e18 | -1.04957823957209e18 | -1.0495782395721e18 | -1.049578239572e18 | -1.04957823957e18 | -1.0495782396e18 | -1.0495782399999999e18 | -1.04957824e18 | -1.0495782e18 | -1.049578e18 | -1.04958e18 | -1.0496e18 | -1.0499999999999999e18 | -1.05e18 | -9.999999999999999e17 | 0.0 | 0.0 | NaN | ++----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+------------------------------------------------------+---------------------------------------------------------+ + +SELECT ROUND(12::DECIMAL(3,0)); + ++------------------+ +| round(Int64(12)) | ++------------------+ +| 12.0 | ++------------------+ + +-- null precision becomes null (postgres behavior) +SELECT ROUND(12::DECIMAL(3,0), NULL); + ++-----------------------+ +| round(Int64(12),NULL) | ++-----------------------+ +| | ++-----------------------+ + +-- different types for ROUND +SELECT ROUND('-100.3'::DECIMAL(4,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(4,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(4,1), -1)::VARCHAR; + ++--------------------------------+-------------------------------+--------------------------------+ +| round(Utf8("-100.3"),Int64(1)) | round(Utf8("104.3"),Int64(0)) | round(Utf8("104.3"),Int64(-1)) | ++--------------------------------+-------------------------------+--------------------------------+ +| -100.3 | 104.0 | 100.0 | ++--------------------------------+-------------------------------+--------------------------------+ + +SELECT ROUND('-100.3'::DECIMAL(9,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(9,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(9,1), -1)::VARCHAR; + ++--------------------------------+-------------------------------+--------------------------------+ +| round(Utf8("-100.3"),Int64(1)) | round(Utf8("104.3"),Int64(0)) | round(Utf8("104.3"),Int64(-1)) | ++--------------------------------+-------------------------------+--------------------------------+ +| -100.3 | 104.0 | 100.0 | ++--------------------------------+-------------------------------+--------------------------------+ + +SELECT ROUND('-100.3'::DECIMAL(18,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(18,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(18,1), -1)::VARCHAR; + ++--------------------------------+-------------------------------+--------------------------------+ +| round(Utf8("-100.3"),Int64(1)) | round(Utf8("104.3"),Int64(0)) | round(Utf8("104.3"),Int64(-1)) | ++--------------------------------+-------------------------------+--------------------------------+ +| -100.3 | 104.0 | 100.0 | ++--------------------------------+-------------------------------+--------------------------------+ + +-- use decimal in sub-query +SELECT (SELECT '1.0'::DECIMAL(2,1)); + ++-------------+ +| Utf8("1.0") | ++-------------+ +| 1.0 | ++-------------+ + +-- test join with decimals +CREATE TABLE tmp_table(i INTEGER, ts timestamp time index); + +Affected Rows: 0 + +INSERT INTO tmp_table VALUES (1, 1000), (2, 2000), (3, 3000); + +Affected Rows: 3 + +SELECT * FROM tmp_table; + ++---+---------------------+ +| i | ts | ++---+---------------------+ +| 1 | 1970-01-01T00:00:01 | +| 2 | 1970-01-01T00:00:02 | +| 3 | 1970-01-01T00:00:03 | ++---+---------------------+ + +SELECT * FROM tmp_table JOIN decimals ON decimals.ts = tmp_table.ts; + ++---+---------------------+------+---------------------+ +| i | ts | d | ts | ++---+---------------------+------+---------------------+ +| 2 | 1970-01-01T00:00:02 | 0.20 | 1970-01-01T00:00:02 | +| 1 | 1970-01-01T00:00:01 | 0.10 | 1970-01-01T00:00:01 | ++---+---------------------+------+---------------------+ + +DROP TABLE decimals; + +Affected Rows: 0 + +DROP TABLE tmp_table; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/types/decimal/decimal_ops.sql b/tests/cases/standalone/common/types/decimal/decimal_ops.sql new file mode 100644 index 000000000000..b28e5748d528 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_ops.sql @@ -0,0 +1,203 @@ +-- Some cases port from https://github.com/duckdb/duckdb/blob/main/test/sql/types/decimal/test_decimal_ops.test + +CREATE TABLE decimals(d DECIMAL(3, 2), ts timestamp time index); + +INSERT INTO decimals VALUES ('0.1',1000), ('0.2',2000); + +SELECT * FROM decimals; + +-- ORDER BY + +SELECT * FROM decimals ORDER BY d DESC; + +-- equality + +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(3,2); + +-- greater than equals + +SELECT * FROM decimals WHERE d >= '0.1'::DECIMAL(3,2); + +-- what about if we use different decimal scales? + +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(9,5); + +SELECT * FROM decimals WHERE d >= '0.1'::DECIMAL(9,5) ORDER BY 1; + +-- what if we compare decimals with different scales and width (3,2) vs (9,1) + +INSERT INTO decimals VALUES ('0.11',3000), ('0.21',4000); + +SELECT * FROM decimals WHERE d = '0.1'::DECIMAL(9,1); + +SELECT * FROM decimals WHERE d > '0.1'::DECIMAL(9,1) ORDER BY 1; + +DELETE FROM decimals WHERE d <> d::DECIMAL(9,1); + +SELECT * FROM decimals; + +-- test ABS function + +SELECT ABS('-0.1'::DECIMAL), ABS('0.1'::DECIMAL), ABS(NULL::DECIMAL); + +SELECT ABS('-0.1'::DECIMAL(4,3)) AS col1, ABS('-0.1'::DECIMAL(9,3)) AS col2, ABS('-0.1'::DECIMAL(18,3)) AS col3, ABS('-0.1'::DECIMAL(38,3)) AS col4; + +-- test CEIL function + +SELECT CEIL('0.1'::DECIMAL), CEIL('-0.1'::DECIMAL), CEIL(NULL::DECIMAL); + +SELECT CEIL('100.3'::DECIMAL), CEIL('-127012.3'::DECIMAL); + +SELECT CEIL('10.5'::DECIMAL), CEIL('-10.5'::DECIMAL); + +-- ceil function on the boundaries + +SELECT CEIL('999.9'::DECIMAL(4,1)), CEIL('99999999.9'::DECIMAL(9,1)), CEIL('99999999999999999.9'::DECIMAL(18,1)), CEIL('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +SELECT CEIL('-999.9'::DECIMAL(4,1)), CEIL('-99999999.9'::DECIMAL(9,1)), CEIL('-99999999999999999.9'::DECIMAL(18,1)), CEIL('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +-- test FLOOR function + +SELECT FLOOR('0.1'::DECIMAL), FLOOR('-0.1'::DECIMAL), FLOOR(NULL::DECIMAL); + +SELECT FLOOR('100.3'::DECIMAL), FLOOR('-127012.3'::DECIMAL); + +SELECT FLOOR('10.5'::DECIMAL), FLOOR('-10.5'::DECIMAL); + +-- floor function on the boundaries + +SELECT FLOOR('999.9'::DECIMAL(4,1)), FLOOR('99999999.9'::DECIMAL(9,1)), FLOOR('99999999999999999.9'::DECIMAL(18,1)), FLOOR('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +SELECT FLOOR('-999.9'::DECIMAL(4,1)), FLOOR('-99999999.9'::DECIMAL(9,1)), FLOOR('-99999999999999999.9'::DECIMAL(18,1)), FLOOR('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +-- test unary ROUND function + +SELECT ROUND('0.1'::DECIMAL), ROUND('-0.1'::DECIMAL), ROUND(NULL::DECIMAL); + +SELECT ROUND('100.3'::DECIMAL), ROUND('-127012.3'::DECIMAL); + +SELECT ROUND('10.5'::DECIMAL), ROUND('-10.5'::DECIMAL); + +-- round function on the boundaries + +SELECT ROUND('999.9'::DECIMAL(4,1)), ROUND('99999999.9'::DECIMAL(9,1)), ROUND('99999999999999999.9'::DECIMAL(18,1)), ROUND('9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +SELECT ROUND('-999.9'::DECIMAL(4,1)), ROUND('-99999999.9'::DECIMAL(9,1)), ROUND('-99999999999999999.9'::DECIMAL(18,1)), ROUND('-9999999999999999999999999999999999999.9'::DECIMAL(38,1)); + +-- round with precision + +SELECT ROUND('100.3908147521'::DECIMAL(18,10), 0)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 1)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 2)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 3)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 4)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 5)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 6)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 7)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 8)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 9)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 10)::VARCHAR, + ROUND('100.3908147521'::DECIMAL(18,10), 100000)::VARCHAR, + ROUND(NULL::DECIMAL, 0); + +-- negative precision + +SELECT ROUND('1049578239572094512.32415'::DECIMAL(30,10), 0)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -1)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -2)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -3)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -4)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -5)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -6)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -7)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -8)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -9)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -10)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -11)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -12)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -13)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -14)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -15)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -16)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -18)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -19)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -20)::VARCHAR, + ROUND('1049578239572094512.32415'::DECIMAL(30,10), -19842)::VARCHAR; + + +-- negative values + +SELECT ROUND('-100.3908147521'::DECIMAL(18,10), 0)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 1)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 2)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 3)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 4)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 5)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 6)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 7)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 8)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 9)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 10)::VARCHAR, + ROUND('-100.3908147521'::DECIMAL(18,10), 100000)::VARCHAR, + ROUND(NULL::DECIMAL, 0); + + +SELECT ROUND('-1049578239572094512.32415'::DECIMAL(30,10), 0)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -1)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -2)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -3)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -4)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -5)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -6)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -7)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -8)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -9)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -10)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -11)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -12)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -13)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -14)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -15)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -16)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -18)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -19)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -20)::VARCHAR, + ROUND('-1049578239572094512.32415'::DECIMAL(30,10), -19842)::VARCHAR; + +SELECT ROUND(12::DECIMAL(3,0)); + +-- null precision becomes null (postgres behavior) + +SELECT ROUND(12::DECIMAL(3,0), NULL); + +-- different types for ROUND + +SELECT ROUND('-100.3'::DECIMAL(4,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(4,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(4,1), -1)::VARCHAR; + +SELECT ROUND('-100.3'::DECIMAL(9,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(9,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(9,1), -1)::VARCHAR; + +SELECT ROUND('-100.3'::DECIMAL(18,1), 1)::VARCHAR, + ROUND('104.3'::DECIMAL(18,1), 0)::VARCHAR, + ROUND('104.3'::DECIMAL(18,1), -1)::VARCHAR; + +-- use decimal in sub-query + +SELECT (SELECT '1.0'::DECIMAL(2,1)); + +-- test join with decimals + +CREATE TABLE tmp_table(i INTEGER, ts timestamp time index); + +INSERT INTO tmp_table VALUES (1, 1000), (2, 2000), (3, 3000); + +SELECT * FROM tmp_table; + +SELECT * FROM tmp_table JOIN decimals ON decimals.ts = tmp_table.ts; + +DROP TABLE decimals; + +DROP TABLE tmp_table; diff --git a/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.result b/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.result new file mode 100644 index 000000000000..68af47cf58c5 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.result @@ -0,0 +1,66 @@ +select '1.023450000001'::DECIMAL(5,4); + ++------------------------+ +| Utf8("1.023450000001") | ++------------------------+ +| 1.0235 | ++------------------------+ + +select '1.234499999'::DECIMAL(4,3); + ++---------------------+ +| Utf8("1.234499999") | ++---------------------+ +| 1.234 | ++---------------------+ + +select '1.23499999'::DECIMAL(4,3); + ++--------------------+ +| Utf8("1.23499999") | ++--------------------+ +| 1.235 | ++--------------------+ + +select '1.234499999'::DECIMAL(5,4); + ++---------------------+ +| Utf8("1.234499999") | ++---------------------+ +| 1.2345 | ++---------------------+ + +-- arrow-rs is a little strange about the conversion behavior of negative numbers. +-- issue: https://github.com/apache/arrow-datafusion/issues/8326 +select '-1.023450000001'::DECIMAL(5,4); + ++-------------------------+ +| Utf8("-1.023450000001") | ++-------------------------+ +| -0.9765 | ++-------------------------+ + +select '-1.234499999'::DECIMAL(4,3); + ++----------------------+ +| Utf8("-1.234499999") | ++----------------------+ +| -0.766 | ++----------------------+ + +select '-1.23499999'::DECIMAL(4,3); + ++---------------------+ +| Utf8("-1.23499999") | ++---------------------+ +| -0.765 | ++---------------------+ + +select '-1.234499999'::DECIMAL(5,4); + ++----------------------+ +| Utf8("-1.234499999") | ++----------------------+ +| -0.7655 | ++----------------------+ + diff --git a/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.sql b/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.sql new file mode 100644 index 000000000000..89fd28a38518 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_small_precision_behavior.sql @@ -0,0 +1,17 @@ +select '1.023450000001'::DECIMAL(5,4); + +select '1.234499999'::DECIMAL(4,3); + +select '1.23499999'::DECIMAL(4,3); + +select '1.234499999'::DECIMAL(5,4); + +-- arrow-rs is a little strange about the conversion behavior of negative numbers. +-- issue: https://github.com/apache/arrow-datafusion/issues/8326 +select '-1.023450000001'::DECIMAL(5,4); + +select '-1.234499999'::DECIMAL(4,3); + +select '-1.23499999'::DECIMAL(4,3); + +select '-1.234499999'::DECIMAL(5,4); diff --git a/tests/cases/standalone/common/types/decimal/decimal_table.result b/tests/cases/standalone/common/types/decimal/decimal_table.result new file mode 100644 index 000000000000..aaf2a08450eb --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_table.result @@ -0,0 +1,60 @@ +CREATE TABLE decimals(d DECIMAL(18,1) , ts timestamp time index); + +Affected Rows: 0 + +INSERT INTO decimals VALUES (99000000000000000.0, 1000); + +Affected Rows: 1 + +SELECT d + 1 FROM decimals; + ++-----------------------+ +| decimals.d + Int64(1) | ++-----------------------+ +| 99000000000000001.0 | ++-----------------------+ + +SELECT d + 1000000000000000.0 FROM decimals; + ++----------------------------------------+ +| decimals.d + Float64(1000000000000000) | ++----------------------------------------+ +| 1.0e17 | ++----------------------------------------+ + +SELECT -1 - d FROM decimals; + ++------------------------+ +| Int64(-1) - decimals.d | ++------------------------+ +| -99000000000000001.0 | ++------------------------+ + +SELECT -1000000000000000.0 - d FROM decimals; + ++-----------------------------------------+ +| Float64(-1000000000000000) - decimals.d | ++-----------------------------------------+ +| -1.0e17 | ++-----------------------------------------+ + +SELECT 1 * d FROM decimals; + ++-----------------------+ +| Int64(1) * decimals.d | ++-----------------------+ +| 99000000000000000.0 | ++-----------------------+ + +SELECT 2 * d FROM decimals; + ++-----------------------+ +| Int64(2) * decimals.d | ++-----------------------+ +| 198000000000000000.0 | ++-----------------------+ + +DROP TABLE decimals; + +Affected Rows: 0 + diff --git a/tests/cases/standalone/common/types/decimal/decimal_table.sql b/tests/cases/standalone/common/types/decimal/decimal_table.sql new file mode 100644 index 000000000000..6d854d4e1991 --- /dev/null +++ b/tests/cases/standalone/common/types/decimal/decimal_table.sql @@ -0,0 +1,17 @@ +CREATE TABLE decimals(d DECIMAL(18,1) , ts timestamp time index); + +INSERT INTO decimals VALUES (99000000000000000.0, 1000); + +SELECT d + 1 FROM decimals; + +SELECT d + 1000000000000000.0 FROM decimals; + +SELECT -1 - d FROM decimals; + +SELECT -1000000000000000.0 - d FROM decimals; + +SELECT 1 * d FROM decimals; + +SELECT 2 * d FROM decimals; + +DROP TABLE decimals;