Skip to content

Commit

Permalink
MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on synt…
Browse files Browse the repository at this point in the history
…ax error

When CURSOR parameters get parsed, their sp_assignment_lex instances
(one instance per parameter) get collected to List<sp_assignment_lex>.

These instances get linked to sphead only in the end of the list.
If a syntax error happened in the middle of the parameter list,
these instances were not deleted, which caused memory leaks.

Fix:

using a Bison %destructor to free rules of the <sp_assignment_lex_list>
type (on syntax errors).

Afte the fix these sp_assignment_lex instances from CURSOR parameters
deleted as follows:

- If the CURSOR statement was fully parsed, then these instances
  get properly linked to sp_head structures, so they are deleted
  during ~sp_head (this did not change)

- If the CURSOR statement failed on a syntax error, then by Bison's
  %destructor (this is being added in the current patch).
  • Loading branch information
abarkov committed Jun 29, 2023
1 parent 0d3720c commit fdab2c4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 1 deletion.
21 changes: 21 additions & 0 deletions mysql-test/main/sp-memory-leak.result
Expand Up @@ -19,3 +19,24 @@ END
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_END_here;
END' at line 2
#
# MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error
#
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
CLOSE cur;
END' at line 3
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(1,sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
CLOSE cur;
END' at line 3
25 changes: 25 additions & 0 deletions mysql-test/main/sp-memory-leak.test
Expand Up @@ -27,3 +27,28 @@ BEGIN NOT ATOMIC
END
$$
DELIMITER ;$$


--echo #
--echo # MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error
--echo #

DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$

DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(1,sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$
6 changes: 5 additions & 1 deletion sql/sql_lex.h
Expand Up @@ -3429,7 +3429,11 @@ struct LEX: public Query_tables_list
sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling

void delete_if_not_sp_lex_in_use()
{
if (!sp_lex_in_use)
delete this;
}
sp_pcontext *spcont;

st_sp_chistics sp_chistics;
Expand Down
15 changes: 15 additions & 0 deletions sql/sql_yacc.yy
Expand Up @@ -1535,6 +1535,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
cursor_actual_parameters
opt_parenthesized_cursor_actual_parameters

%destructor
{
if ($$)
{
sp_assignment_lex *elem;
List_iterator<sp_assignment_lex> li(*$$);
while ((elem= li++))
{
if (!elem->sp_lex_in_use)
delete elem;
}
}
} <sp_assignment_lex_list>


%type <var_type>
option_type opt_var_type opt_var_ident_type

Expand Down

0 comments on commit fdab2c4

Please sign in to comment.