Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit738df43

Browse files
author
Neil Conway
committed
Fix bug in CONTINUE statement for PL/pgSQL: when we continue a loop,
we need to be careful to reset rc to PLPGSQL_RC_OK, depending on howthe loop's logic is structured. If we continue a loop but it thenexits without executing the loop's body again, we want to returnPLPGSQL_RC_OK to our caller. Enhance the regression tests to catchthis problem. Per report from Michael Fuhr.
1 parent05db8b5 commit738df43

File tree

3 files changed

+92
-23
lines changed

3 files changed

+92
-23
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.147 2005/06/2201:35:02 neilc Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.148 2005/06/2207:28:47 neilc Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1216,11 +1216,9 @@ exec_stmt_if(PLpgSQL_execstate *estate, PLpgSQL_stmt_if *stmt)
12161216
staticint
12171217
exec_stmt_loop(PLpgSQL_execstate*estate,PLpgSQL_stmt_loop*stmt)
12181218
{
1219-
intrc;
1220-
12211219
for (;;)
12221220
{
1223-
rc=exec_stmts(estate,stmt->body);
1221+
intrc=exec_stmts(estate,stmt->body);
12241222

12251223
switch (rc)
12261224
{
@@ -1271,12 +1269,12 @@ exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
12711269
staticint
12721270
exec_stmt_while(PLpgSQL_execstate*estate,PLpgSQL_stmt_while*stmt)
12731271
{
1274-
boolvalue;
1275-
boolisnull;
1276-
intrc;
1277-
12781272
for (;;)
12791273
{
1274+
intrc;
1275+
boolvalue;
1276+
boolisnull;
1277+
12801278
value=exec_eval_boolean(estate,stmt->cond,&isnull);
12811279
exec_eval_cleanup(estate);
12821280

@@ -1425,21 +1423,22 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
14251423
elseif (rc==PLPGSQL_RC_CONTINUE)
14261424
{
14271425
if (estate->exitlabel==NULL)
1428-
/* anonymous continue, socontinue the current loop */
1429-
;
1426+
/* anonymous continue, sore-run the current loop */
1427+
rc=PLPGSQL_RC_OK;
14301428
elseif (stmt->label!=NULL&&
14311429
strcmp(stmt->label,estate->exitlabel)==0)
14321430
{
1433-
/*labelled continue,matchesthe current stmt's label */
1431+
/*labelmatchesnamed continue, so re-run loop */
14341432
estate->exitlabel=NULL;
1433+
rc=PLPGSQL_RC_OK;
14351434
}
14361435
else
14371436
{
14381437
/*
1439-
* otherwise, this is alabelled continue that does
1440-
*notmatch the current statement's label, if any:
1441-
*returnRC_CONTINUE so that the CONTINUE will
1442-
*propagate upthe stack.
1438+
* otherwise, this is anamed continue that does not
1439+
* match the current statement's label, if any: return
1440+
* RC_CONTINUE so that the CONTINUE will propagate up
1441+
* the stack.
14431442
*/
14441443
break;
14451444
}
@@ -1555,18 +1554,22 @@ exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
15551554
elseif (rc==PLPGSQL_RC_CONTINUE)
15561555
{
15571556
if (estate->exitlabel==NULL)
1558-
/* unlabelled continue, continue the current loop */
1557+
{
1558+
/* anonymous continue, so re-run the current loop */
1559+
rc=PLPGSQL_RC_OK;
15591560
continue;
1561+
}
15601562
elseif (stmt->label!=NULL&&
15611563
strcmp(stmt->label,estate->exitlabel)==0)
15621564
{
1563-
/* labelled continue, matches the current stmt's label */
1565+
/* label matches named continue, so re-run loop */
1566+
rc=PLPGSQL_RC_OK;
15641567
estate->exitlabel=NULL;
15651568
continue;
15661569
}
15671570

15681571
/*
1569-
* otherwise, we processed alabelled continue
1572+
* otherwise, we processed anamed continue
15701573
* that does not match the current statement's
15711574
* label, if any: return RC_CONTINUE so that the
15721575
* CONTINUE will propagate up the stack.
@@ -2462,14 +2465,12 @@ static int
24622465
exec_stmt_dynfors(PLpgSQL_execstate*estate,PLpgSQL_stmt_dynfors*stmt)
24632466
{
24642467
Datumquery;
2465-
boolisnull= false;
2468+
boolisnull;
24662469
Oidrestype;
24672470
char*querystr;
24682471
PLpgSQL_rec*rec=NULL;
24692472
PLpgSQL_row*row=NULL;
24702473
SPITupleTable*tuptab;
2471-
intrc=PLPGSQL_RC_OK;
2472-
inti;
24732474
intn;
24742475
void*plan;
24752476
Portalportal;
@@ -2536,8 +2537,12 @@ exec_stmt_dynfors(PLpgSQL_execstate *estate, PLpgSQL_stmt_dynfors *stmt)
25362537
*/
25372538
while (n>0)
25382539
{
2540+
inti;
2541+
25392542
for (i=0;i<n;i++)
25402543
{
2544+
intrc;
2545+
25412546
/*
25422547
* Assign the tuple to the target
25432548
*/

‎src/test/regress/expected/plpgsql.out

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2547,7 +2547,33 @@ begin
25472547
for _r in execute 'select * from conttesttbl' loop
25482548
continue when _r.v <= 20;
25492549
raise notice '%', _r.v;
2550-
end loop;
2550+
end loop;
2551+
2552+
raise notice '---7---';
2553+
for _i in 1..3 loop
2554+
raise notice '%', _i;
2555+
continue when _i = 3;
2556+
end loop;
2557+
2558+
raise notice '---8---';
2559+
_i := 1;
2560+
while _i <= 3 loop
2561+
raise notice '%', _i;
2562+
_i := _i + 1;
2563+
continue when _i = 3;
2564+
end loop;
2565+
2566+
raise notice '---9---';
2567+
for _r in select * from conttesttbl order by v limit 1 loop
2568+
raise notice '%', _r.v;
2569+
continue;
2570+
end loop;
2571+
2572+
raise notice '---10---';
2573+
for _r in execute 'select * from conttesttbl order by v limit 1' loop
2574+
raise notice '%', _r.v;
2575+
continue;
2576+
end loop;
25512577
end; $$ language plpgsql;
25522578
select continue_test1();
25532579
NOTICE: ---1---
@@ -2591,6 +2617,18 @@ NOTICE: 40
25912617
NOTICE: ---6---
25922618
NOTICE: 30
25932619
NOTICE: 40
2620+
NOTICE: ---7---
2621+
NOTICE: 1
2622+
NOTICE: 2
2623+
NOTICE: 3
2624+
NOTICE: ---8---
2625+
NOTICE: 1
2626+
NOTICE: 2
2627+
NOTICE: 3
2628+
NOTICE: ---9---
2629+
NOTICE: 10
2630+
NOTICE: ---10---
2631+
NOTICE: 10
25942632
continue_test1
25952633
----------------
25962634

‎src/test/regress/sql/plpgsql.sql

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,33 @@ begin
21692169
for _rin execute'select * from conttesttbl' loop
21702170
continue when_r.v<=20;
21712171
raise notice'%',_r.v;
2172-
end loop;
2172+
end loop;
2173+
2174+
raise notice'---7---';
2175+
for _iin1..3 loop
2176+
raise notice'%', _i;
2177+
continue when _i=3;
2178+
end loop;
2179+
2180+
raise notice'---8---';
2181+
_i :=1;
2182+
while _i<=3 loop
2183+
raise notice'%', _i;
2184+
_i := _i+1;
2185+
continue when _i=3;
2186+
end loop;
2187+
2188+
raise notice'---9---';
2189+
for _rinselect*from conttesttblorder by vlimit1 loop
2190+
raise notice'%',_r.v;
2191+
continue;
2192+
end loop;
2193+
2194+
raise notice'---10---';
2195+
for _rin execute'select * from conttesttbl order by v limit 1' loop
2196+
raise notice'%',_r.v;
2197+
continue;
2198+
end loop;
21732199
end; $$ language plpgsql;
21742200

21752201
select continue_test1();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp