diff --git a/mysql-test/main/type_bit.result b/mysql-test/main/type_bit.result index 1b5adf8c1fe..945dbfb3863 100644 --- a/mysql-test/main/type_bit.result +++ b/mysql-test/main/type_bit.result @@ -1859,5 +1859,25 @@ cc 18446744073709551615 cr 18446744073709551615 ct 18446744073709551615 # +# MDEV-32244 Wrong bit encoding using COALESCE +# +CREATE TABLE t1 (c1 BIT); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT +c1, +COALESCE(c1, c1) AS c2, +COALESCE(c1, null) AS c3, +COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` bit(1) DEFAULT NULL, + `c2` bit(1) DEFAULT NULL, + `c3` bit(1) DEFAULT NULL, + `c4` bit(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/type_bit.test b/mysql-test/main/type_bit.test index 95a29af70f6..56ba954e728 100644 --- a/mysql-test/main/type_bit.test +++ b/mysql-test/main/type_bit.test @@ -543,6 +543,22 @@ DELIMITER ;$$ --horizontal_results +--echo # +--echo # MDEV-32244 Wrong bit encoding using COALESCE +--echo # + +CREATE TABLE t1 (c1 BIT); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT + c1, + COALESCE(c1, c1) AS c2, + COALESCE(c1, null) AS c3, + COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/type_year.result b/mysql-test/main/type_year.result index 124654cd946..6f8add9d381 100644 --- a/mysql-test/main/type_year.result +++ b/mysql-test/main/type_year.result @@ -675,5 +675,25 @@ FLOOR(a) int(4) unsigned YES NULL CEILING(a) int(4) unsigned YES NULL DROP TABLE t2,t1; # +# MDEV-32244 Wrong bit encoding using COALESCE +# +CREATE TABLE t1 (c1 YEAR); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT +c1, +COALESCE(c1, c1) AS c2, +COALESCE(c1, null) AS c3, +COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` year(4) DEFAULT NULL, + `c2` year(4) DEFAULT NULL, + `c3` year(4) DEFAULT NULL, + `c4` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/type_year.test b/mysql-test/main/type_year.test index c281bdb7d97..25fe6486607 100644 --- a/mysql-test/main/type_year.test +++ b/mysql-test/main/type_year.test @@ -354,6 +354,20 @@ CREATE TABLE t2 AS SELECT a, ROUND(a), TRUNCATE(a,0), FLOOR(a), CEILING(a) FROM DESC t2; DROP TABLE t2,t1; +--echo # +--echo # MDEV-32244 Wrong bit encoding using COALESCE +--echo # + +CREATE TABLE t1 (c1 YEAR); +INSERT INTO t1 (c1) VALUES (0x01); +CREATE TABLE t2 AS SELECT + c1, + COALESCE(c1, c1) AS c2, + COALESCE(c1, null) AS c3, + COALESCE(null, c1) AS c4 FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; --echo # --echo # End of 10.4 tests diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 92bf2b39f90..edffcf761c8 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1588,6 +1588,7 @@ Type_handler::bit_and_int_mixture_handler(uint max_char_length) Note, independently from "treat_bit_as_number": - a single BIT argument gives BIT as a result - two BIT couterparts give BIT as a result + - (BIT + explicit NULL) or (explicit NULL + BIT) give BIT @details This function aggregates field types from the array of items. Found type is supposed to be used later as the result field type @@ -1620,8 +1621,11 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, { const Type_handler *cur= items[i]->type_handler(); set_if_bigger(max_display_length, items[i]->max_display_length()); - if (treat_bit_as_number && - ((type_handler() == &type_handler_bit) ^ (cur == &type_handler_bit))) + uint bit_count= (type_handler() == &type_handler_bit) + + (cur == &type_handler_bit); + uint null_count= (type_handler() == &type_handler_null) + + (cur == &type_handler_null); + if (treat_bit_as_number && bit_count == 1 && null_count == 0) { bit_and_non_bit_mixture_found= true; if (type_handler() == &type_handler_bit) @@ -4067,12 +4071,39 @@ Type_handler_timestamp_common::create_item_copy(THD *thd, Item *item) const /*************************************************************************/ +/* + This method handles YEAR and BIT data types. + It does not switch the data type to DECIAMAL on a + unsigned_flag mistmatch. This important for combinations + like YEAR+NULL, BIT+NULL. +*/ bool Type_handler_int_result:: Item_hybrid_func_fix_attributes(THD *thd, const char *func_name, Type_handler_hybrid_field_type *handler, Type_all_attributes *func, Item **items, uint nitems) const +{ + func->aggregate_attributes_int(items, nitems); + return false; +} + + +/* + This method handles general purpose integer data types + TINYINT, SHORTINT, MEDIUNINT, BIGINT. + It switches to DECIMAL in case if a mismatch in unsigned_flag found. + + Note, we should fix this to ignore all items with + type_handler()==&type_handler_null. + It's too late for 10.4. Let's do it eventually in a higher version. +*/ +bool Type_handler_general_purpose_int:: + Item_hybrid_func_fix_attributes(THD *thd, + const char *func_name, + Type_handler_hybrid_field_type *handler, + Type_all_attributes *func, + Item **items, uint nitems) const { bool unsigned_flag= items[0]->unsigned_flag; for (uint i= 1; i < nitems; i++) diff --git a/sql/sql_type.h b/sql/sql_type.h index bf76806c44a..97315faa665 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -4820,6 +4820,12 @@ public: type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0; uint32 max_display_length(const Item *item) const; uint32 Item_decimal_notation_int_digits(const Item *item) const; + bool Item_hybrid_func_fix_attributes(THD *thd, + const char *name, + Type_handler_hybrid_field_type *, + Type_all_attributes *atrr, + Item **items, + uint nitems) const; bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; };