summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/sp.result19
-rw-r--r--mysql-test/t/sp.test34
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item.h18
-rw-r--r--sql/sp_head.cc23
5 files changed, 91 insertions, 4 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index d1d41035475..1570f2252ec 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3166,4 +3166,23 @@ a
4
truncate t2|
drop procedure if exists bug12168|
+drop table if exists t3|
+drop procedure if exists bug11333|
+create table t3 (c1 char(128))|
+insert into t3 values
+('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')|
+create procedure bug11333(i int)
+begin
+declare tmp varchar(128);
+set @x = 0;
+repeat
+select c1 into tmp from t3
+where c1 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
+set @x = @x + 1;
+until @x >= i
+end repeat;
+end|
+call bug11333(10)|
+drop procedure bug11333|
+drop table t3|
drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index f3e7c3e07a0..6f79243a2b1 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -3996,6 +3996,40 @@ truncate t2|
drop procedure if exists bug12168|
#
+# Bug #11333 "Stored Procedure: Memory blow up on repeated SELECT ... INTO
+# query"
+# One more memleak bug. Use the test to check memory consumption.
+#
+
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug11333|
+--enable_warnings
+
+create table t3 (c1 char(128))|
+
+insert into t3 values
+ ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')|
+
+
+create procedure bug11333(i int)
+begin
+ declare tmp varchar(128);
+ set @x = 0;
+ repeat
+ select c1 into tmp from t3
+ where c1 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
+ set @x = @x + 1;
+ until @x >= i
+ end repeat;
+end|
+
+call bug11333(10)|
+
+drop procedure bug11333|
+drop table t3|
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/sql/item.cc b/sql/item.cc
index 7575a6a218b..98caf4918ab 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -303,6 +303,7 @@ void *Item::operator new(size_t size, Item *reuse, uint *rsize)
if (rsize)
(*rsize)= reuse->rsize;
reuse->cleanup();
+ delete reuse;
TRASH((void *)reuse, size);
return (void *)reuse;
}
diff --git a/sql/item.h b/sql/item.h
index 4dfd99e0dbd..51f7c641de1 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1298,6 +1298,15 @@ public:
// it is constant => can be used without fix_fields (and frequently used)
fixed= 1;
}
+ /* Just create an item and do not fill string representation */
+ Item_string(CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
+ {
+ collation.set(cs, dv);
+ max_length= 0;
+ set_name(NULL, 0, cs);
+ decimals= NOT_FIXED_DEC;
+ fixed= 1;
+ }
Item_string(const char *name_par, const char *str, uint length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
{
@@ -1309,6 +1318,15 @@ public:
// it is constant => can be used without fix_fields (and frequently used)
fixed= 1;
}
+ /*
+ This is used in stored procedures to avoid memory leaks and
+ does a deep copy of its argument.
+ */
+ void set_str_with_copy(const char *str_arg, uint length_arg)
+ {
+ str_value.copy(str_arg, length_arg, collation.collation);
+ max_length= str_value.numchars() * collation.collation->mbmaxlen;
+ }
enum Type type() const { return STRING_ITEM; }
double val_real();
longlong val_int();
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f119ef1ec22..0a3521e8855 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -249,10 +249,25 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
DBUG_PRINT("info",("default result: %*s",
s->length(), s->c_ptr_quick()));
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize)
- Item_string(thd->strmake(s->ptr(),
- s->length()), s->length(),
- it->collation.collation),
- use_callers_arena, &backup_current_arena);
+ Item_string(it->collation.collation),
+ use_callers_arena, &backup_current_arena);
+ /*
+ We have to use special constructor and allocate string
+ on system heap here. This is because usual Item_string
+ constructor would allocate memory in the callers arena.
+ This would lead to the memory leak in SP loops.
+ See Bug #11333 "Stored Procedure: Memory blow up on
+ repeated SELECT ... INTO query" for sample of such SP.
+ TODO: Usage of the system heap gives significant overhead,
+ however usual "reuse" mechanism does not work here, as
+ Item_string has no max size. That is, if we have a loop, which
+ has string variable with constantly increasing size, we would have
+ to allocate new pieces of memory again and again on each iteration.
+ In future we should probably reserve some area of memory for
+ not-very-large strings and reuse it. But for large strings
+ we would have to use system heap anyway.
+ */
+ ((Item_string*) it)->set_str_with_copy(s->ptr(), s->length());
}
break;
}