Commit 5e6c1224 authored by Dmitry Shulga's avatar Dmitry Shulga Committed by Unknown

MDEV-33769: Memory leak found in the test main.rownum run with --ps-protocol...

MDEV-33769: Memory leak found in the test main.rownum run with --ps-protocol against a server built with the option -DWITH_PROTECT_STATEMENT_MEMROOT

A memory leak happens on the second execution of a query that run in PS mode
and uses the function ROWNUM().

A memory leak took place on allocation of an instance of the class Item_int
for storing a limit value that is performed at the function set_limit_for_unit
indirectly called from JOIN::optimize_inner. Typical trace to the place where
the memory leak occurred is below:
 JOIN::optimize_inner
  optimize_rownum
   process_direct_rownum_comparison
    set_limit_for_unit
     new (thd->mem_root) Item_int(thd, lim, MAX_BIGINT_WIDTH);

To fix this memory leak, calling of the function optimize_rownum()
has to be performed only once on first execution and never called
after that. To control it, the new data member
  first_rownum_optimization
added into the structure st_select_lex.
parent 6bf2b64a
......@@ -89,3 +89,32 @@ f
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
# End of 10.4 tests
#
# MDEV-33769: Memory leak found in the test main.rownum run with --ps-protocol against a server built with the option -DWITH_PROTECT_STATEMENT_MEMROOT
#
CREATE OR REPLACE TABLE t1(a INT);
PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE ROWNUM() < 2';
EXECUTE stmt;
1
EXECUTE stmt;
1
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
PREPARE stmt FROM 'SELECT * FROM t1 WHERE ROWNUM() < ?';
# Expected output is two rows (1), (2)
EXECUTE stmt USING 3;
a
1
2
# Expected output is one row (1)
EXECUTE stmt USING 2;
a
1
# Expected output is three rows (1), (2), (3)
EXECUTE stmt USING 4;
a
1
2
# Clean up
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
# End of 10.6 tests
......@@ -110,3 +110,27 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo # End of 10.4 tests
--echo #
--echo # MDEV-33769: Memory leak found in the test main.rownum run with --ps-protocol against a server built with the option -DWITH_PROTECT_STATEMENT_MEMROOT
--echo #
CREATE OR REPLACE TABLE t1(a INT);
PREPARE stmt FROM 'SELECT 1 FROM t1 WHERE ROWNUM() < 2';
EXECUTE stmt;
EXECUTE stmt;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
PREPARE stmt FROM 'SELECT * FROM t1 WHERE ROWNUM() < ?';
--echo # Expected output is two rows (1), (2)
EXECUTE stmt USING 3;
--echo # Expected output is one row (1)
EXECUTE stmt USING 2;
--echo # Expected output is three rows (1), (2), (3)
EXECUTE stmt USING 4;
--echo # Clean up
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo # End of 10.6 tests
......@@ -3051,6 +3051,7 @@ void st_select_lex::init_query()
is_correlated= 0;
first_natural_join_processing= 1;
first_cond_optimization= 1;
first_rownum_optimization= true;
no_wrap_view_item= 0;
exclude_from_table_unique_test= 0;
in_tvc= 0;
......
......@@ -1262,6 +1262,13 @@ class st_select_lex: public st_select_lex_node
bool is_correlated:1;
bool first_natural_join_processing:1;
bool first_cond_optimization:1;
/**
The purpose of this flag is to run initialization phase for rownum
only once. This flag is set on at st_select_lex::init_query and reset to
the value false after the method optimize_rownum() has been called
from the method JOIN::optimize_inner.
*/
bool first_rownum_optimization:1;
/* do not wrap view fields with Item_ref */
bool no_wrap_view_item:1;
/* exclude this select from check of unique_table() */
......
......@@ -2312,8 +2312,12 @@ JOIN::optimize_inner()
DBUG_RETURN(1);
}
if (select_lex->with_rownum && ! order && ! group_list &&
!select_distinct && conds && select_lex == unit->global_parameters())
!select_distinct && conds && select_lex == unit->global_parameters() &&
select_lex->first_rownum_optimization)
{
optimize_rownum(thd, unit, conds);
select_lex->first_rownum_optimization= false;
}
having= optimize_cond(this, having, join_list, TRUE,
&having_value, &having_equal);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment