Commit 7ad33ceb authored by Tom Lane's avatar Tom Lane

Rearrange use of plpgsql_add_initdatums() so that only the parsing of a

DECLARE section needs to know about it.  Formerly, everyplace besides DECLARE
that created variables needed to do "plpgsql_add_initdatums(NULL)" to prevent
those variables from being sucked up as part of a subsequent DECLARE block.
This is obviously error-prone, and in fact the SQLSTATE/SQLERRM patch had
failed to do it for those two variables, leading to the bug recently exhibited
by Asif Ali Rehman: a DECLARE within an exception handler tried to reinitialize
SQLERRM.

Although the SQLSTATE/SQLERRM patch isn't in any pre-8.1 branches, and so
I can't point to a demonstrable failure there, it seems wise to back-patch
this into the older branches anyway, just to keep the logic similar to HEAD.
parent b577aa9e
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.97 2007/02/01 19:10:29 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.98 2007/02/08 18:37:14 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -272,7 +272,6 @@ decl_sect : opt_block_label ...@@ -272,7 +272,6 @@ decl_sect : opt_block_label
$$.label = $1; $$.label = $1;
$$.n_initvars = 0; $$.n_initvars = 0;
$$.initvarnos = NULL; $$.initvarnos = NULL;
plpgsql_add_initdatums(NULL);
} }
| opt_block_label decl_start | opt_block_label decl_start
{ {
...@@ -280,7 +279,6 @@ decl_sect : opt_block_label ...@@ -280,7 +279,6 @@ decl_sect : opt_block_label
$$.label = $1; $$.label = $1;
$$.n_initvars = 0; $$.n_initvars = 0;
$$.initvarnos = NULL; $$.initvarnos = NULL;
plpgsql_add_initdatums(NULL);
} }
| opt_block_label decl_start decl_stmts | opt_block_label decl_start decl_stmts
{ {
...@@ -289,12 +287,16 @@ decl_sect : opt_block_label ...@@ -289,12 +287,16 @@ decl_sect : opt_block_label
$$.label = $3; $$.label = $3;
else else
$$.label = $1; $$.label = $1;
/* Remember variables declared in decl_stmts */
$$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos)); $$.n_initvars = plpgsql_add_initdatums(&($$.initvarnos));
} }
; ;
decl_start : K_DECLARE decl_start : K_DECLARE
{ {
/* Forget any variables created before block */
plpgsql_add_initdatums(NULL);
/* Make variable names be local to block */
plpgsql_ns_setlocal(true); plpgsql_ns_setlocal(true);
} }
; ;
...@@ -990,9 +992,6 @@ for_control : ...@@ -990,9 +992,6 @@ for_control :
-1), -1),
true); true);
/* put the for-variable into the local block */
plpgsql_add_initdatums(NULL);
new = palloc0(sizeof(PLpgSQL_stmt_fori)); new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI; new->cmd_type = PLPGSQL_STMT_FORI;
new->lineno = $1; new->lineno = $1;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.111 2007/02/01 19:10:29 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.112 2007/02/08 18:37:14 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -666,11 +666,6 @@ do_compile(FunctionCallInfo fcinfo, ...@@ -666,11 +666,6 @@ do_compile(FunctionCallInfo fcinfo,
true); true);
function->found_varno = var->dno; function->found_varno = var->dno;
/*
* Forget about the above created variables
*/
plpgsql_add_initdatums(NULL);
/* /*
* Now parse the function's text * Now parse the function's text
*/ */
...@@ -1893,11 +1888,17 @@ plpgsql_adddatum(PLpgSQL_datum *new) ...@@ -1893,11 +1888,17 @@ plpgsql_adddatum(PLpgSQL_datum *new)
/* ---------- /* ----------
* plpgsql_add_initdatums Put all datum entries created * plpgsql_add_initdatums Make an array of the datum numbers of
* since the last call into the * all the simple VAR datums created since the last call
* finishing code block so the * to this function.
* block knows which variables to *
* reinitialize when entered. * If varnos is NULL, we just forget any datum entries created since the
* last call.
*
* This is used around a DECLARE section to create a list of the VARs
* that have to be initialized at block entry. Note that VARs can also
* be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
* the responsibility of special-purpose code to initialize them.
* ---------- * ----------
*/ */
int int
......
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