summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result3
-rw-r--r--mysql-test/t/func_str.test6
-rw-r--r--sql/item_strfunc.cc5
-rw-r--r--sql/sql_string.h1
4 files changed, 14 insertions, 1 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index e07ee4f0add..345832387bd 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -673,3 +673,6 @@ c1 c2
2147483647 4294967295
-2147483648 0
drop table t1;
+select left(1234, 3) + 0;
+left(1234, 3) + 0
+123
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 61d0326f7dd..e7852df40b3 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -402,3 +402,9 @@ insert into t1 values ('-21474836461','-21474836461');
show warnings;
select * from t1;
drop table t1;
+
+#
+# Bug #4878: LEFT() in integer/float context
+#
+
+select left(1234, 3) + 0;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index d3493e1fad1..995627766c0 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -984,7 +984,10 @@ String *Item_func_left::val_str(String *str)
return &my_empty_string;
if (res->length() <= (uint) length)
return res;
- str_value.set(*res, 0, res->charpos(length));
+ if (&str_value == res)
+ str_value.length(res->charpos(length));
+ else
+ str_value.set(*res, 0, res->charpos(length));
return &str_value;
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 01329c45a98..0179b3ebadc 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -98,6 +98,7 @@ public:
void set(String &str,uint32 offset,uint32 arg_length)
{
+ DBUG_ASSERT(&str != this);
free();
Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
if (str.Alloced_length)