diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-12-11 15:09:17 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-12-12 16:25:16 +0400 |
commit | e0f9540bcc6ab1618b6fd475f02e019401c4c295 (patch) | |
tree | da554e11e2ad9c9eea4b67efc7e221ce4609564c /sql/sp_head.cc | |
parent | ce47e66516ec1319dacaa3880d21622af6e00ad7 (diff) | |
download | mariadb-git-e0f9540bcc6ab1618b6fd475f02e019401c4c295.tar.gz |
MDEV-20667 Server crash on pop_cursor
When backpatching a forward GOTO label, the old code erroneously
used CURSOR/HANDLER difference between context frames "c" and "a" to tune
a cpop/hpop command. So the cpop/hpop command later tried to pop
all cursors/handlers declared between "a" and "c", but those between
"b" and "c" were not cpushed/hpoped yet during the execution of "GOTO x".
Fixing the code to use the difference between frames "b" and "a" only.
BEGIN -- a
...
GOTO x; -- b
...
<<x>> -- c
...
END -- d
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ab7faf51849..360713fc452 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2571,7 +2571,7 @@ sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block) } if (bp->instr_type == CPOP) { - uint n= lab->ctx->diff_cursors(lab_begin_block->ctx, true); + uint n= bp->instr->m_ctx->diff_cursors(lab_begin_block->ctx, true); if (n == 0) { // Remove cpop instr @@ -2588,7 +2588,7 @@ sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block) } if (bp->instr_type == HPOP) { - uint n= lab->ctx->diff_handlers(lab_begin_block->ctx, true); + uint n= bp->instr->m_ctx->diff_handlers(lab_begin_block->ctx, true); if (n == 0) { // Remove hpop instr @@ -3082,6 +3082,8 @@ void sp_head::optimize() sp_instr *i; uint src, dst; + DBUG_EXECUTE_IF("sp_head_optimize_disable", return; ); + opt_mark(); bp.empty(); |