summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2012-01-09 11:28:02 +0100
committerJon Olav Hauglid <jon.hauglid@oracle.com>2012-01-09 11:28:02 +0100
commitb8291e2b60b311b621b15aff1dfec817da1bbf4c (patch)
tree72ca1c71906da75727e51474b01b58c7a6f16892 /sql/sql_yacc.yy
parent86505c3c545d3866a85464b0762b452d85599993 (diff)
downloadmariadb-git-b8291e2b60b311b621b15aff1dfec817da1bbf4c.tar.gz
Backport from mysql-trunk of:
------------------------------------------------------------ revno: 3258 committer: Jon Olav Hauglid <jon.hauglid@oracle.com> branch nick: mysql-trunk-bug12663165 timestamp: Thu 2011-07-14 10:05:12 +0200 message: Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS When stored routines are loaded, a simple optimizer tries to locate and remove dead code. The problem was that this dead code removal did not work correctly with CONTINUE handlers. If a statement triggers a CONTINUE handler, the following statement will be executed after the handler statement has completed. This means that the following statement is not dead code even if the previous statement unconditionally alters control flow. This fact was lost on the dead code removal routine, which ended up with removing instructions that could have been executed. This could then lead to assertions, crashes and generally bad behavior when the stored routine was executed. This patch fixes the problem by marking as live code all stored routine instructions that are in the same scope as a CONTINUE handler. Test case added to sp.test.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy12
1 files changed, 9 insertions, 3 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index facbc6d3e95..7e7ff7e91ca 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2532,9 +2532,15 @@ sp_decl:
sp_instr_hpush_jump *i=
new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
ctx->current_var_count());
- if (i == NULL ||
- sp->add_instr(i) ||
- sp->push_backpatch(i, ctx->push_label((char *)"", 0)))
+ if (i == NULL || sp->add_instr(i))
+ MYSQL_YYABORT;
+
+ /* For continue handlers, mark end of handler scope. */
+ if ($2 == SP_HANDLER_CONTINUE &&
+ sp->push_backpatch(i, ctx->last_label()))
+ MYSQL_YYABORT;
+
+ if (sp->push_backpatch(i, ctx->push_label(empty_c_string, 0)))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt