summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-12-11 15:09:17 +0400
committerAlexander Barkov <bar@mariadb.com>2019-12-12 16:25:16 +0400
commite0f9540bcc6ab1618b6fd475f02e019401c4c295 (patch)
treeda554e11e2ad9c9eea4b67efc7e221ce4609564c /sql/sp_head.cc
parentce47e66516ec1319dacaa3880d21622af6e00ad7 (diff)
downloadmariadb-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.cc6
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();