mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-28686 Assertion `0' in Type_handler_string_result::make_sort_key or unexpected result
The code in the can_eval_in_optimize() branch in Item_func_pad::fix_length_and_dec() did not take into account that the constant can be negative. So the function will return NULL. This later crashed on DBUG_ASSERT() because a NOT NULL function returned NULL. Adding set_maybe_null() into this branch if the constant is negative.
This commit is contained in:
parent
4ded2cbe13
commit
b9f9d804f2
3 changed files with 55 additions and 5 deletions
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue