summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Glukhov <Sergey.Glukhov@sun.com>2009-09-10 15:24:07 +0500
committerSergey Glukhov <Sergey.Glukhov@sun.com>2009-09-10 15:24:07 +0500
commit10406ae65871de074e807e626f9ede686e9321d4 (patch)
treed57eb47198b5b9ed74be5982062200f2cbb5efd7
parent24f103e39c100d0ca4fa4a4777fe82cd6d69034b (diff)
downloadmariadb-git-10406ae65871de074e807e626f9ede686e9321d4.tar.gz
Bug#46815 CONCAT_WS returning wrong data
The problem is that argument buffer can be used as result buffer and it leads to argument value change. The fix is to use 'old buffer' as result buffer only if first argument is not constant item. mysql-test/r/func_str.result: test result mysql-test/t/func_str.test: test case sql/item_strfunc.cc: The problem is that argument buffer can be used as result buffer and it leads to argument value change. The fix is to use 'old buffer' as result buffer only if first argument is not constant item.
-rw-r--r--mysql-test/r/func_str.result9
-rw-r--r--mysql-test/t/func_str.test13
-rw-r--r--sql/item_strfunc.cc7
3 files changed, 28 insertions, 1 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 75f8983e838..bf2a9ca8901 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2196,4 +2196,13 @@ SELECT LOAD_FILE(a) FROM t1;
LOAD_FILE(a)
NULL
DROP TABLE t1;
+CREATE TABLE t1 (f2 VARCHAR(20));
+CREATE TABLE t2 (f2 VARCHAR(20));
+INSERT INTO t1 VALUES ('MIN'),('MAX');
+INSERT INTO t2 VALUES ('LOAD');
+SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
+concat_name
+LOAD_MIN
+LOAD_MAX
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 4b0f91e4408..e396fbcebd8 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1177,5 +1177,18 @@ INSERT INTO t1 VALUES ('aaaaaaaa');
SELECT LOAD_FILE(a) FROM t1;
DROP TABLE t1;
+#
+# Bug#46815 CONCAT_WS returning wrong data
+#
+CREATE TABLE t1 (f2 VARCHAR(20));
+CREATE TABLE t2 (f2 VARCHAR(20));
+
+INSERT INTO t1 VALUES ('MIN'),('MAX');
+INSERT INTO t2 VALUES ('LOAD');
+
+SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index e3fe67f4324..6f697a1665a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -600,6 +600,7 @@ String *Item_func_concat_ws::val_str(String *str)
String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
*sep_str, *res, *res2,*use_as_buff;
uint i;
+ bool is_const= 0;
null_value=0;
if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
@@ -613,7 +614,11 @@ String *Item_func_concat_ws::val_str(String *str)
// If not, return the empty string
for (i=1; i < arg_count; i++)
if ((res= args[i]->val_str(str)))
+ {
+ is_const= args[i]->const_item() || !args[i]->used_tables();
break;
+ }
+
if (i == arg_count)
return &my_empty_string;
@@ -631,7 +636,7 @@ String *Item_func_concat_ws::val_str(String *str)
current_thd->variables.max_allowed_packet);
goto null;
}
- if (res->alloced_length() >=
+ if (!is_const && res->alloced_length() >=
res->length() + sep_str->length() + res2->length())
{ // Use old buffer
res->append(*sep_str); // res->length() > 0 always