summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2005-06-28 21:45:11 +0300
committerunknown <bell@sanja.is.com.ua>2005-06-28 21:45:11 +0300
commit2637338014fc335ea872b3c0ca85bb75bc309b51 (patch)
tree53a7c6eac183ba5acf820c263dca5abdbfd58eb5
parentdadf91f0ff29d1ac767a16803c3eaca7db3e13ed (diff)
downloadmariadb-git-2637338014fc335ea872b3c0ca85bb75bc309b51.tar.gz
fixed substring() length calculation in case of constant negative argument (BUG#10269)
mysql-test/r/func_str.result: Correct length reporting from substring() mysql-test/t/func_str.test: Correct length reporting from substring() sql/item_strfunc.cc: fixed substring() length calculation in case of constant negative argument
-rw-r--r--mysql-test/r/func_str.result15
-rw-r--r--mysql-test/t/func_str.test9
-rw-r--r--sql/item_strfunc.cc3
3 files changed, 26 insertions, 1 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 60c77d91ca5..91ee3be3b72 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -800,3 +800,18 @@ SELECT * FROM t1, t2 WHERE num=substring(str from 1 for 6);
str num
notnumber 0
DROP TABLE t1,t2;
+create table t1 (b varchar(5));
+insert t1 values ('ab'), ('abc'), ('abcd'), ('abcde');
+select *,substring(b,1),substring(b,-1),substring(b,-2),substring(b,-3),substring(b,-4),substring(b,-5) from t1;
+b substring(b,1) substring(b,-1) substring(b,-2) substring(b,-3) substring(b,-4) substring(b,-5)
+ab ab b ab
+abc abc c bc abc
+abcd abcd d cd bcd abcd
+abcde abcde e de cde bcde abcde
+select * from (select *,substring(b,1),substring(b,-1),substring(b,-2),substring(b,-3),substring(b,-4),substring(b,-5) from t1) t;
+b substring(b,1) substring(b,-1) substring(b,-2) substring(b,-3) substring(b,-4) substring(b,-5)
+ab ab b ab
+abc abc c bc abc
+abcd abcd d cd bcd abcd
+abcde abcde e de cde bcde abcde
+drop table t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 36cfac16ff3..9a8ef7c1341 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -541,3 +541,12 @@ SELECT * FROM t1, t2 WHERE num=str;
SELECT * FROM t1, t2 WHERE num=substring(str from 1 for 6);
DROP TABLE t1,t2;
+
+#
+# Correct length reporting from substring() (BUG#10269)
+#
+create table t1 (b varchar(5));
+insert t1 values ('ab'), ('abc'), ('abcd'), ('abcde');
+select *,substring(b,1),substring(b,-1),substring(b,-2),substring(b,-3),substring(b,-4),substring(b,-5) from t1;
+select * from (select *,substring(b,1),substring(b,-1),substring(b,-2),substring(b,-3),substring(b,-4),substring(b,-5) from t1) t;
+drop table t1;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 881a8a7c915..08e6a222c69 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1065,7 +1065,8 @@ void Item_func_substr::fix_length_and_dec()
collation.set(args[0]->collation);
if (args[1]->const_item())
{
- int32 start=(int32) args[1]->val_int()-1;
+ 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 */
else