diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 22cf0a5cc56..eb00837eaaf 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5068,5 +5068,21 @@ NULL DROP TABLE t1; # +# MDEV-20292 REPEAT(x,-1) returns a wrong data type +# +CREATE OR REPLACE TABLE t1 (i BIGINT); +INSERT INTO t1 VALUES (42); +CREATE OR REPLACE TABLE t2 AS SELECT +REPEAT(i,0) AS c0, +REPEAT(i,-1) AS c1 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c0` char(0) CHARACTER SET utf8 DEFAULT NULL, + `c1` char(0) CHARACTER SET utf8 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1, t2; +# # End of 10.3 tests # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index c122516d756..135d00bcd8c 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2028,6 +2028,19 @@ SELECT LPAD( c, 0, '?' ) FROM t1; SELECT RPAD( c, 0, '?' ) FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-20292 REPEAT(x,-1) returns a wrong data type +--echo # + +CREATE OR REPLACE TABLE t1 (i BIGINT); +INSERT INTO t1 VALUES (42); +CREATE OR REPLACE TABLE t2 AS SELECT + REPEAT(i,0) AS c0, + REPEAT(i,-1) AS c1 +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t1, t2; + --echo # --echo # End of 10.3 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3d2b3ef4814..65acc071237 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2967,20 +2967,20 @@ bool Item_func_repeat::fix_length_and_dec() if (agg_arg_charsets_for_string_result(collation, args, 1)) return TRUE; DBUG_ASSERT(collation.collation != NULL); - if (args[1]->const_item()) + if (args[1]->const_item() && !args[1]->is_expensive()) { - /* must be longlong to avoid truncation */ - longlong count= args[1]->val_int(); - - /* 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) - count= 0; - else if (count > INT_MAX32) - count= INT_MAX32; - - ulonglong char_length= (ulonglong) args[0]->max_char_length() * count; - fix_char_length_ulonglong(char_length); + Longlong_hybrid nr= args[1]->to_longlong_hybrid(); + if (args[1]->null_value || nr.neg()) + fix_char_length(0); + else + { + /* Assumes that the maximum length of a String is < INT_MAX32. */ + longlong count= nr.value(); + if (count > INT_MAX32) + count= INT_MAX32; + ulonglong char_length= (ulonglong) args[0]->max_char_length() * count; + fix_char_length_ulonglong(char_length); + } } else {