Skip to content

Commit

Permalink
MDEV-32466: Potential memory leak on executing of create view statement
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dmitryshulga committed Nov 24, 2023
1 parent bdfd93d commit 5064750
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 5 deletions.
22 changes: 22 additions & 0 deletions mysql-test/main/ps_mem_leaks.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
28 changes: 28 additions & 0 deletions mysql-test/main/ps_mem_leaks.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion sql/sp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
{
Expand Down
11 changes: 11 additions & 0 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand Down
5 changes: 3 additions & 2 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 5064750

Please sign in to comment.