summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2005-10-21 13:24:41 +0200
committerunknown <pem@mysql.com>2005-10-21 13:24:41 +0200
commit01cc9f1abfbf8f3a2b16728c4e55074eb9e9b5bf (patch)
tree59c344102f4adb495c38768dd4fbae2fb34f8c78
parentf3ee1afe41d8d43ed2d41025434387249828c6aa (diff)
parentd9dc38a8e6d7ccee755423a7e9256d857042cf73 (diff)
downloadmariadb-git-01cc9f1abfbf8f3a2b16728c4e55074eb9e9b5bf.tar.gz
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/usr/home/pem/bug13941/mysql-5.0
-rw-r--r--mysql-test/r/sp.result28
-rw-r--r--mysql-test/t/sp.test43
-rw-r--r--sql/sp_head.cc18
3 files changed, 88 insertions, 1 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index e95ee4441ce..7fdbeff9a86 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3504,4 +3504,32 @@ drop procedure bug7049_5|
drop procedure bug7049_6|
drop function bug7049_1|
drop function bug7049_2|
+drop function if exists bug13941|
+drop procedure if exists bug13941|
+create function bug13941(p_input_str text)
+returns text
+begin
+declare p_output_str text;
+set p_output_str = p_input_str;
+set p_output_str = replace(p_output_str, 'xyzzy', 'plugh');
+set p_output_str = replace(p_output_str, 'test', 'prova');
+set p_output_str = replace(p_output_str, 'this', 'questo');
+set p_output_str = replace(p_output_str, ' a ', 'una ');
+set p_output_str = replace(p_output_str, 'is', '');
+return p_output_str;
+end|
+create procedure bug13941(out sout varchar(128))
+begin
+set sout = 'Local';
+set sout = ifnull(sout, 'DEF');
+end|
+select bug13941('this is a test')|
+bug13941('this is a test')
+questo una prova
+call bug13941(@a)|
+select @a|
+@a
+Local
+drop function bug13941|
+drop procedure bug13941|
drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 4b9987c2803..18607c7f13c 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4391,6 +4391,49 @@ drop function bug7049_2|
#
+# BUG#13941: replace() string fuction behaves badly inside stored procedure
+# (BUG#13914: IFNULL is returning garbage in stored procedure)
+#
+--disable_warnings
+drop function if exists bug13941|
+drop procedure if exists bug13941|
+--enable_warnings
+
+create function bug13941(p_input_str text)
+ returns text
+begin
+ declare p_output_str text;
+
+ set p_output_str = p_input_str;
+
+ set p_output_str = replace(p_output_str, 'xyzzy', 'plugh');
+ set p_output_str = replace(p_output_str, 'test', 'prova');
+ set p_output_str = replace(p_output_str, 'this', 'questo');
+ set p_output_str = replace(p_output_str, ' a ', 'una ');
+ set p_output_str = replace(p_output_str, 'is', '');
+
+ return p_output_str;
+end|
+
+create procedure bug13941(out sout varchar(128))
+begin
+ set sout = 'Local';
+ set sout = ifnull(sout, 'DEF');
+end|
+
+# Note: The bug showed different behaviour in different types of builds,
+# giving garbage results in some, and seemingly working in others.
+# Running with valgrind (or purify) is the safe way to check that it's
+# really working correctly.
+select bug13941('this is a test')|
+call bug13941(@a)|
+select @a|
+
+drop function bug13941|
+drop procedure bug13941|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 063c388702d..abc66ce0b21 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -293,6 +293,22 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
if (it == reuse)
DBUG_RETURN(it);
+ /*
+ For some functions, 's' is now pointing to an argument of the
+ function, which might be a local variable that is to be reused.
+ In this case, new(reuse, &rsize) below will call the destructor
+ and 's' ends up pointing to freed memory.
+ A somewhat ugly fix is to simply copy the string to our local one
+ (which is unused by most functions anyway), but only if 's' is
+ pointing somewhere else than to 'tmp' or 'it->str_value'.
+ */
+ if (reuse && s != &tmp && s != &it->str_value)
+ {
+ if (tmp.copy((const String)(*s)))
+ DBUG_RETURN(NULL);
+ s= &tmp;
+ }
+
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize)
Item_string(it->collation.collation),
use_callers_arena, &backup_arena);
@@ -323,7 +339,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
return_null_item:
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_null(),
- use_callers_arena, &backup_arena);
+ use_callers_arena, &backup_arena);
end:
it->rsize= rsize;