summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-03-18 15:33:59 +0400
committerAlexander Barkov <bar@mariadb.com>2019-03-18 15:33:59 +0400
commit3b98c65c4e8b50b3000cbca643a5d3048cf1f7f7 (patch)
tree229ac6510d1571de247850cd5e63fd4d805e740c
parent6c08174e365c1a2db76e51dedd2a8292464472d6 (diff)
downloadmariadb-git-3b98c65c4e8b50b3000cbca643a5d3048cf1f7f7.tar.gz
MDEV-18881 Assertion `0' failed in make_sortkey upon SELECT with GROUP BY after LOAD DATA
-rw-r--r--mysql-test/r/func_str.result43
-rw-r--r--mysql-test/t/func_str.test30
-rw-r--r--sql/item_strfunc.cc36
-rw-r--r--sql/item_strfunc.h23
4 files changed, 95 insertions, 37 deletions
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
@@ -1611,6 +1611,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
{
- String tmp_value, rpad_str;
+protected:
+ String tmp_value, pad_str;
public:
- Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
+ Item_func_pad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_str_func(thd, arg1, arg2, arg3) {}
- String *val_str(String *);
void fix_length_and_dec();
+};
+
+
+class Item_func_rpad :public Item_func_pad
+{
+public:
+ Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
+ Item_func_pad(thd, arg1, arg2, arg3) {}
+ String *val_str(String *);
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"; }
};