Skip to content

Commit ec6c4fa

Browse files
author
malff@lambda.hsd1.co.comcast.net.
committed
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
2 parents e5ed653 + 7bd56cf commit ec6c4fa

File tree

6 files changed

+276
-37
lines changed

6 files changed

+276
-37
lines changed

mysql-test/r/sp-code.result

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,115 @@ optimizer: keep hreturn
733733
drop table t1;
734734
drop procedure proc_26977_broken;
735735
drop procedure proc_26977_works;
736+
drop procedure if exists proc_33618_h;
737+
drop procedure if exists proc_33618_c;
738+
create procedure proc_33618_h(num int)
739+
begin
740+
declare count1 int default '0';
741+
declare vb varchar(30);
742+
declare last_row int;
743+
while(num>=1) do
744+
set num=num-1;
745+
begin
746+
declare cur1 cursor for select `a` from t_33618;
747+
declare continue handler for not found set last_row = 1;
748+
set last_row:=0;
749+
open cur1;
750+
rep1:
751+
repeat
752+
begin
753+
declare exit handler for 1062 begin end;
754+
fetch cur1 into vb;
755+
if (last_row = 1) then
756+
## should generate a hpop instruction here
757+
leave rep1;
758+
end if;
759+
end;
760+
until last_row=1
761+
end repeat;
762+
close cur1;
763+
end;
764+
end while;
765+
end//
766+
create procedure proc_33618_c(num int)
767+
begin
768+
declare count1 int default '0';
769+
declare vb varchar(30);
770+
declare last_row int;
771+
while(num>=1) do
772+
set num=num-1;
773+
begin
774+
declare cur1 cursor for select `a` from t_33618;
775+
declare continue handler for not found set last_row = 1;
776+
set last_row:=0;
777+
open cur1;
778+
rep1:
779+
repeat
780+
begin
781+
declare cur2 cursor for select `b` from t_33618;
782+
fetch cur1 into vb;
783+
if (last_row = 1) then
784+
## should generate a cpop instruction here
785+
leave rep1;
786+
end if;
787+
end;
788+
until last_row=1
789+
end repeat;
790+
close cur1;
791+
end;
792+
end while;
793+
end//
794+
show procedure code proc_33618_h;
795+
Pos Instruction
796+
0 set count1@1 _latin1'0'
797+
1 set vb@2 NULL
798+
2 set last_row@3 NULL
799+
3 jump_if_not 24(24) (num@0 >= 1)
800+
4 set num@0 (num@0 - 1)
801+
5 cpush cur1@0
802+
6 hpush_jump 9 4 CONTINUE
803+
7 set last_row@3 1
804+
8 hreturn 4
805+
9 set last_row@3 0
806+
10 copen cur1@0
807+
11 hpush_jump 13 4 EXIT
808+
12 hreturn 0 17
809+
13 cfetch cur1@0 vb@2
810+
14 jump_if_not 17(17) (last_row@3 = 1)
811+
15 hpop 1
812+
16 jump 19
813+
17 hpop 1
814+
18 jump_if_not 11(19) (last_row@3 = 1)
815+
19 cclose cur1@0
816+
20 hpop 1
817+
21 cpop 1
818+
22 jump 3
819+
show procedure code proc_33618_c;
820+
Pos Instruction
821+
0 set count1@1 _latin1'0'
822+
1 set vb@2 NULL
823+
2 set last_row@3 NULL
824+
3 jump_if_not 23(23) (num@0 >= 1)
825+
4 set num@0 (num@0 - 1)
826+
5 cpush cur1@0
827+
6 hpush_jump 9 4 CONTINUE
828+
7 set last_row@3 1
829+
8 hreturn 4
830+
9 set last_row@3 0
831+
10 copen cur1@0
832+
11 cpush cur2@1
833+
12 cfetch cur1@0 vb@2
834+
13 jump_if_not 16(16) (last_row@3 = 1)
835+
14 cpop 1
836+
15 jump 18
837+
16 cpop 1
838+
17 jump_if_not 11(18) (last_row@3 = 1)
839+
18 cclose cur1@0
840+
19 hpop 1
841+
20 cpop 1
842+
21 jump 3
843+
drop procedure proc_33618_h;
844+
drop procedure proc_33618_c;
736845
End of 5.0 tests.
737846
CREATE PROCEDURE p1()
738847
BEGIN

