mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
0d3720c12a
The parser works as follows: The rule expr_lex returns a pointer to a newly created sp_expr_lex instance which is not linked to any MariaDB structures yet - it is pointed only from a Bison stack variable. The sp_expr_lex instance gets linked to other structures (such as sp_instr_jump_if_not) later, after scanning some following grammar. Problem before the fix: If a parse error happened immediately after expr_lex (before it got linked), the created sp_expr_lex value got lost causing a memory leak. Fix: - Using Bison's "destructor" directive to free the results of expr_lex on parse/oom errors. - Moving the call for LEX::cleanup_lex_after_parse_error() from MYSQL_YYABORT and yyerror inside parse_sql(). This is needed because Bison calls destructors after yyerror(), while it's important to delete the sp_expr_lex instance before LEX::cleanup_lex_after_parse_error(). The latter frees the memory root containing the sp_expr_lex instance. After this change the code block are executed in the following order: - yyerror() -- now only raises the error to DA (no cleanup done any more) - %destructor { delete $$; } <expr_lex> -- destructs the sp_expr_lex instance - LEX::cleanup_lex_after_parse_error() -- frees the memory root containing the sp_expr_lex instance - Removing the "delete sublex" related code from restore_lex(): - restore_lex() is called in most cases on success, when delete is not needed. - There is one place when restore_lex() is called on error: In sp_create_assignment_instr(). But in this case LEX::sp_lex_in_use is true anyway. The patch adds a new DBUG_ASSERT(lex->sp_lex_in_use) to guard this.
29 lines
476 B
Text
29 lines
476 B
Text
--echo #
|
|
--echo # MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks
|
|
--echo #
|
|
|
|
DELIMITER $$;
|
|
--error ER_PARSE_ERROR
|
|
BEGIN NOT ATOMIC
|
|
IF SCALAR() expected_THEN_here;
|
|
END
|
|
$$
|
|
DELIMITER ;$$
|
|
|
|
|
|
DELIMITER $$;
|
|
--error ER_PARSE_ERROR
|
|
BEGIN NOT ATOMIC
|
|
WHILE SCALAR() expected_DO_here;
|
|
END
|
|
$$
|
|
DELIMITER ;$$
|
|
|
|
|
|
DELIMITER $$;
|
|
--error ER_PARSE_ERROR
|
|
BEGIN NOT ATOMIC
|
|
REPEAT SELECT 1; UNTIL SCALAR() expected_END_here;
|
|
END
|
|
$$
|
|
DELIMITER ;$$
|