summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result11
-rw-r--r--mysql-test/t/func_str.test11
-rw-r--r--sql/item_strfunc.cc7
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())
{