mysql-test/t/sp-code.test

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,83 @@ drop table t1;
520520
drop procedure proc_26977_broken;
521521
drop procedure proc_26977_works;
522522

523+
#
524+
# Bug#33618 Crash in sp_rcontext
525+
#
526+
527+
--disable_warnings
528+
drop procedure if exists proc_33618_h;
529+
drop procedure if exists proc_33618_c;
530+
--enable_warnings
531+
532+
delimiter //;
533+
534+
create procedure proc_33618_h(num int)
535+
begin
536+
declare count1 int default '0';
537+
declare vb varchar(30);
538+
declare last_row int;
539+
540+
while(num>=1) do
541+
set num=num-1;
542+
begin
543+
declare cur1 cursor for select `a` from t_33618;
544+
declare continue handler for not found set last_row = 1;
545+
set last_row:=0;
546+
open cur1;
547+
rep1:
548+
repeat
549+
begin
550+
declare exit handler for 1062 begin end;
551+
fetch cur1 into vb;
552+
if (last_row = 1) then
553+
## should generate a hpop instruction here
554+
leave rep1;
555+
end if;
556+
end;
557+
until last_row=1
558+
end repeat;
559+
close cur1;
560+
end;
561+
end while;
562+
end//
563+
564+
create procedure proc_33618_c(num int)
565+
begin
566+
declare count1 int default '0';
567+
declare vb varchar(30);
568+
declare last_row int;
569+
570+
while(num>=1) do
571+
set num=num-1;
572+
begin
573+
declare cur1 cursor for select `a` from t_33618;
574+
declare continue handler for not found set last_row = 1;
575+
set last_row:=0;
576+
open cur1;
577+
rep1:
578+
repeat
579+
begin
580+
declare cur2 cursor for select `b` from t_33618;
581+
fetch cur1 into vb;
582+
if (last_row = 1) then
583+
## should generate a cpop instruction here
584+
leave rep1;
585+
end if;
586+
end;
587+
until last_row=1
588+
end repeat;
589+
close cur1;
590+
end;
591+
end while;
592+
end//
593+
delimiter ;//
594+
595+
show procedure code proc_33618_h;
596+
show procedure code proc_33618_c;
597+
598+
drop procedure proc_33618_h;
599+
drop procedure proc_33618_c;
523600

524601
--echo End of 5.0 tests.
525602

sql/sp_head.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,11 +2074,17 @@ sp_head::backpatch(sp_label_t *lab)
20742074
uint dest= instructions();
20752075
List_iterator_fast<bp_t> li(m_backpatch);
20762076

2077+
DBUG_ENTER("sp_head::backpatch");
20772078
while ((bp= li++))
20782079
{
20792080
if (bp->lab == lab)
2081+
{
2082+
DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d",
2083+
bp->instr->m_ip, (ulong) lab, lab->name, dest));
20802084
bp->instr->backpatch(dest, lab->ctx);
2085+
}
20812086
}
2087+
DBUG_VOID_RETURN;
20822088
}
20832089

20842090
/*

sql/sp_head.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,8 +877,9 @@ class sp_instr_jump : public sp_instr_opt_meta
877877

878878
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
879879
{
880-
if (m_dest == 0) // Don't reset
881-
m_dest= dest;
880+
/* Calling backpatch twice is a logic flaw in jump resolution. */
881+
DBUG_ASSERT(m_dest == 0);
882+
m_dest= dest;
882883
}
883884

