Loading mysql-test/r/sp-code.result +109 −0 Original line number Diff line number Diff line Loading @@ -733,6 +733,115 @@ optimizer: keep hreturn drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; drop procedure if exists proc_33618_h; drop procedure if exists proc_33618_c; create procedure proc_33618_h(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare exit handler for 1062 begin end; fetch cur1 into vb; if (last_row = 1) then ## should generate a hpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// create procedure proc_33618_c(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare cur2 cursor for select `b` from t_33618; fetch cur1 into vb; if (last_row = 1) then ## should generate a cpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// show procedure code proc_33618_h; Pos Instruction 0 set count1@1 _latin1'0' 1 set vb@2 NULL 2 set last_row@3 NULL 3 jump_if_not 24(24) (num@0 >= 1) 4 set num@0 (num@0 - 1) 5 cpush cur1@0 6 hpush_jump 9 4 CONTINUE 7 set last_row@3 1 8 hreturn 4 9 set last_row@3 0 10 copen cur1@0 11 hpush_jump 13 4 EXIT 12 hreturn 0 17 13 cfetch cur1@0 vb@2 14 jump_if_not 17(17) (last_row@3 = 1) 15 hpop 1 16 jump 19 17 hpop 1 18 jump_if_not 11(19) (last_row@3 = 1) 19 cclose cur1@0 20 hpop 1 21 cpop 1 22 jump 3 show procedure code proc_33618_c; Pos Instruction 0 set count1@1 _latin1'0' 1 set vb@2 NULL 2 set last_row@3 NULL 3 jump_if_not 23(23) (num@0 >= 1) 4 set num@0 (num@0 - 1) 5 cpush cur1@0 6 hpush_jump 9 4 CONTINUE 7 set last_row@3 1 8 hreturn 4 9 set last_row@3 0 10 copen cur1@0 11 cpush cur2@1 12 cfetch cur1@0 vb@2 13 jump_if_not 16(16) (last_row@3 = 1) 14 cpop 1 15 jump 18 16 cpop 1 17 jump_if_not 11(18) (last_row@3 = 1) 18 cclose cur1@0 19 hpop 1 20 cpop 1 21 jump 3 drop procedure proc_33618_h; drop procedure proc_33618_c; End of 5.0 tests. CREATE PROCEDURE p1() BEGIN Loading mysql-test/t/sp-code.test +77 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,83 @@ drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; # # Bug#33618 Crash in sp_rcontext # --disable_warnings drop procedure if exists proc_33618_h; drop procedure if exists proc_33618_c; --enable_warnings delimiter //; create procedure proc_33618_h(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare exit handler for 1062 begin end; fetch cur1 into vb; if (last_row = 1) then ## should generate a hpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// create procedure proc_33618_c(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare cur2 cursor for select `b` from t_33618; fetch cur1 into vb; if (last_row = 1) then ## should generate a cpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// delimiter ;// show procedure code proc_33618_h; show procedure code proc_33618_c; drop procedure proc_33618_h; drop procedure proc_33618_c; --echo End of 5.0 tests. Loading sql/sp_head.cc +6 −0 Original line number Diff line number Diff line Loading @@ -2074,12 +2074,18 @@ sp_head::backpatch(sp_label_t *lab) uint dest= instructions(); List_iterator_fast<bp_t> li(m_backpatch); DBUG_ENTER("sp_head::backpatch"); while ((bp= li++)) { if (bp->lab == lab) { DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d", bp->instr->m_ip, (ulong) lab, lab->name, dest)); bp->instr->backpatch(dest, lab->ctx); } } DBUG_VOID_RETURN; } /* Prepare an instance of Create_field for field creation (fill all necessary Loading sql/sp_head.h +3 −2 Original line number Diff line number Diff line Loading @@ -877,7 +877,8 @@ class sp_instr_jump : public sp_instr_opt_meta virtual void backpatch(uint dest, sp_pcontext *dst_ctx) { if (m_dest == 0) // Don't reset /* Calling backpatch twice is a logic flaw in jump resolution. */ DBUG_ASSERT(m_dest == 0); m_dest= dest; } Loading sql/sp_rcontext.cc +75 −1 Original line number Diff line number Diff line Loading @@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno, void sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) { DBUG_ENTER("sp_rcontext::push_cursor"); DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index()); m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i); DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); DBUG_VOID_RETURN; } void sp_rcontext::pop_cursors(uint count) { DBUG_ENTER("sp_rcontext::pop_cursors"); DBUG_ASSERT(m_ccount >= count); while (count--) { delete m_cstack[--m_ccount]; } DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); DBUG_VOID_RETURN; } void sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f) { DBUG_ENTER("sp_rcontext::push_handler"); DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index()); m_handler[m_hcount].cond= cond; m_handler[m_hcount].handler= h; m_handler[m_hcount].type= type; m_handler[m_hcount].foffset= f; m_hcount+= 1; DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); DBUG_VOID_RETURN; } void sp_rcontext::pop_handlers(uint count) { DBUG_ENTER("sp_rcontext::pop_handlers"); DBUG_ASSERT(m_hcount >= count); m_hcount-= count; DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); DBUG_VOID_RETURN; } void sp_rcontext::push_hstack(uint h) { DBUG_ENTER("sp_rcontext::push_hstack"); DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index()); m_hstack[m_hsp++]= h; DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); DBUG_VOID_RETURN; } uint sp_rcontext::pop_hstack() { uint handler; DBUG_ENTER("sp_rcontext::pop_hstack"); DBUG_ASSERT(m_hsp); handler= m_hstack[--m_hsp]; DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); DBUG_RETURN(handler); } void sp_rcontext::enter_handler(int hid) { DBUG_ENTER("sp_rcontext::enter_handler"); DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index()); m_in_handler[m_ihsp++]= hid; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } void sp_rcontext::exit_handler() { DBUG_ENTER("sp_rcontext::exit_handler"); DBUG_ASSERT(m_ihsp); m_ihsp-= 1; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } Loading Loading
mysql-test/r/sp-code.result +109 −0 Original line number Diff line number Diff line Loading @@ -733,6 +733,115 @@ optimizer: keep hreturn drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; drop procedure if exists proc_33618_h; drop procedure if exists proc_33618_c; create procedure proc_33618_h(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare exit handler for 1062 begin end; fetch cur1 into vb; if (last_row = 1) then ## should generate a hpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// create procedure proc_33618_c(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare cur2 cursor for select `b` from t_33618; fetch cur1 into vb; if (last_row = 1) then ## should generate a cpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// show procedure code proc_33618_h; Pos Instruction 0 set count1@1 _latin1'0' 1 set vb@2 NULL 2 set last_row@3 NULL 3 jump_if_not 24(24) (num@0 >= 1) 4 set num@0 (num@0 - 1) 5 cpush cur1@0 6 hpush_jump 9 4 CONTINUE 7 set last_row@3 1 8 hreturn 4 9 set last_row@3 0 10 copen cur1@0 11 hpush_jump 13 4 EXIT 12 hreturn 0 17 13 cfetch cur1@0 vb@2 14 jump_if_not 17(17) (last_row@3 = 1) 15 hpop 1 16 jump 19 17 hpop 1 18 jump_if_not 11(19) (last_row@3 = 1) 19 cclose cur1@0 20 hpop 1 21 cpop 1 22 jump 3 show procedure code proc_33618_c; Pos Instruction 0 set count1@1 _latin1'0' 1 set vb@2 NULL 2 set last_row@3 NULL 3 jump_if_not 23(23) (num@0 >= 1) 4 set num@0 (num@0 - 1) 5 cpush cur1@0 6 hpush_jump 9 4 CONTINUE 7 set last_row@3 1 8 hreturn 4 9 set last_row@3 0 10 copen cur1@0 11 cpush cur2@1 12 cfetch cur1@0 vb@2 13 jump_if_not 16(16) (last_row@3 = 1) 14 cpop 1 15 jump 18 16 cpop 1 17 jump_if_not 11(18) (last_row@3 = 1) 18 cclose cur1@0 19 hpop 1 20 cpop 1 21 jump 3 drop procedure proc_33618_h; drop procedure proc_33618_c; End of 5.0 tests. CREATE PROCEDURE p1() BEGIN Loading
mysql-test/t/sp-code.test +77 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,83 @@ drop table t1; drop procedure proc_26977_broken; drop procedure proc_26977_works; # # Bug#33618 Crash in sp_rcontext # --disable_warnings drop procedure if exists proc_33618_h; drop procedure if exists proc_33618_c; --enable_warnings delimiter //; create procedure proc_33618_h(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare exit handler for 1062 begin end; fetch cur1 into vb; if (last_row = 1) then ## should generate a hpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// create procedure proc_33618_c(num int) begin declare count1 int default '0'; declare vb varchar(30); declare last_row int; while(num>=1) do set num=num-1; begin declare cur1 cursor for select `a` from t_33618; declare continue handler for not found set last_row = 1; set last_row:=0; open cur1; rep1: repeat begin declare cur2 cursor for select `b` from t_33618; fetch cur1 into vb; if (last_row = 1) then ## should generate a cpop instruction here leave rep1; end if; end; until last_row=1 end repeat; close cur1; end; end while; end// delimiter ;// show procedure code proc_33618_h; show procedure code proc_33618_c; drop procedure proc_33618_h; drop procedure proc_33618_c; --echo End of 5.0 tests. Loading
sql/sp_head.cc +6 −0 Original line number Diff line number Diff line Loading @@ -2074,12 +2074,18 @@ sp_head::backpatch(sp_label_t *lab) uint dest= instructions(); List_iterator_fast<bp_t> li(m_backpatch); DBUG_ENTER("sp_head::backpatch"); while ((bp= li++)) { if (bp->lab == lab) { DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d", bp->instr->m_ip, (ulong) lab, lab->name, dest)); bp->instr->backpatch(dest, lab->ctx); } } DBUG_VOID_RETURN; } /* Prepare an instance of Create_field for field creation (fill all necessary Loading
sql/sp_head.h +3 −2 Original line number Diff line number Diff line Loading @@ -877,7 +877,8 @@ class sp_instr_jump : public sp_instr_opt_meta virtual void backpatch(uint dest, sp_pcontext *dst_ctx) { if (m_dest == 0) // Don't reset /* Calling backpatch twice is a logic flaw in jump resolution. */ DBUG_ASSERT(m_dest == 0); m_dest= dest; } Loading
sql/sp_rcontext.cc +75 −1 Original line number Diff line number Diff line Loading @@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno, void sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) { DBUG_ENTER("sp_rcontext::push_cursor"); DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index()); m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i); DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); DBUG_VOID_RETURN; } void sp_rcontext::pop_cursors(uint count) { DBUG_ENTER("sp_rcontext::pop_cursors"); DBUG_ASSERT(m_ccount >= count); while (count--) { delete m_cstack[--m_ccount]; } DBUG_PRINT("info", ("m_ccount: %d", m_ccount)); DBUG_VOID_RETURN; } void sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f) { DBUG_ENTER("sp_rcontext::push_handler"); DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index()); m_handler[m_hcount].cond= cond; m_handler[m_hcount].handler= h; m_handler[m_hcount].type= type; m_handler[m_hcount].foffset= f; m_hcount+= 1; DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); DBUG_VOID_RETURN; } void sp_rcontext::pop_handlers(uint count) { DBUG_ENTER("sp_rcontext::pop_handlers"); DBUG_ASSERT(m_hcount >= count); m_hcount-= count; DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); DBUG_VOID_RETURN; } void sp_rcontext::push_hstack(uint h) { DBUG_ENTER("sp_rcontext::push_hstack"); DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index()); m_hstack[m_hsp++]= h; DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); DBUG_VOID_RETURN; } uint sp_rcontext::pop_hstack() { uint handler; DBUG_ENTER("sp_rcontext::pop_hstack"); DBUG_ASSERT(m_hsp); handler= m_hstack[--m_hsp]; DBUG_PRINT("info", ("m_hsp: %d", m_hsp)); DBUG_RETURN(handler); } void sp_rcontext::enter_handler(int hid) { DBUG_ENTER("sp_rcontext::enter_handler"); DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index()); m_in_handler[m_ihsp++]= hid; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } void sp_rcontext::exit_handler() { DBUG_ENTER("sp_rcontext::exit_handler"); DBUG_ASSERT(m_ihsp); m_ihsp-= 1; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } Loading