mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-32244 Wrong bit encoding using COALESCE
When aggregating pairs BIT+NULL and NULL+BIT for result, e.g. in COALESCE(), preserve the BIT data type (ignore explicit NULLs). The same fix applied to YEAR.
This commit is contained in:
@ -1859,5 +1859,25 @@ cc 18446744073709551615
|
|||||||
cr 18446744073709551615
|
cr 18446744073709551615
|
||||||
ct 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
|
# End of 10.4 tests
|
||||||
#
|
#
|
||||||
|
@ -543,6 +543,22 @@ DELIMITER ;$$
|
|||||||
--horizontal_results
|
--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 #
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -675,5 +675,25 @@ FLOOR(a) int(4) unsigned YES NULL
|
|||||||
CEILING(a) int(4) unsigned YES NULL
|
CEILING(a) int(4) unsigned YES NULL
|
||||||
DROP TABLE t2,t1;
|
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
|
# End of 10.4 tests
|
||||||
#
|
#
|
||||||
|
@ -354,6 +354,20 @@ CREATE TABLE t2 AS SELECT a, ROUND(a), TRUNCATE(a,0), FLOOR(a), CEILING(a) FROM
|
|||||||
DESC t2;
|
DESC t2;
|
||||||
DROP TABLE t2,t1;
|
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 #
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
|
@ -1588,6 +1588,7 @@ Type_handler::bit_and_int_mixture_handler(uint max_char_length)
|
|||||||
Note, independently from "treat_bit_as_number":
|
Note, independently from "treat_bit_as_number":
|
||||||
- a single BIT argument gives BIT as a result
|
- a single BIT argument gives BIT as a result
|
||||||
- two BIT couterparts give 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.
|
@details This function aggregates field types from the array of items.
|
||||||
Found type is supposed to be used later as the result field type
|
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();
|
const Type_handler *cur= items[i]->type_handler();
|
||||||
set_if_bigger(max_display_length, items[i]->max_display_length());
|
set_if_bigger(max_display_length, items[i]->max_display_length());
|
||||||
if (treat_bit_as_number &&
|
uint bit_count= (type_handler() == &type_handler_bit) +
|
||||||
((type_handler() == &type_handler_bit) ^ (cur == &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;
|
bit_and_non_bit_mixture_found= true;
|
||||||
if (type_handler() == &type_handler_bit)
|
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::
|
bool Type_handler_int_result::
|
||||||
Item_hybrid_func_fix_attributes(THD *thd,
|
Item_hybrid_func_fix_attributes(THD *thd,
|
||||||
const char *func_name,
|
const char *func_name,
|
||||||
Type_handler_hybrid_field_type *handler,
|
Type_handler_hybrid_field_type *handler,
|
||||||
Type_all_attributes *func,
|
Type_all_attributes *func,
|
||||||
Item **items, uint nitems) const
|
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;
|
bool unsigned_flag= items[0]->unsigned_flag;
|
||||||
for (uint i= 1; i < nitems; i++)
|
for (uint i= 1; i < nitems; i++)
|
||||||
|
@ -4820,6 +4820,12 @@ public:
|
|||||||
type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0;
|
type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0;
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
uint32 Item_decimal_notation_int_digits(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;
|
bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user