#At file:///home/gluh/MySQL/mysql-5.1/ based on revid:sergey.glukhov@stripped
3645 Sergey Glukhov 2011-04-08
Bug#11756242 48137: PROCEDURE ANALYSE() LEAKS MEMORY WHEN RETURNING NULL
There are two problems with ANALYSE():
1. Memory leak
it happens because do_select() can overwrite
JOIN::procedure field(with zero value in our case) and
JOIN destructor don't free the memory allocated for
JOIN::procedure. The fix is to save original JOIN::procedure
before do_select() call and restore it after do_select
execution.
2. Wrong result
If ANALYSE() procedure is used for the statement with LIMIT clause
it could retrun empty result set. It happens because of missing
analyse::end_of_records() call. First end_send() function call
returns NESTED_LOOP_QUERY_LIMIT and second call of end_send() with
end_of_records flag enabled does not happen. The fix is to return
NESTED_LOOP_OK from end_send() if procedure is active.
@ mysql-test/r/analyse.result
test case
@ mysql-test/t/analyse.test
test case
@ sql/sql_select.cc
--save original JOIN::procedure before do_select() call and
restore it after do_select execution.
--return NESTED_LOOP_OK from end_send() if procedure is active
modified:
mysql-test/r/analyse.result
mysql-test/t/analyse.test
sql/sql_select.cc
=== modified file 'mysql-test/r/analyse.result'
--- a/mysql-test/r/analyse.result 2011-03-14 18:03:22 +0000
+++ b/mysql-test/r/analyse.result 2011-04-08 08:45:29 +0000
@@ -135,4 +135,14 @@ SELECT * FROM t1 PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
test.t1.a e e- 1 2 0 0 1.3333 NULL ENUM('e','e-') NOT NULL
DROP TABLE t1;
+#
+# Bug#11756242 48137: PROCEDURE ANALYSE() LEAKS MEMORY WHEN RETURNING NULL
+#
+CREATE TABLE t1(f1 INT) ENGINE=MYISAM;
+CREATE TABLE t2(f2 INT) ENGINE=INNODB;
+INSERT INTO t2 VALUES (1);
+SELECT DISTINCTROW f1 FROM t1 NATURAL RIGHT OUTER JOIN t2 PROCEDURE ANALYSE();
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f1 NULL NULL 0 0 0 1 0.0 0.0 CHAR(0)
+DROP TABLE t1, t2;
End of 5.1 tests
=== modified file 'mysql-test/t/analyse.test'
--- a/mysql-test/t/analyse.test 2011-03-14 18:03:22 +0000
+++ b/mysql-test/t/analyse.test 2011-04-08 08:45:29 +0000
@@ -1,6 +1,7 @@
#
# Test of procedure analyse
#
+-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1,t2;
@@ -144,4 +145,14 @@ INSERT INTO t1 VALUES ('e'),('e'),('e-')
SELECT * FROM t1 PROCEDURE ANALYSE();
DROP TABLE t1;
+--echo #
+--echo # Bug#11756242 48137: PROCEDURE ANALYSE() LEAKS MEMORY WHEN RETURNING NULL
+--echo #
+
+CREATE TABLE t1(f1 INT) ENGINE=MYISAM;
+CREATE TABLE t2(f2 INT) ENGINE=INNODB;
+INSERT INTO t2 VALUES (1);
+SELECT DISTINCTROW f1 FROM t1 NATURAL RIGHT OUTER JOIN t2 PROCEDURE ANALYSE();
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2011-02-22 21:03:32 +0000
+++ b/sql/sql_select.cc 2011-04-08 08:45:29 +0000
@@ -1929,7 +1929,11 @@ JOIN::exec()
if (!curr_join->sort_and_group &&
curr_join->const_tables != curr_join->tables)
curr_join->join_tab[curr_join->const_tables].sorted= 0;
- if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
+
+ Procedure *save_proc= curr_join->procedure;
+ tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0);
+ curr_join->procedure= save_proc;
+ if (tmp_error)
{
error= tmp_error;
DBUG_VOID_RETURN;
@@ -12354,10 +12358,14 @@ end_send(JOIN *join, JOIN_TAB *join_tab
int error;
if (join->having && join->having->val_int() == 0)
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
- error=0;
if (join->procedure)
- error=join->procedure->send_row(join->procedure_fields_list);
- else if (join->do_send_rows)
+ {
+ if (join->procedure->send_row(join->procedure_fields_list))
+ DBUG_RETURN(NESTED_LOOP_ERROR);
+ DBUG_RETURN(NESTED_LOOP_OK);
+ }
+ error=0;
+ if (join->do_send_rows)
error=join->result->send_data(*join->fields);
if (error)
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
Attachment: [text/bzr-bundle] bzr/sergey.glukhov@oracle.com-20110408084529-ighkkh6m1p94mk0g.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (sergey.glukhov:3645) Bug#11756242 | Sergey Glukhov | 8 Apr |