Commit 5064750f authored by Dmitry Shulga's avatar Dmitry Shulga

MDEV-32466: Potential memory leak on executing of create view statement

This patch is actually follow-up for the task
  MDEV-23902: MariaDB crash on calling function
to use correct query arena for a statement. In case invocation of
a function is in progress use its call arena, else use current
query arena that can be either a statement or a regular query arena.
parent bdfd93d3
......@@ -57,4 +57,26 @@ EXECUTE stmt;
exp
0
DEALLOCATE PREPARE stmt;
#
# MDEV-32466: Potential memory leak on execuing of create view statement
#
CREATE FUNCTION f1 () RETURNS VARCHAR(1)
BEGIN
DECLARE rec1 ROW TYPE OF v1;
SELECT z INTO rec1 FROM v1;
RETURN 1;
END|
CREATE FUNCTION f2 () RETURNS VARCHAR(1) RETURN '!';
CREATE VIEW v1 AS SELECT f2() z;
PREPARE stmt FROM "SELECT f1()";
EXECUTE stmt;
f1()
1
EXECUTE stmt;
f1()
1
DEALLOCATE PREPARE stmt;
DROP FUNCTION f1;
DROP VIEW v1;
DROP FUNCTION f2;
# End of 10.4 tests
......@@ -69,4 +69,32 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
--echo #
--echo # MDEV-32466: Potential memory leak on execuing of create view statement
--echo #
--delimiter |
CREATE FUNCTION f1 () RETURNS VARCHAR(1)
BEGIN
DECLARE rec1 ROW TYPE OF v1;
SELECT z INTO rec1 FROM v1;
RETURN 1;
END|
--delimiter ;
CREATE FUNCTION f2 () RETURNS VARCHAR(1) RETURN '!';
CREATE VIEW v1 AS SELECT f2() z;
PREPARE stmt FROM "SELECT f1()";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
# Clean up
DROP FUNCTION f1;
DROP VIEW v1;
DROP FUNCTION f2;
--echo # End of 10.4 tests
......@@ -2720,7 +2720,8 @@ void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *belong_to_view)
{
for (Sroutine_hash_entry *rt= src->first; rt; rt= rt->next)
(void)sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
(void)sp_add_used_routine(prelocking_ctx, thd->active_stmt_arena_to_use(),
&rt->mdl_request.key, rt->m_handler,
belong_to_view);
}
......
......@@ -7740,7 +7740,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
while ((item= it++))
{
if (make_pre_fix)
pre_fix->push_back(item, thd->stmt_arena->mem_root);
pre_fix->push_back(item, thd->active_stmt_arena_to_use()->mem_root);
if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
{
......
......@@ -2790,6 +2790,17 @@ class THD: public THD_count, /* this must be first */
*/
Query_arena *stmt_arena;
/**
Get either call or statement arena. In case some function is called from
within a query the call arena has to be used for a memory allocation,
else use the statement arena.
*/
Query_arena *active_stmt_arena_to_use()
{
return (state == Query_arena::STMT_SP_QUERY_ARGUMENTS) ? this :
stmt_arena;
}
void *bulk_param;
/*
......
......@@ -3115,8 +3115,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
uint n_elems= get_cardinality_of_ref_ptrs_slice(order_group_num) * 5;
if (!ref_pointer_array.is_null())
return false;
Item **array= static_cast<Item**>(thd->stmt_arena->alloc(sizeof(Item*) *
n_elems));
Item **array= static_cast<Item**>(
thd->active_stmt_arena_to_use()->alloc(sizeof(Item*) * n_elems));
if (likely(array != NULL))
ref_pointer_array= Ref_ptr_array(array, n_elems);
return array == NULL;
......
......@@ -1655,7 +1655,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
objects of the view.
*/
if (!(table->view_sctx= (Security_context *)
thd->stmt_arena->calloc(sizeof(Security_context))))
thd->active_stmt_arena_to_use()->calloc(sizeof(Security_context))))
goto err;
security_ctx= table->view_sctx;
}
......
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