From 6c4af1461f6f1183f6cf886f6d620cb527078f3f Mon Sep 17 00:00:00 2001 From: Jigao Luo Date: Fri, 9 Sep 2022 22:54:35 +0200 Subject: [PATCH] [MCOL-5205] Fix bug from union type in UNION processing. This patch fixs the reported JIRA issue MCOL 5205, which consists of a wrong union type from two input Int types. The bug results in wrong unioned answers in CS. The fix includes more INT case discussions. Additionaly, this patch provides detailed unit tests for correctness in UNION processing with Int. Signed-off-by: Jigao Luo --- datatypes/mcs_datatype.h | 78 +- mysql-test/columnstore/basic/r/union.result | 747 +++++++++++++++++++- mysql-test/columnstore/basic/t/union.test | 240 ++++++- utils/dataconvert/dataconvert.cpp | 36 +- 4 files changed, 1054 insertions(+), 47 deletions(-) diff --git a/datatypes/mcs_datatype.h b/datatypes/mcs_datatype.h index 2bdfada62..93b673070 100644 --- a/datatypes/mcs_datatype.h +++ b/datatypes/mcs_datatype.h @@ -471,10 +471,7 @@ inline bool isDecimal(const datatypes::SystemCatalog::ColDataType type) return (type == datatypes::SystemCatalog::DECIMAL || type == datatypes::SystemCatalog::UDECIMAL); } -/** convenience function to determine if column type is an - * unsigned type - */ -inline bool isUnsigned(const datatypes::SystemCatalog::ColDataType type) +inline bool isUnsignedInteger(const datatypes::SystemCatalog::ColDataType type) { switch (type) { @@ -482,7 +479,22 @@ inline bool isUnsigned(const datatypes::SystemCatalog::ColDataType type) case datatypes::SystemCatalog::USMALLINT: case datatypes::SystemCatalog::UMEDINT: case datatypes::SystemCatalog::UINT: - case datatypes::SystemCatalog::UBIGINT: + case datatypes::SystemCatalog::UBIGINT: return true; + + default: return false; + } +} + +/** convenience function to determine if column type is an + * unsigned type + */ +inline bool isUnsigned(const datatypes::SystemCatalog::ColDataType type) +{ + if (isUnsignedInteger(type)) + return true; + + switch (type) + { case datatypes::SystemCatalog::CHAR: case datatypes::SystemCatalog::VARCHAR: case datatypes::SystemCatalog::TEXT: @@ -506,6 +518,62 @@ inline bool isSignedInteger(const datatypes::SystemCatalog::ColDataType type) } } +inline bool sameSignednessInteger(const datatypes::SystemCatalog::ColDataType type1, const datatypes::SystemCatalog::ColDataType type2) +{ + return (isSignedInteger(type1) && isSignedInteger(type2)) || (isUnsignedInteger(type1) && isUnsignedInteger(type2)); +} + +inline bool differentSignednessInteger(const datatypes::SystemCatalog::ColDataType type1, const datatypes::SystemCatalog::ColDataType type2) +{ + return (isSignedInteger(type1) && isUnsignedInteger(type2)) || (isUnsignedInteger(type1) && isSignedInteger(type2)); +} + +inline void promoteSignedInteger(datatypes::SystemCatalog::TypeHolderStd& unionedType) +{ + switch (unionedType.colDataType) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::UTINYINT: + { + unionedType.colDataType = datatypes::SystemCatalog::SMALLINT; + unionedType.colWidth = 2; + return; + } + case datatypes::SystemCatalog::SMALLINT: + case datatypes::SystemCatalog::USMALLINT: + { + unionedType.colDataType = datatypes::SystemCatalog::MEDINT; + unionedType.colWidth = 4; + return; + } + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::UMEDINT: + { + unionedType.colDataType = datatypes::SystemCatalog::INT; + unionedType.colWidth = 4; + return; + } + case datatypes::SystemCatalog::INT: + case datatypes::SystemCatalog::UINT: + { + unionedType.colDataType = datatypes::SystemCatalog::BIGINT; + unionedType.colWidth = 8; + return; + } + case datatypes::SystemCatalog::BIGINT: + case datatypes::SystemCatalog::UBIGINT: + { + unionedType.colDataType = datatypes::SystemCatalog::DECIMAL; + unionedType.colWidth = MAXDECIMALWIDTH; + unionedType.precision = datatypes::INT128MAXPRECISION; + unionedType.scale = 0; + return; + } + + default: idbassert(0); throw std::logic_error("datatypes::upcastSignedInteger: bad data type"); + } +} + /** @brief The method netects whether type sum and avg aggregate will have wide decimal underlying type diff --git a/mysql-test/columnstore/basic/r/union.result b/mysql-test/columnstore/basic/r/union.result index 894367865..867bccf76 100644 --- a/mysql-test/columnstore/basic/r/union.result +++ b/mysql-test/columnstore/basic/r/union.result @@ -6,21 +6,639 @@ USE mcs_union; # MCOL-4700 Wrong result of a UNION for INT and INT UNSIGNED # CREATE TABLE t1 (a INT, b INT UNSIGNED); -INSERT INTO t1 VALUES (-1,1); +INSERT INTO t1 VALUES (-1, 1), (-1, 1), (-2, 2); +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY b; +a b +-1 1 +-2 2 +SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; +a +-2 +-1 +1 +2 +SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; +b +-2 +-1 +1 +2 +DROP TABLE t1; +# +# Multiple Columns Union +# +CREATE TABLE t1 (a INT, b INT, c INT); +INSERT INTO t1 VALUES (-1, 1, 0), (-2, 2, 0), (-3, 3, 0), (-4, 4, 0), (-5, 5, 0), (-1, 1, 0), (-2, 2, 0), (-3, 3, 0), (-4, 4, 0), (-5, 5, 0); +SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) tu ORDER BY b; +a b c +-1 1 0 +-1 1 0 +-1 1 0 +-1 1 0 +-2 2 0 +-2 2 0 +-2 2 0 +-2 2 0 +-3 3 0 +-3 3 0 +-3 3 0 +-3 3 0 +-4 4 0 +-4 4 0 +-4 4 0 +-4 4 0 +-5 5 0 +-5 5 0 +-5 5 0 +-5 5 0 +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT b FROM t1) tu ORDER BY a; +a +-5 +-5 +-4 +-4 +-3 +-3 +-2 +-2 +-1 +-1 +1 +1 +2 +2 +3 +3 +4 +4 +5 +5 +SELECT * FROM (SELECT b FROM t1 UNION ALL SELECT a FROM t1) tu ORDER BY b; +b +-5 +-5 +-4 +-4 +-3 +-3 +-2 +-2 +-1 +-1 +1 +1 +2 +2 +3 +3 +4 +4 +5 +5 +DROP TABLE t1; +# +# Same Int Type Union +# +CREATE TABLE t1 (a INT UNSIGNED, b INT UNSIGNED); +INSERT INTO t1 VALUES (1, 1), (1, 1), (2, 1), (2, 1), (3, 2), (4, 2), (5, 2); +SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; +a +1 +2 +3 +4 +5 +SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; +b +1 +2 +3 +4 +5 +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY a; +a b +1 1 +2 1 +3 2 +4 2 +5 2 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (-1, -1), (-1, -1), (2, 1), (2, 1), (3, 2), (4, 2), (5, 2); SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; a -1 1 +2 +3 +4 +5 SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; b -1 1 +2 +3 +4 +5 +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY a; +a b +-1 -1 +2 1 +3 2 +4 2 +5 2 DROP TABLE t1; +# +# Signed Int Union +# +CREATE TABLE t1 (a TINYINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); +CREATE TABLE t2 (a SMALLINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-32766 +-126 +-1 +-1 +0 +0 +1 +1 +127 +32767 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-32766 +-126 +-1 +-1 +0 +0 +1 +1 +127 +32767 +DROP TABLE t2; +CREATE TABLE t2 (a MEDIUMINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-8388606 +-126 +-1 +-1 +0 +0 +1 +1 +127 +8388607 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-8388606 +-126 +-1 +-1 +0 +0 +1 +1 +127 +8388607 +DROP TABLE t2; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-2147483646 +-126 +-1 +-1 +0 +0 +1 +1 +127 +2147483647 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-2147483646 +-126 +-1 +-1 +0 +0 +1 +1 +127 +2147483647 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-9223372036854775806 +-126 +-1 +-1 +0 +0 +1 +1 +127 +9223372036854775807 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-9223372036854775806 +-126 +-1 +-1 +0 +0 +1 +1 +127 +9223372036854775807 +DROP TABLE t1,t2; +CREATE TABLE t1 (a SMALLINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +CREATE TABLE t2 (a MEDIUMINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-8388606 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +8388607 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-8388606 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +8388607 +DROP TABLE t2; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-2147483646 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +2147483647 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-2147483646 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +2147483647 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-9223372036854775806 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +9223372036854775807 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-9223372036854775806 +-32766 +-1 +-1 +0 +0 +1 +1 +32767 +9223372036854775807 +DROP TABLE t1,t2; +CREATE TABLE t1 (a MEDIUMINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-2147483646 +-8388606 +-1 +-1 +0 +0 +1 +1 +8388607 +2147483647 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-2147483646 +-8388606 +-1 +-1 +0 +0 +1 +1 +8388607 +2147483647 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-9223372036854775806 +-8388606 +-1 +-1 +0 +0 +1 +1 +8388607 +9223372036854775807 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-9223372036854775806 +-8388606 +-1 +-1 +0 +0 +1 +1 +8388607 +9223372036854775807 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-9223372036854775806 +-2147483646 +-1 +-1 +0 +0 +1 +1 +2147483647 +9223372036854775807 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-9223372036854775806 +-2147483646 +-1 +-1 +0 +0 +1 +1 +2147483647 +9223372036854775807 +DROP TABLE t1,t2; +# +# Unsigned Int Union +# +CREATE TABLE t1 (a TINYINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFF-2); +CREATE TABLE t2 (a SMALLINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +253 +65533 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +253 +65533 +DROP TABLE t2; +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +253 +16777213 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +253 +16777213 +DROP TABLE t2; +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +253 +4294967293 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +253 +4294967293 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +253 +18446744073709551613 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +253 +18446744073709551613 +DROP TABLE t1,t2; +CREATE TABLE t1 (a SMALLINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFF-2); +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +16777213 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +16777213 +DROP TABLE t2; +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +4294967293 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +4294967293 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +18446744073709551613 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +65533 +18446744073709551613 +DROP TABLE t1,t2; +CREATE TABLE t1 (a MEDIUMINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFFFF-2); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +16777213 +4294967293 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +16777213 +4294967293 +DROP TABLE t2; +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +16777213 +18446744073709551613 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +16777213 +18446744073709551613 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFFFFFF-2); +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +0 +0 +1 +1 +4294967293 +18446744073709551613 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +0 +0 +1 +1 +4294967293 +18446744073709551613 +DROP TABLE t1,t2; +# +# Same Size Different Signedness Int Union +# CREATE TABLE t1 (a TINYINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); CREATE TABLE t2 (a TINYINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; a -126 -1 @@ -30,7 +648,7 @@ a 1 127 253 -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; a -126 -1 @@ -43,9 +661,9 @@ a DROP TABLE t1,t2; CREATE TABLE t1 (a SMALLINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); -CREATE TABLE t2 (a INT UNSIGNED); +CREATE TABLE t2 (a SMALLINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT * FROM t2) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; a -32766 -1 @@ -55,7 +673,7 @@ a 1 32767 65533 -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; a -32766 -1 @@ -68,9 +686,9 @@ a DROP TABLE t1,t2; CREATE TABLE t1 (a MEDIUMINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); -CREATE TABLE t2 (a INT UNSIGNED); +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; a -8388606 -1 @@ -80,7 +698,7 @@ a 1 8388607 16777213 -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; a -8388606 -1 @@ -95,7 +713,7 @@ CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); CREATE TABLE t2 (a INT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; a -2147483646 -1 @@ -105,7 +723,7 @@ a 1 2147483647 4294967293 -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; a -2147483646 -1 @@ -120,7 +738,7 @@ CREATE TABLE t1 (a BIGINT); INSERT INTO t1 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); CREATE TABLE t2 (a BIGINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; a -9223372036854775806 -1 @@ -130,7 +748,7 @@ a 1 9223372036854775807 18446744073709551613 -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; a -9223372036854775806 -1 @@ -141,4 +759,107 @@ a 9223372036854775807 18446744073709551613 DROP TABLE t1,t2; +# +# Different Size Different Signedness Int Union +# +CREATE TABLE t1 (a TINYINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; +a +-126 +-1 +0 +0 +1 +1 +127 +65533 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-126 +-1 +0 +0 +1 +1 +127 +65533 +DROP TABLE t1,t2; +CREATE TABLE t1 (a SMALLINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; +a +-32766 +-1 +0 +0 +1 +1 +32767 +65533 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-32766 +-1 +0 +0 +1 +1 +32767 +65533 +DROP TABLE t1,t2; +CREATE TABLE t1 (a MEDIUMINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-8388606 +-1 +0 +0 +1 +1 +8388607 +16777213 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-8388606 +-1 +0 +0 +1 +1 +8388607 +16777213 +DROP TABLE t1,t2; +CREATE TABLE t1 (a BIGINT); +INSERT INTO t1 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +a +-9223372036854775806 +-1 +0 +0 +1 +1 +16777213 +9223372036854775807 +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +a +-9223372036854775806 +-1 +0 +0 +1 +1 +16777213 +9223372036854775807 +DROP TABLE t1,t2; DROP DATABASE mcs_union; diff --git a/mysql-test/columnstore/basic/t/union.test b/mysql-test/columnstore/basic/t/union.test index abae3c497..eed88576a 100644 --- a/mysql-test/columnstore/basic/t/union.test +++ b/mysql-test/columnstore/basic/t/union.test @@ -14,49 +14,263 @@ USE mcs_union; --echo # CREATE TABLE t1 (a INT, b INT UNSIGNED); -INSERT INTO t1 VALUES (-1,1); +INSERT INTO t1 VALUES (-1, 1), (-1, 1), (-2, 2); +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY b; SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; DROP TABLE t1; +--echo # +--echo # Multiple Columns Union +--echo # + +CREATE TABLE t1 (a INT, b INT, c INT); +INSERT INTO t1 VALUES (-1, 1, 0), (-2, 2, 0), (-3, 3, 0), (-4, 4, 0), (-5, 5, 0), (-1, 1, 0), (-2, 2, 0), (-3, 3, 0), (-4, 4, 0), (-5, 5, 0); +SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t1) tu ORDER BY b; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT b FROM t1) tu ORDER BY a; +SELECT * FROM (SELECT b FROM t1 UNION ALL SELECT a FROM t1) tu ORDER BY b; +DROP TABLE t1; + +--echo # +--echo # Same Int Type Union +--echo # + +CREATE TABLE t1 (a INT UNSIGNED, b INT UNSIGNED); +INSERT INTO t1 VALUES (1, 1), (1, 1), (2, 1), (2, 1), (3, 2), (4, 2), (5, 2); +SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; +SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY a; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (-1, -1), (-1, -1), (2, 1), (2, 1), (3, 2), (4, 2), (5, 2); +SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t1) tu ORDER BY a; +SELECT * FROM (SELECT b FROM t1 UNION SELECT a FROM t1) tu ORDER BY b; +SELECT * FROM (SELECT * FROM t1 UNION SELECT * FROM t1) tu ORDER BY a; +DROP TABLE t1; + +--echo # +--echo # Signed Int Union +--echo # + +CREATE TABLE t1 (a TINYINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); +CREATE TABLE t2 (a SMALLINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a MEDIUMINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a SMALLINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +CREATE TABLE t2 (a MEDIUMINT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a MEDIUMINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); +CREATE TABLE t2 (a BIGINT); +INSERT INTO t2 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +--echo # +--echo # Unsigned Int Union +--echo # + +CREATE TABLE t1 (a TINYINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFF-2); +CREATE TABLE t2 (a SMALLINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a SMALLINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFF-2); +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a MEDIUMINT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFFFF-2); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t2; + +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT UNSIGNED); +INSERT INTO t1 VALUES (0),(1),(0xFFFFFFFF-2); +CREATE TABLE t2 (a BIGINT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +--echo # +--echo # Same Size Different Signedness Int Union +--echo # + CREATE TABLE t1 (a TINYINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); CREATE TABLE t2 (a TINYINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; DROP TABLE t1,t2; CREATE TABLE t1 (a SMALLINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); -CREATE TABLE t2 (a INT UNSIGNED); +CREATE TABLE t2 (a SMALLINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT * FROM t2) ORDER BY a; -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; DROP TABLE t1,t2; CREATE TABLE t1 (a MEDIUMINT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); -CREATE TABLE t2 (a INT UNSIGNED); +CREATE TABLE t2 (a MEDIUMINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; DROP TABLE t1,t2; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (CAST(0xFFFFFFFF80000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFF); CREATE TABLE t2 (a INT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; DROP TABLE t1,t2; CREATE TABLE t1 (a BIGINT); INSERT INTO t1 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); CREATE TABLE t2 (a BIGINT UNSIGNED); INSERT INTO t2 VALUES (0),(1),(0xFFFFFFFFFFFFFFFF-2); -(SELECT a FROM t1 UNION ALL SELECT a FROM t2) ORDER BY a; -(SELECT a FROM t2 UNION ALL SELECT a FROM t1) ORDER BY a; +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +--echo # +--echo # Different Size Different Signedness Int Union +--echo # + +CREATE TABLE t1 (a TINYINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFF80 AS SIGNED)+2),(-1),(0),(1),(0x7F); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a SMALLINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFF8000 AS SIGNED)+2),(-1),(0),(1),(0x7FFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT * FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a MEDIUMINT); +INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFF800000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a BIGINT); +INSERT INTO t1 VALUES (CAST(0x8000000000000000 AS SIGNED)+2),(-1),(0),(1),(0x7FFFFFFFFFFFFFFF); +CREATE TABLE t2 (a INT UNSIGNED); +INSERT INTO t2 VALUES (0),(1),(0xFFFFFF-2); +SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT a FROM t2) tu ORDER BY a; +SELECT * FROM (SELECT a FROM t2 UNION ALL SELECT a FROM t1) tu ORDER BY a; DROP TABLE t1,t2; DROP DATABASE mcs_union; diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index 37ff38c4e..5f3af5a2e 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -2984,25 +2984,29 @@ void DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd& u break; } - if (type.colWidth > unionedType.colWidth) + if (type.colDataType == unionedType.colDataType) { - unionedType.colDataType = type.colDataType; - unionedType.colWidth = type.colWidth; + if (type.colWidth > unionedType.colWidth) + unionedType.colWidth = type.colWidth; + } + else if (sameSignednessInteger(unionedType.colDataType, type.colDataType)) + { + // Keep the signedness on the larger data type. + if (type.colWidth > unionedType.colWidth) + { + unionedType.colDataType = type.colDataType; + unionedType.colWidth = type.colWidth; + } + } + else if (differentSignednessInteger(unionedType.colDataType, type.colDataType)) + { + // unionedType must be signed integer with upcasted size to prevent overflow & underflow. + if (type.colWidth > unionedType.colWidth) + unionedType.colDataType = type.colDataType; + promoteSignedInteger(unionedType); } - // If same size but different signedness - if (type.colWidth == unionedType.colWidth && - ((!isUnsigned(unionedType.colDataType) && isUnsigned(type.colDataType)) || - (!isUnsigned(type.colDataType) && isUnsigned(unionedType.colDataType)))) - { - unionedType.colDataType = datatypes::SystemCatalog::DECIMAL; - unionedType.colWidth = datatypes::Decimal::isWideDecimalTypeByPrecision(unionedType.precision) - ? datatypes::MAXDECIMALWIDTH - : datatypes::MAXLEGACYWIDTH; - } - - if (type.colDataType == datatypes::SystemCatalog::DECIMAL || - type.colDataType == datatypes::SystemCatalog::UDECIMAL) + if (isDecimal(type.colDataType)) { unionedType.colDataType = datatypes::SystemCatalog::DECIMAL; }