diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 68cda5fae95..bcc9721d146 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5355,5 +5355,27 @@ HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)) D120D18E DROP VIEW v1; # +# MDEV-28686 Assertion `0' in Type_handler_string_result::make_sort_key or unexpected result +# +CREATE TABLE t (s DATE, e DATE, PERIOD FOR p(s,e)); +INSERT INTO t (s,e) VALUES ('1970-01-01','1970-01-02'),('1980-01-01','1980-01-02'); +SET sql_mode=''; +SELECT e, GROUP_CONCAT(s) FROM t GROUP BY CONVERT((LPAD(e, -1) AND e) USING utf8); +e GROUP_CONCAT(s) +1970-01-02 1970-01-01,1980-01-01 +DROP TABLE t; +CREATE TABLE t (s DATE, e DATE, PERIOD FOR p(s,e)); +INSERT INTO t (s,e) VALUES ('1970-01-01','1970-01-02'),('1980-01-01','1980-01-02'); +SET sql_mode=''; +SELECT DISTINCT CONVERT((LPAD(e, -1) AND e) USING utf8) FROM t; +CONVERT((LPAD(e, -1) AND e) USING utf8) +NULL +SET sql_mode=STRICT_TRANS_TABLES; +SELECT DISTINCT CONVERT((LPAD(e, -1) AND e) USING utf8) FROM t; +CONVERT((LPAD(e, -1) AND e) USING utf8) +NULL +DROP TABLE t; +SET sql_mode=DEFAULT; +# # End of 10.6 tests # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index d632250ba52..9735019c132 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2402,6 +2402,24 @@ CREATE VIEW v1 AS SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); SELECT * FROM v1; DROP VIEW v1; +--echo # +--echo # MDEV-28686 Assertion `0' in Type_handler_string_result::make_sort_key or unexpected result +--echo # + +CREATE TABLE t (s DATE, e DATE, PERIOD FOR p(s,e)); +INSERT INTO t (s,e) VALUES ('1970-01-01','1970-01-02'),('1980-01-01','1980-01-02'); +SET sql_mode=''; +SELECT e, GROUP_CONCAT(s) FROM t GROUP BY CONVERT((LPAD(e, -1) AND e) USING utf8); +DROP TABLE t; + +CREATE TABLE t (s DATE, e DATE, PERIOD FOR p(s,e)); +INSERT INTO t (s,e) VALUES ('1970-01-01','1970-01-02'),('1980-01-01','1980-01-02'); +SET sql_mode=''; +SELECT DISTINCT CONVERT((LPAD(e, -1) AND e) USING utf8) FROM t; +SET sql_mode=STRICT_TRANS_TABLES; +SELECT DISTINCT CONVERT((LPAD(e, -1) AND e) USING utf8) FROM t; +DROP TABLE t; +SET sql_mode=DEFAULT; --echo # --echo # End of 10.6 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 72d7520839b..15821ad530a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -61,13 +61,17 @@ size_t username_char_length= USERNAME_CHAR_LENGTH; Calculate max length of string from length argument to LEFT and RIGHT */ -static uint32 max_length_for_string(Item *item) +static uint32 max_length_for_string(Item *item, bool *neg) { + *neg= false; ulonglong length= item->val_int(); if (item->null_value) return 0; if (length > (ulonglong) LONGLONG_MAX && !item->unsigned_flag) + { + *neg= true; return 0; // Negative + } if (length > (ulonglong) INT_MAX32) { /* Limit string length to maxium string length in MariaDB (2G) */ @@ -1664,7 +1668,8 @@ void Item_str_func::left_right_max_length() uint32 char_length= args[0]->max_char_length(); if (args[1]->can_eval_in_optimize()) { - uint32 length= max_length_for_string(args[1]); + bool neg; + uint32 length= max_length_for_string(args[1], &neg); set_if_smaller(char_length, length); } fix_char_length(char_length); @@ -3078,7 +3083,8 @@ bool Item_func_repeat::fix_length_and_dec() DBUG_ASSERT(collation.collation != NULL); if (args[1]->can_eval_in_optimize()) { - uint32 length= max_length_for_string(args[1]); + bool neg; + uint32 length= max_length_for_string(args[1], &neg); ulonglong char_length= (ulonglong) args[0]->max_char_length() * length; fix_char_length_ulonglong(char_length); return false; @@ -3152,7 +3158,8 @@ bool Item_func_space::fix_length_and_dec() collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); if (args[0]->can_eval_in_optimize()) { - fix_char_length_ulonglong(max_length_for_string(args[0])); + bool neg; + fix_char_length_ulonglong(max_length_for_string(args[0], &neg)); return false; } max_length= MAX_BLOB_WIDTH; @@ -3278,7 +3285,10 @@ bool Item_func_pad::fix_length_and_dec() DBUG_ASSERT(collation.collation->mbmaxlen > 0); if (args[1]->can_eval_in_optimize()) { - fix_char_length_ulonglong(max_length_for_string(args[1])); + bool neg; + fix_char_length_ulonglong(max_length_for_string(args[1], &neg)); + if (neg) + set_maybe_null(); return false; } max_length= MAX_BLOB_WIDTH;