Below is the list of changes that have just been committed into a local
5.0 repository of uchum. When uchum 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@stripped, 2007-07-20 04:49:29+05:00, gshchepa@stripped +3 -0
Fixed bug #29834.
Repetitive access to the view column by it's name in a stored
procedure caused a memory leak.
mysql-test/r/sp.result@stripped, 2007-07-20 04:42:38+05:00, gshchepa@stripped +75 -0
Updated test case for bug #29834.
mysql-test/t/sp.test@stripped, 2007-07-20 04:42:29+05:00, gshchepa@stripped +62 -0
Updated test case for bug #29834.
sql/sql_base.cc@stripped, 2007-07-20 04:41:40+05:00, gshchepa@stripped +3 -3
Fixed bug #29834.
The find_field_in_view function has been modified to deny
an unnecessary population of the Item_direct_view_ref
objects during SP/SF call.
diff -Nrup a/mysql-test/r/sp.result b/mysql-test/r/sp.result
--- a/mysql-test/r/sp.result 2007-06-07 12:07:38 +05:00
+++ b/mysql-test/r/sp.result 2007-07-20 04:42:38 +05:00
@@ -6176,4 +6176,79 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`r
DROP VIEW v1;
DROP FUNCTION metered;
DROP TABLE t1;
+DROP PROCEDURE IF EXISTS p1;
+Warnings:
+Note 1305 PROCEDURE p1 does not exist
+DROP PROCEDURE IF EXISTS p2;
+Warnings:
+Note 1305 PROCEDURE p2 does not exist
+DROP FUNCTION IF EXISTS f1;
+Warnings:
+Note 1305 FUNCTION f1 does not exist
+DROP VIEW IF EXISTS v1;
+Warnings:
+Note 1051 Unknown table 'test.v1'
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (c1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1(IN loops BIGINT(19) UNSIGNED)
+BEGIN
+WHILE loops > 0 DO
+SELECT c1 FROM v1;
+SET loops = loops - 1;
+END WHILE;
+END|
+CREATE PROCEDURE p2(IN loops BIGINT(19) UNSIGNED)
+BEGIN
+WHILE loops > 0 DO
+SELECT c1 FROM v1;
+CALL p1(2);
+SET loops = loops - 1;
+END WHILE;
+END|
+CREATE FUNCTION f1(loops INT UNSIGNED)
+RETURNS INT
+BEGIN
+DECLARE tmp INT;
+WHILE loops > 0 DO
+SELECT c1 INTO tmp FROM v1;
+SET loops = loops - 1;
+END WHILE;
+RETURN loops;
+END|
+CALL p1(2);
+c1
+c1
+CALL p2(2);
+c1
+c1
+c1
+c1
+c1
+c1
+SELECT f1(2);
+f1(2)
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+Warning 1329 No data - zero rows fetched, selected, or processed
+PREPARE s1 FROM 'SELECT f1(2)';
+EXECUTE s1;
+f1(2)
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+Warning 1329 No data - zero rows fetched, selected, or processed
+EXECUTE s1;
+f1(2)
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+Warning 1329 No data - zero rows fetched, selected, or processed
+DROP PREPARE s1;
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.0 tests
diff -Nrup a/mysql-test/t/sp.test b/mysql-test/t/sp.test
--- a/mysql-test/t/sp.test 2007-06-29 13:27:19 +05:00
+++ b/mysql-test/t/sp.test 2007-07-20 04:42:29 +05:00
@@ -7134,5 +7134,67 @@ DROP VIEW v1;
DROP FUNCTION metered;
DROP TABLE t1;
+#
+# Bug#29834: Accessing a view column by name in a stored procedure causes
+# a memory leak.
+#
+# This is leak test. Run with large number passed to p1 and p2 procedure,
+# anf f1 function.
+#
+
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1 (c1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+DELIMITER |;
+
+CREATE PROCEDURE p1(IN loops BIGINT(19) UNSIGNED)
+BEGIN
+ WHILE loops > 0 DO
+ SELECT c1 FROM v1;
+ SET loops = loops - 1;
+ END WHILE;
+END|
+
+CREATE PROCEDURE p2(IN loops BIGINT(19) UNSIGNED)
+BEGIN
+ WHILE loops > 0 DO
+ SELECT c1 FROM v1;
+ CALL p1(2);
+ SET loops = loops - 1;
+ END WHILE;
+END|
+
+CREATE FUNCTION f1(loops INT UNSIGNED)
+ RETURNS INT
+BEGIN
+ DECLARE tmp INT;
+ WHILE loops > 0 DO
+ SELECT c1 INTO tmp FROM v1;
+ SET loops = loops - 1;
+ END WHILE;
+ RETURN loops;
+END|
+
+DELIMITER ;|
+
+CALL p1(2);
+CALL p2(2);
+
+SELECT f1(2);
+
+PREPARE s1 FROM 'SELECT f1(2)';
+EXECUTE s1;
+EXECUTE s1;
+
+DROP PREPARE s1;
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
--echo End of 5.0 tests
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc 2007-06-03 12:03:12 +05:00
+++ b/sql/sql_base.cc 2007-07-20 04:41:40 +05:00
@@ -3435,7 +3435,7 @@ find_field_in_view(THD *thd, TABLE_LIST
table_list->alias, name, item_name, (ulong) ref));
Field_iterator_view field_it;
field_it.set(table_list);
- Query_arena *arena, backup;
+ Query_arena *arena= 0, backup;
DBUG_ASSERT(table_list->schema_table_reformed ||
(ref != 0 && table_list->view != 0));
@@ -3444,14 +3444,14 @@ find_field_in_view(THD *thd, TABLE_LIST
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
// in PS use own arena or data will be freed after prepare
- if (register_tree_change)
+ if (register_tree_change && !thd->spcont)
arena= thd->activate_stmt_arena_if_needed(&backup);
/*
create_item() may, or may not create a new Item, depending on
the column reference. See create_view_field() for details.
*/
Item *item= field_it.create_item(thd);
- if (register_tree_change && arena)
+ if (arena)
thd->restore_active_arena(arena, &backup);
if (!item)