Skip to content

Commit fb9a959

Browse files
MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery
constellation Analysis: The decimals is set to NOT_FIXED_DEC for Field_str even if it is NULL. Unsigned has decimals=0. So Type_std_attributes::decimals is set to 39 (maximum between 0 and 39). This results in incorrect number of decimals when we have union of unsigned and NULL type. Fix: Check if the field is created from NULL value. If yes, set decimals to 0 otherwise set it to NOT_FIXED_DEC.
1 parent 59998d3 commit fb9a959

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

mysql-test/main/union.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,5 +2601,39 @@ Warnings:
26012601
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where `test`.`t2`.`a` < 5 except /* select#2 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where `test`.`t3`.`a` < 5 union all /* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4
26022602
drop table t1,t2,t3;
26032603
#
2604+
# MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery
2605+
# constellation
2606+
#
2607+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT * from (SELECT NULL) t;
2608+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2609+
def CAST(1 AS UNSIGNED) 246 2 1 Y 32896 0 63
2610+
CAST(1 AS UNSIGNED)
2611+
1
2612+
NULL
2613+
SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT NULL) t;
2614+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2615+
def CAST(1 AS SIGNED) 3 2 1 Y 32896 0 63
2616+
CAST(1 AS SIGNED)
2617+
1
2618+
NULL
2619+
SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT CAST(1 AS UNSIGNED)) t;
2620+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2621+
def CAST(1 AS SIGNED) 246 11 1 N 32897 0 63
2622+
CAST(1 AS SIGNED)
2623+
1
2624+
1
2625+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT NULL;
2626+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2627+
def CAST(1 AS UNSIGNED) 246 2 1 Y 32896 0 63
2628+
CAST(1 AS UNSIGNED)
2629+
1
2630+
NULL
2631+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED);
2632+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
2633+
def CAST(1 AS UNSIGNED) 246 2 1 N 32897 0 63
2634+
CAST(1 AS UNSIGNED)
2635+
1
2636+
1
2637+
#
26042638
# End of 10.3 tests
26052639
#

mysql-test/main/union.test

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,24 @@ select * from t1 where a > 4;
18551855

18561856
drop table t1,t2,t3;
18571857

1858+
--echo #
1859+
--echo # MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery
1860+
--echo # constellation
1861+
--echo #
1862+
1863+
--disable_ps_protocol
1864+
--enable_metadata
1865+
1866+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT * from (SELECT NULL) t;
1867+
SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT NULL) t;
1868+
SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT CAST(1 AS UNSIGNED)) t;
1869+
1870+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT NULL;
1871+
SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED);
1872+
1873+
--disable_metadata
1874+
--enable_ps_protocol
1875+
18581876
--echo #
18591877
--echo # End of 10.3 tests
18601878
--echo #

sql/field.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,7 @@ class Field_str :public Field {
17621762
uchar null_bit_arg, utype unireg_check_arg,
17631763
const LEX_CSTRING *field_name_arg,
17641764
const DTCollation &collation);
1765-
uint decimals() const { return NOT_FIXED_DEC; }
1765+
uint decimals() const { return is_created_from_null_item ? 0 : NOT_FIXED_DEC; }
17661766
int save_in_field(Field *to) { return save_in_field_str(to); }
17671767
bool memcpy_field_possible(const Field *from) const
17681768
{

0 commit comments

Comments
 (0)