diff --git a/mysql-test/main/sp-memory-leak.result b/mysql-test/main/sp-memory-leak.result index aea278801d8..37a0f119341 100644 --- a/mysql-test/main/sp-memory-leak.result +++ b/mysql-test/main/sp-memory-leak.result @@ -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 diff --git a/mysql-test/main/sp-memory-leak.test b/mysql-test/main/sp-memory-leak.test index 5b346aa8b10..0035044209a 100644 --- a/mysql-test/main/sp-memory-leak.test +++ b/mysql-test/main/sp-memory-leak.test @@ -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 ;$$ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2e3ce7d7503..5538fdd04e6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3429,7 +3429,11 @@ public: 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; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 601ff119fc3..524da7be4c3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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 li(*$$); + while ((elem= li++)) + { + if (!elem->sp_lex_in_use) + delete elem; + } + } +} + + %type option_type opt_var_type opt_var_ident_type