884885
/*

sql/sp_rcontext.cc

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno,
314314
void
315315
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
316316
{
317+
DBUG_ENTER("sp_rcontext::push_cursor");
318+
DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index());
317319
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
320+
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
321+
DBUG_VOID_RETURN;
318322
}
319323

320-
321324
void
322325
sp_rcontext::pop_cursors(uint count)
323326
{
327+
DBUG_ENTER("sp_rcontext::pop_cursors");
328+
DBUG_ASSERT(m_ccount >= count);
324329
while (count--)
325330
{
326331
delete m_cstack[--m_ccount];
327332
}
333+
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
334+
DBUG_VOID_RETURN;
335+
}
336+
337+
void
338+
sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
339+
{
340+
DBUG_ENTER("sp_rcontext::push_handler");
341+
DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index());
342+
343+
m_handler[m_hcount].cond= cond;
344+
m_handler[m_hcount].handler= h;
345+
m_handler[m_hcount].type= type;
346+
m_handler[m_hcount].foffset= f;
347+
m_hcount+= 1;
348+
349+
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
350+
DBUG_VOID_RETURN;
351+
}
352+
353+
void
354+
sp_rcontext::pop_handlers(uint count)
355+
{
356+
DBUG_ENTER("sp_rcontext::pop_handlers");
357+
DBUG_ASSERT(m_hcount >= count);
358+
m_hcount-= count;
359+
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
360+
DBUG_VOID_RETURN;
361+
}
362+
363+
void
364+
sp_rcontext::push_hstack(uint h)
365+
{
366+
DBUG_ENTER("sp_rcontext::push_hstack");
367+
DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index());
368+
m_hstack[m_hsp++]= h;
369+
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
370+
DBUG_VOID_RETURN;
371+
}
372+
373+
uint
374+
sp_rcontext::pop_hstack()
375+
{
376+
uint handler;
377+
DBUG_ENTER("sp_rcontext::pop_hstack");
378+
DBUG_ASSERT(m_hsp);
379+
handler= m_hstack[--m_hsp];
380+
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
381+
DBUG_RETURN(handler);
382+
}
383+
384+
void
385+
sp_rcontext::enter_handler(int hid)
386+
{
387+
DBUG_ENTER("sp_rcontext::enter_handler");
388+
DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index());
389+
m_in_handler[m_ihsp++]= hid;
390+
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
391+
DBUG_VOID_RETURN;
392+
}
393+
394+
void
395+
sp_rcontext::exit_handler()
396+
{
397+
DBUG_ENTER("sp_rcontext::exit_handler");
398+
DBUG_ASSERT(m_ihsp);
399+
m_ihsp-= 1;
400+
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
401+
DBUG_VOID_RETURN;
328402
}
329403

330404

sql/sp_rcontext.h

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc
107107
return m_return_value_set;
108108
}
109109

110-
inline void
111-
push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
112-
{
113-
m_handler[m_hcount].cond= cond;
114-
m_handler[m_hcount].handler= h;
115-
m_handler[m_hcount].type= type;
116-
m_handler[m_hcount].foffset= f;
117-
m_hcount+= 1;
118-
}
110+
void push_handler(struct sp_cond_type *cond, uint h, int type, uint f);
119111

120-
inline void
121-
pop_handlers(uint count)
122-
{
123-
m_hcount-= count;
124-
}
112+
void pop_handlers(uint count);
125113

126114
// Returns 1 if a handler was found, 0 otherwise.
127115
bool
@@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc
158146
m_hfound= -1;
159147
}
160148

161-
inline void
162-
push_hstack(uint h)
163-
{
164-
m_hstack[m_hsp++]= h;
165-
}
149+
void push_hstack(uint h);
166150

167-
inline uint
168-
pop_hstack()
169-
{
170-
return m_hstack[--m_hsp];
171-
}
151+
uint pop_hstack();
172152

173-
inline void
174-
enter_handler(int hid)
175-
{
176-
m_in_handler[m_ihsp++]= hid;
177-
}
153+
void enter_handler(int hid);
178154

179-
inline void
180-
exit_handler()
181-
{
182-
m_ihsp-= 1;
183-
}
155+
void exit_handler();
184156

185157
void
186158
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);

0 commit comments

Comments
 (0)