diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 3d9c9bc15d9..06cfa233f73 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2980,6 +2980,49 @@ select md5(_filename "a"), sha(_filename "a"); md5(_filename "a") sha(_filename "a") 0cc175b9c0f1b6a831c399e269772661 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 # +# MDEV-18881 Assertion `0' failed in make_sortkey upon SELECT with GROUP BY after LOAD DATA +# +CREATE TABLE t1 (a BIT(22), b CHAR(8) NOT NULL, c CHAR(8)); +INSERT INTO t1 VALUES (0xA4B,'foo','qux'); +INSERT INTO t1 VALUES (0x8F5,'bar','foobar'); +INSERT INTO t1 VALUES (0x0, '', NULL); +INSERT INTO t1 VALUES (0x4B, 'foo','qux'); +INSERT INTO t1 VALUES (0x8F5, 'bar', 'foobar'); +SET SESSION SQL_MODE= ''; +SELECT GROUP_CONCAT(c) AS f FROM t1 GROUP BY LPAD('foo', 20, b); +f +NULL +foobar,foobar +qux,qux +DROP TABLE t1; +SET SESSION SQL_MODE=DEFAULT; +CREATE TABLE t1 AS SELECT +LPAD('a',10,' '), +RPAD('a',10,' '), +LPAD('a',10,' '), +RPAD('a',10,' '), +LPAD('a',10,NULL), +RPAD('a',10,NULL), +LPAD('a',10,''), +RPAD('a',10,''), +LPAD('a',10,RAND()), +RPAD('a',10,RAND()); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `LPAD('a',10,' ')` varchar(10) NOT NULL, + `RPAD('a',10,' ')` varchar(10) NOT NULL, + `LPAD('a',10,' ')` varchar(10) NOT NULL, + `RPAD('a',10,' ')` varchar(10) NOT NULL, + `LPAD('a',10,NULL)` varchar(10) DEFAULT NULL, + `RPAD('a',10,NULL)` varchar(10) DEFAULT NULL, + `LPAD('a',10,'')` varchar(10) DEFAULT NULL, + `RPAD('a',10,'')` varchar(10) DEFAULT NULL, + `LPAD('a',10,RAND())` varchar(10) DEFAULT NULL, + `RPAD('a',10,RAND())` varchar(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +# # End of 5.5 tests # # diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 46b4dc2e3f0..de954d2f60b 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1610,6 +1610,36 @@ drop table t1,t2; # select md5(_filename "a"), sha(_filename "a"); +--echo # +--echo # MDEV-18881 Assertion `0' failed in make_sortkey upon SELECT with GROUP BY after LOAD DATA +--echo # + +CREATE TABLE t1 (a BIT(22), b CHAR(8) NOT NULL, c CHAR(8)); +INSERT INTO t1 VALUES (0xA4B,'foo','qux'); +INSERT INTO t1 VALUES (0x8F5,'bar','foobar'); +INSERT INTO t1 VALUES (0x0, '', NULL); +INSERT INTO t1 VALUES (0x4B, 'foo','qux'); +INSERT INTO t1 VALUES (0x8F5, 'bar', 'foobar'); +SET SESSION SQL_MODE= ''; +SELECT GROUP_CONCAT(c) AS f FROM t1 GROUP BY LPAD('foo', 20, b); +DROP TABLE t1; +SET SESSION SQL_MODE=DEFAULT; + +CREATE TABLE t1 AS SELECT + LPAD('a',10,' '), + RPAD('a',10,' '), + LPAD('a',10,' '), + RPAD('a',10,' '), + LPAD('a',10,NULL), + RPAD('a',10,NULL), + LPAD('a',10,''), + RPAD('a',10,''), + LPAD('a',10,RAND()), + RPAD('a',10,RAND()); +SHOW CREATE TABLE t1; +DROP TABLE t1; + + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 73080d9f7fe..de13999bab8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3066,8 +3066,12 @@ err: } -void Item_func_rpad::fix_length_and_dec() +void Item_func_pad::fix_length_and_dec() { + String *str; + if (!args[2]->basic_const_item() || !(str= args[2]->val_str(&pad_str)) || !str->length()) + maybe_null= true; + // Handle character set for args[0] and args[2]. if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) return; @@ -3101,7 +3105,7 @@ String *Item_func_rpad::val_str(String *str) longlong count= args[1]->val_int(); longlong byte_count; String *res= args[0]->val_str(str); - String *rpad= args[2]->val_str(&rpad_str); + String *rpad= args[2]->val_str(&pad_str); if (!res || args[1]->null_value || !rpad || ((count < 0) && !args[1]->unsigned_flag)) @@ -3174,32 +3178,6 @@ String *Item_func_rpad::val_str(String *str) } -void Item_func_lpad::fix_length_and_dec() -{ - // Handle character set for args[0] and args[2]. - if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) - return; - - if (args[1]->const_item()) - { - ulonglong char_length= (ulonglong) args[1]->val_int(); - DBUG_ASSERT(collation.collation->mbmaxlen > 0); - /* Assumes that the maximum length of a String is < INT_MAX32. */ - /* Set here so that rest of code sees out-of-bound value as such. */ - if (args[1]->null_value) - char_length= 0; - else if (char_length > INT_MAX32) - char_length= INT_MAX32; - fix_char_length_ulonglong(char_length); - } - else - { - max_length= MAX_BLOB_WIDTH; - maybe_null= 1; - } -} - - String *Item_func_lpad::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -3208,7 +3186,7 @@ String *Item_func_lpad::val_str(String *str) longlong count= args[1]->val_int(); longlong byte_count; String *res= args[0]->val_str(&tmp_value); - String *pad= args[2]->val_str(&lpad_str); + String *pad= args[2]->val_str(&pad_str); if (!res || args[1]->null_value || !pad || ((count < 0) && !args[1]->unsigned_flag)) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 49faed2fec1..ace246bc271 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -823,26 +823,33 @@ public: }; -class Item_func_rpad :public Item_str_func +class Item_func_pad: public Item_str_func +{ +protected: + String tmp_value, pad_str; +public: + Item_func_pad(THD *thd, Item *arg1, Item *arg2, Item *arg3): + Item_str_func(thd, arg1, arg2, arg3) {} + void fix_length_and_dec(); +}; + + +class Item_func_rpad :public Item_func_pad { - String tmp_value, rpad_str; public: Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3): - Item_str_func(thd, arg1, arg2, arg3) {} + Item_func_pad(thd, arg1, arg2, arg3) {} String *val_str(String *); - void fix_length_and_dec(); const char *func_name() const { return "rpad"; } }; -class Item_func_lpad :public Item_str_func +class Item_func_lpad :public Item_func_pad { - String tmp_value, lpad_str; public: Item_func_lpad(THD *thd, Item *arg1, Item *arg2, Item *arg3): - Item_str_func(thd, arg1, arg2, arg3) {} + Item_func_pad(thd, arg1, arg2, arg3) {} String *val_str(String *); - void fix_length_and_dec(); const char *func_name() const { return "lpad"; } };