Below is the list of changes that have just been committed into a local
5.0 repository of pem. When pem does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2013 05/10/19 14:54:54 pem@stripped +3 -0
Fixed BUG#13941: replace() string fuction behaves badly inside stored
procedure
For some functions returning strings (like "replace" and "ifnull" - where
val_str() is returning a pointer into one of the parameters) - we ended
up with a dangling pointer after the new operator destroyed the reuse item
in the eval function.
A working, if not very elegant, solution is to simply copy the string in
such cases.
sql/sp_head.cc
1.192 05/10/19 14:54:41 pem@stripped +15 -0
Copy the string when evaluating some string functions (e.g. "replace" and "ifnull")
to avoid using a dangling pointer.
mysql-test/t/sp.test
1.160 05/10/19 14:54:41 pem@stripped +43 -0
New test case for BUG#13941.
mysql-test/r/sp.result
1.166 05/10/19 14:54:41 pem@stripped +28 -0
New test case for BUG#13941.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: pem
# Host: mysql.comhem.se
# Root: /usr/home/pem/bug13941/mysql-5.0
--- 1.165/mysql-test/r/sp.result 2005-10-17 17:08:51 +02:00
+++ 1.166/mysql-test/r/sp.result 2005-10-19 14:54:41 +02:00
@@ -3504,4 +3504,32 @@
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;
--- 1.159/mysql-test/t/sp.test 2005-10-17 17:08:55 +02:00
+++ 1.160/mysql-test/t/sp.test 2005-10-19 14:54:41 +02:00
@@ -4391,6 +4391,49 @@
#
+# 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
--- 1.191/sql/sp_head.cc 2005-10-17 15:12:29 +02:00
+++ 1.192/sql/sp_head.cc 2005-10-19 14:54:41 +02:00
@@ -293,6 +293,21 @@
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 it 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)
+ {
+ tmp.copy(s->c_ptr(), s->length(), it->collation.collation);
+ s= &tmp;
+ }
+
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize)
Item_string(it->collation.collation),
use_callers_arena, &backup_arena);
| Thread |
|---|
| • bk commit into 5.0 tree (pem:1.2013) BUG#13941 | pem | 19 Oct |