Commit ec6c4fad authored by malff@lambda.hsd1.co.comcast.net's avatar malff@lambda.hsd1.co.comcast.net

Merge lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.0-33618

into  lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-33618
parents e5ed653e 7bd56cfa
...@@ -733,6 +733,115 @@ optimizer: keep hreturn ...@@ -733,6 +733,115 @@ optimizer: keep hreturn
drop table t1; drop table t1;
drop procedure proc_26977_broken; drop procedure proc_26977_broken;
drop procedure proc_26977_works; 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. End of 5.0 tests.
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
BEGIN BEGIN
......
...@@ -520,6 +520,83 @@ drop table t1; ...@@ -520,6 +520,83 @@ drop table t1;
drop procedure proc_26977_broken; drop procedure proc_26977_broken;
drop procedure proc_26977_works; 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. --echo End of 5.0 tests.
......
...@@ -2074,11 +2074,17 @@ sp_head::backpatch(sp_label_t *lab) ...@@ -2074,11 +2074,17 @@ sp_head::backpatch(sp_label_t *lab)
uint dest= instructions(); uint dest= instructions();
List_iterator_fast<bp_t> li(m_backpatch); List_iterator_fast<bp_t> li(m_backpatch);
DBUG_ENTER("sp_head::backpatch");
while ((bp= li++)) while ((bp= li++))
{ {
if (bp->lab == lab) 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); bp->instr->backpatch(dest, lab->ctx);
}
} }
DBUG_VOID_RETURN;
} }
/* /*
......
...@@ -877,8 +877,9 @@ class sp_instr_jump : public sp_instr_opt_meta ...@@ -877,8 +877,9 @@ class sp_instr_jump : public sp_instr_opt_meta
virtual void backpatch(uint dest, sp_pcontext *dst_ctx) 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. */
m_dest= dest; DBUG_ASSERT(m_dest == 0);
m_dest= dest;
} }
/* /*
......
...@@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno, ...@@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno,
void void
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) 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); m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
DBUG_VOID_RETURN;
} }
void void
sp_rcontext::pop_cursors(uint count) sp_rcontext::pop_cursors(uint count)
{ {
DBUG_ENTER("sp_rcontext::pop_cursors");
DBUG_ASSERT(m_ccount >= count);
while (count--) while (count--)
{ {
delete m_cstack[--m_ccount]; 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;
} }
......
...@@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc ...@@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc
return m_return_value_set; return m_return_value_set;
} }
inline void void push_handler(struct sp_cond_type *cond, uint h, int type, uint f);
push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
{
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;
}
inline void void pop_handlers(uint count);
pop_handlers(uint count)
{
m_hcount-= count;
}
// Returns 1 if a handler was found, 0 otherwise. // Returns 1 if a handler was found, 0 otherwise.
bool bool
...@@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc ...@@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc
m_hfound= -1; m_hfound= -1;
} }
inline void void push_hstack(uint h);
push_hstack(uint h)
{
m_hstack[m_hsp++]= h;
}
inline uint uint pop_hstack();
pop_hstack()
{
return m_hstack[--m_hsp];
}
inline void void enter_handler(int hid);
enter_handler(int hid)
{
m_in_handler[m_ihsp++]= hid;
}
inline void void exit_handler();
exit_handler()
{
m_ihsp-= 1;
}
void void
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i); push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
......
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