diff options
-rw-r--r-- | mysql-test/r/func_str.result | 11 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 11 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 7 |
3 files changed, 25 insertions, 4 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 3a629f2f685..e06e7ffe00c 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1940,6 +1940,17 @@ abcxx select lpad('abc', cast(5 as unsigned integer), 'x'); lpad('abc', cast(5 as unsigned integer), 'x') xxabc +create table t1(f1 longtext); +insert into t1 values ("123"),("456"); +select substring(f1,1,1) from t1 group by 1; +substring(f1,1,1) +1 +4 +create table t2(f1 varchar(3)); +insert into t1 values ("123"),("456"); +select substring(f1,4,1), substring(f1,-4,1) from t2; +substring(f1,4,1) substring(f1,-4,1) +drop table t1,t2; DROP TABLE IF EXISTS t1; CREATE TABLE `t1` ( `id` varchar(20) NOT NULL, diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 56098ad345e..d42be70c057 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1009,6 +1009,17 @@ select rpad('abc', cast(5 as unsigned integer), 'x'); select lpad('abc', cast(5 as unsigned integer), 'x'); # +# Bug#15757: Wrong SUBSTRING() result when a tmp table was employed. +# +create table t1(f1 longtext); +insert into t1 values ("123"),("456"); +select substring(f1,1,1) from t1 group by 1; +create table t2(f1 varchar(3)); +insert into t1 values ("123"),("456"); +select substring(f1,4,1), substring(f1,-4,1) from t2; +drop table t1,t2; + +# # Bug #25197 :repeat function returns null when using table field directly as count # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7764b58c69e..6b1921e5bc8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1184,11 +1184,10 @@ void Item_func_substr::fix_length_and_dec() if (args[1]->const_item()) { int32 start= (int32) args[1]->val_int(); - start= (int32)((start < 0) ? max_length + start : start - 1); - if (start < 0 || start >= (int32) max_length) - max_length=0; /* purecov: inspected */ + if (start < 0) + max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start); else - max_length-= (uint) start; + max_length-= min((uint)(start - 1), max_length); } if (arg_count == 3 && args[2]->const_item()) { |