Commit 1a5c4c2d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-26186 280 Bytes lost in mysys/array.c, mysys/hash.c, sql/sp.cc,...

MDEV-26186 280 Bytes lost in mysys/array.c, mysys/hash.c, sql/sp.cc, sql/sp.cc, sql/item_create.cc, sql/item_create.cc, sql/sql_yacc.yy:10748 when using oracle sql_mode

There was a memory leak under these conditions:
- YYABORT was called in the end-of-rule action of a rule containing expr_lex
- This expr_lex was not bound to any sp_lex_keeper

Bison did not call %destructor <expr_lex> in this case, because its stack
already contained a reduced upper-level rule.

Fixing rules starting with RETURN, CONTINUE, EXIT keywords:

Turning end-of-rule actions with YYABORT into mid-rule actions
by adding an empty trailing { } block. This prevents the upper level
rule from being reduced without calling %destructor <expr_lex>.

In other rules expr_lex is used not immediately before the last
end-of-rule { } block, so they don't need changes.
parent 68403eed
#
# Start of 10.5 tests
#
#
# MDEV-26186 280 Bytes lost in mysys/array.c, mysys/hash.c, sql/sp.cc, sql/sp.cc, sql/item_create.cc, sql/item_create.cc, sql/sql_yacc.yy:10748 when using oracle sql_mode
#
SET sql_mode= 'oracle';
BEGIN CONTINUE WHEN f0();
ERROR 42000: CONTINUE with no matching label:
SET sql_mode= 'oracle';
BEGIN CONTINUE label WHEN f0();
ERROR 42000: CONTINUE with no matching label: label
SET sql_mode= 'oracle';
BEGIN EXIT WHEN f0();
ERROR 42000: EXIT with no matching label:
SET sql_mode= 'oracle';
BEGIN EXIT label WHEN f0();
ERROR 42000: EXIT with no matching label: label
SET sql_mode= 'oracle';
WHILE f(8)<1 DO SELECT 1;;
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 'DO SELECT 1' at line 1
SET sql_mode= 'oracle';
BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f0();
ERROR 42000: RETURN is only allowed in a FUNCTION
#
# End of 10.5 tests
#
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-26186 280 Bytes lost in mysys/array.c, mysys/hash.c, sql/sp.cc, sql/sp.cc, sql/item_create.cc, sql/item_create.cc, sql/sql_yacc.yy:10748 when using oracle sql_mode
--echo #
SET sql_mode= 'oracle';
--error ER_SP_LILABEL_MISMATCH
BEGIN CONTINUE WHEN f0();
SET sql_mode= 'oracle';
--error ER_SP_LILABEL_MISMATCH
BEGIN CONTINUE label WHEN f0();
SET sql_mode= 'oracle';
--error ER_SP_LILABEL_MISMATCH
BEGIN EXIT WHEN f0();
SET sql_mode= 'oracle';
--error ER_SP_LILABEL_MISMATCH
BEGIN EXIT label WHEN f0();
SET sql_mode= 'oracle';
--error ER_PARSE_ERROR
--query WHILE f(8)<1 DO SELECT 1;
SET sql_mode= 'oracle';
--error ER_SP_BADRETURN
BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f0();
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -1526,6 +1526,43 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
delete $$;
} <expr_lex>
/*
// COMMENT_FOR_DESCTRUCTOR:
//
// %destructor is only invoked if the rule parsing fails in the middle.
// If we call YYABORT from the last code block %destructor is not called,
// because Bison's stack already contains the reduced upper level rule.
// If we need to invoke the %destructor after the YYABORT in the last code
// block, we have to add another dummy empty end-of-rule action {} at the end.
// So to have a %destructor work properly with YYABORT,
// make sure to turn a grammar like this:
rule:
KEYWORD expr_lex
{
if (condition) // End-of-rule action
YYABORT;
}
;
// into:
rule:
KEYWORD expr_lex
{
if (condition) // This is now a mid-rule action
YYABORT;
}
{
// A dummy empty end-of-rule action.
}
;
*/
%type <assignment_lex>
assignment_source_lex
assignment_source_expr
......@@ -3731,6 +3768,7 @@ sp_proc_stmt_return:
$2->get_item(), $2)))
MYSQL_YYABORT;
}
{ /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
| RETURN_ORACLE_SYM
{
LEX *lex= Lex;
......@@ -3757,11 +3795,13 @@ sp_proc_stmt_exit_oracle:
if (unlikely($3->sp_exit_statement(thd, $3->get_item())))
MYSQL_YYABORT;
}
{ /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
| EXIT_ORACLE_SYM label_ident WHEN_SYM expr_lex
{
if (unlikely($4->sp_exit_statement(thd, &$2, $4->get_item())))
MYSQL_YYABORT;
}
{ /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
;
sp_proc_stmt_continue_oracle:
......@@ -3780,11 +3820,13 @@ sp_proc_stmt_continue_oracle:
if (unlikely($3->sp_continue_when_statement(thd)))
MYSQL_YYABORT;
}
{ /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
| CONTINUE_ORACLE_SYM label_ident WHEN_SYM expr_lex
{
if (unlikely($4->sp_continue_when_statement(thd, &$2)))
MYSQL_YYABORT;
}
{ /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
;
......
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