Commit e86457ce authored by jimw@mysql.com's avatar jimw@mysql.com

Fix QUOTE() to not reuse the input field for output, which resulted in

incorrect results when the input was a constant across a multi-row SELECT
statement. (Bug #8248)
parent 76ff72d7
...@@ -297,3 +297,10 @@ quote(ltrim(concat(' ', 'a'))) ...@@ -297,3 +297,10 @@ quote(ltrim(concat(' ', 'a')))
select quote(trim(concat(' ', 'a'))); select quote(trim(concat(' ', 'a')));
quote(trim(concat(' ', 'a'))) quote(trim(concat(' ', 'a')))
'a' 'a'
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
QUOTE('A')
'A'
'A'
'A'
DROP TABLE t1;
...@@ -193,3 +193,8 @@ select trim(leading 'foo' from 'foo'); ...@@ -193,3 +193,8 @@ select trim(leading 'foo' from 'foo');
select quote(ltrim(concat(' ', 'a'))); select quote(ltrim(concat(' ', 'a')));
select quote(trim(concat(' ', 'a'))); select quote(trim(concat(' ', 'a')));
# Bad results from QUOTE(). Bug #8248
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
DROP TABLE t1;
...@@ -2183,18 +2183,13 @@ String *Item_func_quote::val_str(String *str) ...@@ -2183,18 +2183,13 @@ String *Item_func_quote::val_str(String *str)
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
new_length+= get_esc_bit(escmask, (uchar) *from); new_length+= get_esc_bit(escmask, (uchar) *from);
/* if (tmp_value.alloc(new_length))
We have to use realloc() instead of alloc() as we want to keep the
old result in arg
*/
if (arg->realloc(new_length))
goto null; goto null;
/* /*
As 'arg' and 'str' may be the same string, we must replace characters We replace characters from the end to the beginning
from the end to the beginning
*/ */
to= (char*) arg->ptr() + new_length - 1; to= (char*) tmp_value.ptr() + new_length - 1;
*to--= '\''; *to--= '\'';
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
{ {
...@@ -2222,9 +2217,9 @@ String *Item_func_quote::val_str(String *str) ...@@ -2222,9 +2217,9 @@ String *Item_func_quote::val_str(String *str)
} }
} }
*to= '\''; *to= '\'';
arg->length(new_length); tmp_value.length(new_length);
null_value= 0; null_value= 0;
return arg; return &tmp_value;
null: null:
null_value= 1; null_value= 1;
......
...@@ -535,6 +535,7 @@ class Item_func_export_set: public Item_str_func ...@@ -535,6 +535,7 @@ class Item_func_export_set: public Item_str_func
class Item_func_quote :public Item_str_func class Item_func_quote :public Item_str_func
{ {
String tmp_value;
public: public:
Item_func_quote(Item *a) :Item_str_func(a) {} Item_func_quote(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "quote"; } const char *func_name() const { return "quote"; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment