Re: WIP: pl/pgsql cleanup
- From: Neil Conway <neilc@samurai.com>
- To: Tom Lane <tgl@sss.pgh.pa.us>
- Cc: pgsql-patches <pgsql-patches@postgresql.org>
- Subject: Re: WIP: pl/pgsql cleanup
- Date: Thu, 20 Jan 2005 15:48:02 +1100
- Message-id: <1106196482.22946.248.camel@localhost.localdomain>
On Tue, 2005-01-18 at 01:02 -0500, Tom Lane wrote:
> I think that the existing parsing code feels free to palloc junk data
> that needn't be kept around as part of the finished function definition.
> It might be better to keep CurrentMemoryContext pointing at a temp
> context, and translate malloc() to MemoryContextAlloc(function_context)
> rather than just palloc(). (Of course you could hide this in a macro,
> maybe falloc()?)
Are there really enough short-lived pallocs that this is worth the
trouble? One potential issue is that there are plenty of places where
we'd want to falloc(), but don't have the function easily available
(e.g. in the parser).
Attached is a revised patch (no major changes, just grammar cleanup).
While rewriting some cruft in PL/PgSQL's gram.y, I noticed that we will
overflow a heap-allocated array if the user specifies more than 1024
parameters to a refcursor (a demonstration .sql file is also attached).
I think this is probably worth backpatching to 8.0 (and earlier?) --
I've attached a quick hack of a patch that fixes the issue, although of
course the fix for 8.1 is nicer.
-Neil
Index: src/pl/plpgsql/src/gram.y
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/gram.y,v
retrieving revision 1.64
diff -c -r1.64 gram.y
*** src/pl/plpgsql/src/gram.y 25 Oct 2004 06:27:21 -0000 1.64
--- src/pl/plpgsql/src/gram.y 20 Jan 2005 03:59:01 -0000
***************
*** 86,91 ****
--- 86,92 ----
int n_initvars;
int *initvarnos;
} declhdr;
+ List *list;
PLpgSQL_type *dtype;
PLpgSQL_datum *scalar; /* a VAR, RECFIELD, or TRIGARG */
PLpgSQL_variable *variable; /* a VAR, REC, or ROW */
***************
*** 94,104 ****
PLpgSQL_rec *rec;
PLpgSQL_expr *expr;
PLpgSQL_stmt *stmt;
- PLpgSQL_stmts *stmts;
PLpgSQL_stmt_block *program;
PLpgSQL_condition *condition;
PLpgSQL_exception *exception;
- PLpgSQL_exceptions *exceptions;
PLpgSQL_nsitem *nsitem;
}
--- 95,103 ----
***************
*** 108,114 ****
%type <ival> decl_const decl_notnull
%type <expr> decl_defval decl_cursor_query
%type <dtype> decl_datatype
! %type <row> decl_cursor_args decl_cursor_arglist
%type <nsitem> decl_aliasitem
%type <str> decl_stmts decl_stmt
--- 107,114 ----
%type <ival> decl_const decl_notnull
%type <expr> decl_defval decl_cursor_query
%type <dtype> decl_datatype
! %type <row> decl_cursor_args
! %type <list> decl_cursor_arglist decl_cursor_opt_arglist
%type <nsitem> decl_aliasitem
%type <str> decl_stmts decl_stmt
***************
*** 126,132 ****
%type <str> opt_exitlabel
%type <str> execsql_start
! %type <stmts> proc_sect proc_stmts stmt_else loop_body
%type <stmt> proc_stmt pl_block
%type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
%type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
--- 126,132 ----
%type <str> opt_exitlabel
%type <str> execsql_start
! %type <list> proc_sect proc_stmts stmt_else loop_body
%type <stmt> proc_stmt pl_block
%type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
%type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
***************
*** 134,140 ****
%type <stmt> stmt_dynexecute stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_close stmt_null
! %type <exceptions> exception_sect proc_exceptions
%type <exception> proc_exception
%type <condition> proc_conditions
--- 134,140 ----
%type <stmt> stmt_dynexecute stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_close stmt_null
! %type <list> exception_sect proc_exceptions
%type <exception> proc_exception
%type <condition> proc_conditions
***************
*** 240,246 ****
comp_option : O_OPTION O_DUMP
{
! plpgsql_DumpExecTree = 1;
}
;
--- 240,246 ----
comp_option : O_OPTION O_DUMP
{
! plpgsql_DumpExecTree = true;
}
;
***************
*** 252,259 ****
{
PLpgSQL_stmt_block *new;
! new = malloc(sizeof(PLpgSQL_stmt_block));
! memset(new, 0, sizeof(PLpgSQL_stmt_block));
new->cmd_type = PLPGSQL_STMT_BLOCK;
new->lineno = $3;
--- 252,258 ----
{
PLpgSQL_stmt_block *new;
! new = palloc0(sizeof(PLpgSQL_stmt_block));
new->cmd_type = PLPGSQL_STMT_BLOCK;
new->lineno = $3;
***************
*** 379,386 ****
-1),
true);
! curname_def = malloc(sizeof(PLpgSQL_expr));
! memset(curname_def, 0, sizeof(PLpgSQL_expr));
curname_def->dtype = PLPGSQL_DTYPE_EXPR;
strcpy(buf, "SELECT '");
--- 378,384 ----
-1),
true);
! curname_def = palloc0(sizeof(PLpgSQL_expr));
curname_def->dtype = PLPGSQL_DTYPE_EXPR;
strcpy(buf, "SELECT '");
***************
*** 393,399 ****
*cp2++ = *cp1++;
}
strcpy(cp2, "'::refcursor");
! curname_def->query = strdup(buf);
new->default_val = curname_def;
new->cursor_explicit_expr = $6;
--- 391,397 ----
*cp2++ = *cp1++;
}
strcpy(cp2, "'::refcursor");
! curname_def->query = pstrdup(buf);
new->default_val = curname_def;
new->cursor_explicit_expr = $6;
***************
*** 422,483 ****
}
| '(' decl_cursor_arglist ')'
{
- /* Copy the temp arrays to malloc'd storage */
- int nfields = $2->nfields;
- char **ftmp;
- int *vtmp;
-
- ftmp = malloc(nfields * sizeof(char *));
- vtmp = malloc(nfields * sizeof(int));
- memcpy(ftmp, $2->fieldnames, nfields * sizeof(char *));
- memcpy(vtmp, $2->varnos, nfields * sizeof(int));
-
- pfree($2->fieldnames);
- pfree($2->varnos);
-
- $2->fieldnames = ftmp;
- $2->varnos = vtmp;
-
- plpgsql_adddatum((PLpgSQL_datum *)$2);
-
- $$ = $2;
- }
- ;
-
- decl_cursor_arglist : decl_cursor_arg
- {
PLpgSQL_row *new;
! new = malloc(sizeof(PLpgSQL_row));
! memset(new, 0, sizeof(PLpgSQL_row));
new->dtype = PLPGSQL_DTYPE_ROW;
- new->refname = strdup("*internal*");
new->lineno = plpgsql_scanner_lineno();
new->rowtupdesc = NULL;
! /*
! * We make temporary fieldnames/varnos arrays that
! * are much bigger than necessary. We will resize
! * them to just the needed size in the
! * decl_cursor_args production.
! */
! new->fieldnames = palloc(1024 * sizeof(char *));
! new->varnos = palloc(1024 * sizeof(int));
! new->nfields = 1;
! new->fieldnames[0] = $1->refname;
! new->varnos[0] = $1->dno;
$$ = new;
}
! | decl_cursor_arglist ',' decl_cursor_arg
! {
! int i = $1->nfields++;
! $1->fieldnames[i] = $3->refname;
! $1->varnos[i] = $3->dno;
! $$ = $1;
}
;
--- 420,467 ----
}
| '(' decl_cursor_arglist ')'
{
PLpgSQL_row *new;
+ int i;
+ ListCell *l;
! Assert(list_length($2) > 0);
+ new = palloc0(sizeof(PLpgSQL_row));
new->dtype = PLPGSQL_DTYPE_ROW;
new->lineno = plpgsql_scanner_lineno();
new->rowtupdesc = NULL;
! new->nfields = list_length($2);
! new->fieldnames = palloc(new->nfields * sizeof(char *));
! new->varnos = palloc(new->nfields * sizeof(int));
! i = 0;
! foreach (l, $2)
! {
! PLpgSQL_variable *arg = (PLpgSQL_variable *) lfirst(l);
! new->fieldnames[i] = arg->refname;
! new->varnos[i] = arg->dno;
! i++;
! }
+ plpgsql_adddatum((PLpgSQL_datum *) new);
$$ = new;
}
! ;
! /* At least one decl_cursor_arg is required */
! decl_cursor_arglist : decl_cursor_arg decl_cursor_opt_arglist
! {
! $$ = lcons($1, $2);
! }
! ;
! decl_cursor_opt_arglist : decl_cursor_opt_arglist ',' decl_cursor_arg
! {
! $$ = lappend($1, $3);
! }
! | /* EMPTY */
! {
! $$ = NIL;
}
;
***************
*** 524,531 ****
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! /* name should be malloc'd for use as varname */
! $$.name = strdup(name);
$$.lineno = plpgsql_scanner_lineno();
pfree(name);
}
--- 508,514 ----
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! $$.name = pstrdup(name);
$$.lineno = plpgsql_scanner_lineno();
pfree(name);
}
***************
*** 580,590 ****
proc_sect :
{
! PLpgSQL_stmts *new;
!
! new = malloc(sizeof(PLpgSQL_stmts));
! memset(new, 0, sizeof(PLpgSQL_stmts));
! $$ = new;
}
| proc_stmts
{ $$ = $1; }
--- 563,569 ----
proc_sect :
{
! $$ = NIL;
}
| proc_stmts
{ $$ = $1; }
***************
*** 592,622 ****
proc_stmts : proc_stmts proc_stmt
{
! if ($2 != NULL)
! {
! if ($1->stmts_used == $1->stmts_alloc)
! {
! $1->stmts_alloc *= 2;
! $1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
! }
! $1->stmts[$1->stmts_used++] = $2;
! }
! $$ = $1;
}
| proc_stmt
{
! PLpgSQL_stmts *new;
!
! new = malloc(sizeof(PLpgSQL_stmts));
! memset(new, 0, sizeof(PLpgSQL_stmts));
!
! new->stmts_alloc = 32;
! new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
!
! if ($1 != NULL)
! new->stmts[new->stmts_used++] = $1;
!
! $$ = new;
}
;
--- 571,587 ----
proc_stmts : proc_stmts proc_stmt
{
! if ($2 == NULL)
! $$ = $1;
! else
! $$ = lappend($1, $2);
}
| proc_stmt
{
! if ($1 == NULL)
! $$ = NULL;
! else
! $$ = list_make1($1);
}
;
***************
*** 664,672 ****
{
PLpgSQL_stmt_perform *new;
! new = malloc(sizeof(PLpgSQL_stmt_perform));
! memset(new, 0, sizeof(PLpgSQL_stmt_perform));
!
new->cmd_type = PLPGSQL_STMT_PERFORM;
new->lineno = $2;
new->expr = $3;
--- 629,635 ----
{
PLpgSQL_stmt_perform *new;
! new = palloc0(sizeof(PLpgSQL_stmt_perform));
new->cmd_type = PLPGSQL_STMT_PERFORM;
new->lineno = $2;
new->expr = $3;
***************
*** 679,687 ****
{
PLpgSQL_stmt_assign *new;
! new = malloc(sizeof(PLpgSQL_stmt_assign));
! memset(new, 0, sizeof(PLpgSQL_stmt_assign));
!
new->cmd_type = PLPGSQL_STMT_ASSIGN;
new->lineno = $2;
new->varno = $1;
--- 642,648 ----
{
PLpgSQL_stmt_assign *new;
! new = palloc0(sizeof(PLpgSQL_stmt_assign));
new->cmd_type = PLPGSQL_STMT_ASSIGN;
new->lineno = $2;
new->varno = $1;
***************
*** 695,707 ****
{
PLpgSQL_stmt_getdiag *new;
! new = malloc(sizeof(PLpgSQL_stmt_getdiag));
! memset(new, 0, sizeof(PLpgSQL_stmt_getdiag));
!
new->cmd_type = PLPGSQL_STMT_GETDIAG;
new->lineno = $3;
new->ndtitems = $4.nused;
! new->dtitems = malloc(sizeof(PLpgSQL_diag_item) * $4.nused);
memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused);
$$ = (PLpgSQL_stmt *)new;
--- 656,666 ----
{
PLpgSQL_stmt_getdiag *new;
! new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
new->cmd_type = PLPGSQL_STMT_GETDIAG;
new->lineno = $3;
new->ndtitems = $4.nused;
! new->dtitems = palloc(sizeof(PLpgSQL_diag_item) * $4.nused);
memcpy(new->dtitems, $4.dtitems, sizeof(PLpgSQL_diag_item) * $4.nused);
$$ = (PLpgSQL_stmt *)new;
***************
*** 770,778 ****
{
PLpgSQL_arrayelem *new;
! new = malloc(sizeof(PLpgSQL_arrayelem));
! memset(new, 0, sizeof(PLpgSQL_arrayelem));
!
new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
new->subscript = $3;
new->arrayparentno = $1;
--- 729,735 ----
{
PLpgSQL_arrayelem *new;
! new = palloc0(sizeof(PLpgSQL_arrayelem));
new->dtype = PLPGSQL_DTYPE_ARRAYELEM;
new->subscript = $3;
new->arrayparentno = $1;
***************
*** 787,795 ****
{
PLpgSQL_stmt_if *new;
! new = malloc(sizeof(PLpgSQL_stmt_if));
! memset(new, 0, sizeof(PLpgSQL_stmt_if));
!
new->cmd_type = PLPGSQL_STMT_IF;
new->lineno = $2;
new->cond = $3;
--- 744,750 ----
{
PLpgSQL_stmt_if *new;
! new = palloc0(sizeof(PLpgSQL_stmt_if));
new->cmd_type = PLPGSQL_STMT_IF;
new->lineno = $2;
new->cond = $3;
***************
*** 802,853 ****
stmt_else :
{
! PLpgSQL_stmts *new;
!
! new = malloc(sizeof(PLpgSQL_stmts));
! memset(new, 0, sizeof(PLpgSQL_stmts));
! $$ = new;
}
| K_ELSIF lno expr_until_then proc_sect stmt_else
{
! /*
! * Translate the structure: into:
! *
! * IF c1 THEN IF c1 THEN
! * ... ...
! * ELSIF c2 THEN ELSE
! * IF c2 THEN
! * ... ...
! * ELSE ELSE
! * ... ...
! * END IF END IF
! * END IF
! *
! */
!
! PLpgSQL_stmts *new;
PLpgSQL_stmt_if *new_if;
/* first create a new if-statement */
! new_if = malloc(sizeof(PLpgSQL_stmt_if));
! memset(new_if, 0, sizeof(PLpgSQL_stmt_if));
!
new_if->cmd_type = PLPGSQL_STMT_IF;
new_if->lineno = $2;
new_if->cond = $3;
new_if->true_body = $4;
new_if->false_body = $5;
-
- /* this is a 'container' for the if-statement */
- new = malloc(sizeof(PLpgSQL_stmts));
- memset(new, 0, sizeof(PLpgSQL_stmts));
-
- new->stmts_alloc = 64;
- new->stmts_used = 1;
- new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
- new->stmts[0] = (PLpgSQL_stmt *) new_if;
! $$ = new;
}
--- 757,791 ----
stmt_else :
{
! $$ = NIL;
}
| K_ELSIF lno expr_until_then proc_sect stmt_else
{
! /*
! * Translate the structure: into:
! *
! * IF c1 THEN IF c1 THEN
! * ... ...
! * ELSIF c2 THEN ELSE
! * IF c2 THEN
! * ... ...
! * ELSE ELSE
! * ... ...
! * END IF END IF
! * END IF
! */
PLpgSQL_stmt_if *new_if;
/* first create a new if-statement */
! new_if = palloc0(sizeof(PLpgSQL_stmt_if));
new_if->cmd_type = PLPGSQL_STMT_IF;
new_if->lineno = $2;
new_if->cond = $3;
new_if->true_body = $4;
new_if->false_body = $5;
! /* wrap the if-statement in a "container" list */
! $$ = list_make1(new_if);
}
***************
*** 861,869 ****
{
PLpgSQL_stmt_loop *new;
! new = malloc(sizeof(PLpgSQL_stmt_loop));
! memset(new, 0, sizeof(PLpgSQL_stmt_loop));
!
new->cmd_type = PLPGSQL_STMT_LOOP;
new->lineno = $3;
new->label = $1;
--- 799,805 ----
{
PLpgSQL_stmt_loop *new;
! new = palloc0(sizeof(PLpgSQL_stmt_loop));
new->cmd_type = PLPGSQL_STMT_LOOP;
new->lineno = $3;
new->label = $1;
***************
*** 879,887 ****
{
PLpgSQL_stmt_while *new;
! new = malloc(sizeof(PLpgSQL_stmt_while));
! memset(new, 0, sizeof(PLpgSQL_stmt_while));
!
new->cmd_type = PLPGSQL_STMT_WHILE;
new->lineno = $3;
new->label = $1;
--- 815,821 ----
{
PLpgSQL_stmt_while *new;
! new = palloc0(sizeof(PLpgSQL_stmt_while));
new->cmd_type = PLPGSQL_STMT_WHILE;
new->lineno = $3;
new->label = $1;
***************
*** 974,982 ****
yyerror("cannot specify EXECUTE in integer for-loop");
}
- /* name should be malloc'd for use as varname */
fvar = (PLpgSQL_var *)
! plpgsql_build_variable(strdup($2.name),
$2.lineno,
plpgsql_build_datatype(INT4OID,
-1),
--- 908,915 ----
yyerror("cannot specify EXECUTE in integer for-loop");
}
fvar = (PLpgSQL_var *)
! plpgsql_build_variable($2.name,
$2.lineno,
plpgsql_build_datatype(INT4OID,
-1),
***************
*** 985,993 ****
/* put the for-variable into the local block */
plpgsql_add_initdatums(NULL);
! new = malloc(sizeof(PLpgSQL_stmt_fori));
! memset(new, 0, sizeof(PLpgSQL_stmt_fori));
!
new->cmd_type = PLPGSQL_STMT_FORI;
new->lineno = $1;
new->var = fvar;
--- 918,924 ----
/* put the for-variable into the local block */
plpgsql_add_initdatums(NULL);
! new = palloc0(sizeof(PLpgSQL_stmt_fori));
new->cmd_type = PLPGSQL_STMT_FORI;
new->lineno = $1;
new->var = fvar;
***************
*** 1008,1016 ****
yyerror("cannot specify REVERSE in loop over rows");
}
! new = malloc(sizeof(PLpgSQL_stmt_dynfors));
! memset(new, 0, sizeof(PLpgSQL_stmt_dynfors));
!
new->cmd_type = PLPGSQL_STMT_DYNFORS;
new->lineno = $1;
if ($2.rec)
--- 939,945 ----
yyerror("cannot specify REVERSE in loop over rows");
}
! new = palloc0(sizeof(PLpgSQL_stmt_dynfors));
new->cmd_type = PLPGSQL_STMT_DYNFORS;
new->lineno = $1;
if ($2.rec)
***************
*** 1038,1046 ****
yyerror("cannot specify REVERSE in loop over rows");
}
! new = malloc(sizeof(PLpgSQL_stmt_fors));
! memset(new, 0, sizeof(PLpgSQL_stmt_fors));
!
new->cmd_type = PLPGSQL_STMT_FORS;
new->lineno = $1;
if ($2.rec)
--- 967,973 ----
yyerror("cannot specify REVERSE in loop over rows");
}
! new = palloc0(sizeof(PLpgSQL_stmt_fors));
new->cmd_type = PLPGSQL_STMT_FORS;
new->lineno = $1;
if ($2.rec)
***************
*** 1056,1063 ****
* Must get rid of the "SELECT " we prepended
* to expr1's text
*/
! newquery = strdup(expr1->query + 7);
! free(expr1->query);
expr1->query = newquery;
new->query = expr1;
--- 983,990 ----
* Must get rid of the "SELECT " we prepended
* to expr1's text
*/
! newquery = pstrdup(expr1->query + 7);
! pfree(expr1->query);
expr1->query = newquery;
new->query = expr1;
***************
*** 1120,1128 ****
{
PLpgSQL_stmt_exit *new;
! new = malloc(sizeof(PLpgSQL_stmt_exit));
! memset(new, 0, sizeof(PLpgSQL_stmt_exit));
!
new->cmd_type = PLPGSQL_STMT_EXIT;
new->lineno = $2;
new->label = $3;
--- 1047,1053 ----
{
PLpgSQL_stmt_exit *new;
! new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
new->lineno = $2;
new->label = $3;
***************
*** 1136,1143 ****
{
PLpgSQL_stmt_return *new;
! new = malloc(sizeof(PLpgSQL_stmt_return));
! memset(new, 0, sizeof(PLpgSQL_stmt_return));
new->expr = NULL;
new->retrecno = -1;
new->retrowno = -1;
--- 1061,1067 ----
{
PLpgSQL_stmt_return *new;
! new = palloc0(sizeof(PLpgSQL_stmt_return));
new->expr = NULL;
new->retrecno = -1;
new->retrowno = -1;
***************
*** 1189,1197 ****
if (!plpgsql_curr_compile->fn_retset)
yyerror("cannot use RETURN NEXT in a non-SETOF function");
! new = malloc(sizeof(PLpgSQL_stmt_return_next));
! memset(new, 0, sizeof(PLpgSQL_stmt_return_next));
!
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = $2;
--- 1113,1119 ----
if (!plpgsql_curr_compile->fn_retset)
yyerror("cannot use RETURN NEXT in a non-SETOF function");
! new = palloc0(sizeof(PLpgSQL_stmt_return_next));
new->cmd_type = PLPGSQL_STMT_RETURN_NEXT;
new->lineno = $2;
***************
*** 1220,1226 ****
{
PLpgSQL_stmt_raise *new;
! new = malloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = $2;
--- 1142,1148 ----
{
PLpgSQL_stmt_raise *new;
! new = palloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = $2;
***************
*** 1236,1242 ****
{
PLpgSQL_stmt_raise *new;
! new = malloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = $2;
--- 1158,1164 ----
{
PLpgSQL_stmt_raise *new;
! new = palloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
new->lineno = $2;
***************
*** 1317,1323 ****
{
PLpgSQL_stmt_execsql *new;
! new = malloc(sizeof(PLpgSQL_stmt_execsql));
new->cmd_type = PLPGSQL_STMT_EXECSQL;
new->lineno = $2;
new->sqlstmt = read_sql_stmt($1);
--- 1239,1245 ----
{
PLpgSQL_stmt_execsql *new;
! new = palloc(sizeof(PLpgSQL_stmt_execsql));
new->cmd_type = PLPGSQL_STMT_EXECSQL;
new->lineno = $2;
new->sqlstmt = read_sql_stmt($1);
***************
*** 1330,1336 ****
{
PLpgSQL_stmt_dynexecute *new;
! new = malloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = $2;
new->query = $3;
--- 1252,1258 ----
{
PLpgSQL_stmt_dynexecute *new;
! new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
new->lineno = $2;
new->query = $3;
***************
*** 1344,1352 ****
PLpgSQL_stmt_open *new;
int tok;
! new = malloc(sizeof(PLpgSQL_stmt_open));
! memset(new, 0, sizeof(PLpgSQL_stmt_open));
!
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = $2;
new->curvar = $3->varno;
--- 1266,1272 ----
PLpgSQL_stmt_open *new;
int tok;
! new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
new->lineno = $2;
new->curvar = $3->varno;
***************
*** 1488,1494 ****
{
PLpgSQL_stmt_close *new;
! new = malloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = $2;
new->curvar = $3;
--- 1408,1414 ----
{
PLpgSQL_stmt_close *new;
! new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
new->lineno = $2;
new->curvar = $3;
***************
*** 1539,1579 ****
;
execsql_start : T_WORD
! { $$ = strdup(yytext); }
| T_ERROR
! { $$ = strdup(yytext); }
;
exception_sect :
! { $$ = NULL; }
| K_EXCEPTION proc_exceptions
{ $$ = $2; }
;
proc_exceptions : proc_exceptions proc_exception
{
! if ($1->exceptions_used == $1->exceptions_alloc)
! {
! $1->exceptions_alloc *= 2;
! $1->exceptions = realloc($1->exceptions, sizeof(PLpgSQL_exception *) * $1->exceptions_alloc);
! }
! $1->exceptions[$1->exceptions_used++] = $2;
!
! $$ = $1;
}
| proc_exception
{
! PLpgSQL_exceptions *new;
!
! new = malloc(sizeof(PLpgSQL_exceptions));
! memset(new, 0, sizeof(PLpgSQL_exceptions));
!
! new->exceptions_alloc = 16;
! new->exceptions_used = 1;
! new->exceptions = malloc(sizeof(PLpgSQL_exception *) * new->exceptions_alloc);
! new->exceptions[0] = $1;
!
! $$ = new;
}
;
--- 1459,1482 ----
;
execsql_start : T_WORD
! { $$ = pstrdup(yytext); }
| T_ERROR
! { $$ = pstrdup(yytext); }
;
exception_sect :
! { $$ = NIL; }
| K_EXCEPTION proc_exceptions
{ $$ = $2; }
;
proc_exceptions : proc_exceptions proc_exception
{
! $$ = lappend($1, $2);
}
| proc_exception
{
! $$ = list_make1($1);
}
;
***************
*** 1581,1589 ****
{
PLpgSQL_exception *new;
! new = malloc(sizeof(PLpgSQL_exception));
! memset(new, 0, sizeof(PLpgSQL_exception));
!
new->lineno = $2;
new->conditions = $3;
new->action = $5;
--- 1484,1490 ----
{
PLpgSQL_exception *new;
! new = palloc0(sizeof(PLpgSQL_exception));
new->lineno = $2;
new->conditions = $3;
new->action = $5;
***************
*** 1643,1650 ****
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! $$ = strdup(name);
! pfree(name);
}
| T_WORD
{
--- 1544,1550 ----
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! $$ = name;
}
| T_WORD
{
***************
*** 1664,1671 ****
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! $$ = strdup(name);
! pfree(name);
}
;
--- 1564,1570 ----
char *name;
plpgsql_convert_ident(yytext, &name, 1);
! $$ = name;
}
;
***************
*** 1793,1801 ****
if (endtoken)
*endtoken = tok;
! expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
expr->dtype = PLPGSQL_DTYPE_EXPR;
! expr->query = strdup(plpgsql_dstring_get(&ds));
expr->plan = NULL;
expr->nparams = nparams;
while(nparams-- > 0)
--- 1692,1700 ----
if (endtoken)
*endtoken = tok;
! expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
expr->dtype = PLPGSQL_DTYPE_EXPR;
! expr->query = pstrdup(plpgsql_dstring_get(&ds));
expr->plan = NULL;
expr->nparams = nparams;
while(nparams-- > 0)
***************
*** 1931,1937 ****
int varnos[1024];
check_assignable(yylval.scalar);
! fieldnames[0] = strdup(yytext);
varnos[0] = yylval.scalar->dno;
while ((tok = yylex()) == ',')
--- 1830,1836 ----
int varnos[1024];
check_assignable(yylval.scalar);
! fieldnames[0] = pstrdup(yytext);
varnos[0] = yylval.scalar->dno;
while ((tok = yylex()) == ',')
***************
*** 1941,1947 ****
{
case T_SCALAR:
check_assignable(yylval.scalar);
! fieldnames[nfields] = strdup(yytext);
varnos[nfields++] = yylval.scalar->dno;
break;
--- 1840,1846 ----
{
case T_SCALAR:
check_assignable(yylval.scalar);
! fieldnames[nfields] = pstrdup(yytext);
varnos[nfields++] = yylval.scalar->dno;
break;
***************
*** 1955,1968 ****
}
have_nexttok = 1;
! row = malloc(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = strdup("*internal*");
row->lineno = plpgsql_scanner_lineno();
row->rowtupdesc = NULL;
row->nfields = nfields;
! row->fieldnames = malloc(sizeof(char *) * nfields);
! row->varnos = malloc(sizeof(int) * nfields);
while (--nfields >= 0)
{
row->fieldnames[nfields] = fieldnames[nfields];
--- 1854,1867 ----
}
have_nexttok = 1;
! row = palloc(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = pstrdup("*internal*");
row->lineno = plpgsql_scanner_lineno();
row->rowtupdesc = NULL;
row->nfields = nfields;
! row->fieldnames = palloc(sizeof(char *) * nfields);
! row->varnos = palloc(sizeof(int) * nfields);
while (--nfields >= 0)
{
row->fieldnames[nfields] = fieldnames[nfields];
***************
*** 2012,2020 ****
}
}
! expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
expr->dtype = PLPGSQL_DTYPE_EXPR;
! expr->query = strdup(plpgsql_dstring_get(&ds));
expr->plan = NULL;
expr->nparams = nparams;
while(nparams-- > 0)
--- 1911,1919 ----
}
}
! expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int));
expr->dtype = PLPGSQL_DTYPE_EXPR;
! expr->query = pstrdup(plpgsql_dstring_get(&ds));
expr->plan = NULL;
expr->nparams = nparams;
while(nparams-- > 0)
***************
*** 2025,2032 ****
{
PLpgSQL_stmt_select *select;
! select = malloc(sizeof(PLpgSQL_stmt_select));
! memset(select, 0, sizeof(PLpgSQL_stmt_select));
select->cmd_type = PLPGSQL_STMT_SELECT;
select->rec = rec;
select->row = row;
--- 1924,1930 ----
{
PLpgSQL_stmt_select *select;
! select = palloc0(sizeof(PLpgSQL_stmt_select));
select->cmd_type = PLPGSQL_STMT_SELECT;
select->rec = rec;
select->row = row;
***************
*** 2038,2044 ****
{
PLpgSQL_stmt_execsql *execsql;
! execsql = malloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->sqlstmt = expr;
--- 1936,1942 ----
{
PLpgSQL_stmt_execsql *execsql;
! execsql = palloc(sizeof(PLpgSQL_stmt_execsql));
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
execsql->sqlstmt = expr;
***************
*** 2076,2082 ****
int varnos[1024];
check_assignable(yylval.scalar);
! fieldnames[0] = strdup(yytext);
varnos[0] = yylval.scalar->dno;
while ((tok = yylex()) == ',')
--- 1974,1980 ----
int varnos[1024];
check_assignable(yylval.scalar);
! fieldnames[0] = pstrdup(yytext);
varnos[0] = yylval.scalar->dno;
while ((tok = yylex()) == ',')
***************
*** 2086,2092 ****
{
case T_SCALAR:
check_assignable(yylval.scalar);
! fieldnames[nfields] = strdup(yytext);
varnos[nfields++] = yylval.scalar->dno;
break;
--- 1984,1990 ----
{
case T_SCALAR:
check_assignable(yylval.scalar);
! fieldnames[nfields] = pstrdup(yytext);
varnos[nfields++] = yylval.scalar->dno;
break;
***************
*** 2100,2113 ****
}
have_nexttok = 1;
! row = malloc(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = strdup("*internal*");
row->lineno = plpgsql_scanner_lineno();
row->rowtupdesc = NULL;
row->nfields = nfields;
! row->fieldnames = malloc(sizeof(char *) * nfields);
! row->varnos = malloc(sizeof(int) * nfields);
while (--nfields >= 0)
{
row->fieldnames[nfields] = fieldnames[nfields];
--- 1998,2011 ----
}
have_nexttok = 1;
! row = palloc(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = pstrdup("*internal*");
row->lineno = plpgsql_scanner_lineno();
row->rowtupdesc = NULL;
row->nfields = nfields;
! row->fieldnames = palloc(sizeof(char *) * nfields);
! row->varnos = palloc(sizeof(int) * nfields);
while (--nfields >= 0)
{
row->fieldnames[nfields] = fieldnames[nfields];
***************
*** 2128,2135 ****
if (tok != ';')
yyerror("syntax error");
! fetch = malloc(sizeof(PLpgSQL_stmt_select));
! memset(fetch, 0, sizeof(PLpgSQL_stmt_fetch));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
fetch->rec = rec;
fetch->row = row;
--- 2026,2032 ----
if (tok != ';')
yyerror("syntax error");
! fetch = palloc0(sizeof(PLpgSQL_stmt_select));
fetch->cmd_type = PLPGSQL_STMT_FETCH;
fetch->rec = rec;
fetch->row = row;
Index: src/pl/plpgsql/src/pl_comp.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.83
diff -c -r1.83 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c 30 Nov 2004 03:50:29 -0000 1.83
--- src/pl/plpgsql/src/pl_comp.c 19 Jan 2005 23:56:38 -0000
***************
*** 76,82 ****
int plpgsql_error_lineno;
char *plpgsql_error_funcname;
! int plpgsql_DumpExecTree = 0;
PLpgSQL_function *plpgsql_curr_compile;
--- 76,82 ----
int plpgsql_error_lineno;
char *plpgsql_error_funcname;
! bool plpgsql_DumpExecTree = false;
PLpgSQL_function *plpgsql_curr_compile;
***************
*** 130,153 ****
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
PLpgSQL_func_hashkey *func_key);
static void plpgsql_HashTableDelete(PLpgSQL_function *function);
!
! /*
! * This routine is a crock, and so is everyplace that calls it. The problem
! * is that the compiled form of a plpgsql function is allocated permanently
! * (mostly via malloc()) and never released until backend exit. Subsidiary
! * data structures such as fmgr info records therefore must live forever
! * as well. A better implementation would store all this stuff in a per-
! * function memory context that could be reclaimed at need. In the meantime,
! * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
! * it might allocate, and whatever the eventual function might allocate using
! * fn_mcxt, will live forever too.
! */
! static void
! perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
! {
! fmgr_info_cxt(functionId, finfo, TopMemoryContext);
! }
!
/* ----------
* plpgsql_compile Make an execution tree for a PL/pgSQL function.
--- 130,136 ----
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
PLpgSQL_func_hashkey *func_key);
static void plpgsql_HashTableDelete(PLpgSQL_function *function);
! static void delete_function(PLpgSQL_function *func);
/* ----------
* plpgsql_compile Make an execution tree for a PL/pgSQL function.
***************
*** 187,196 ****
if (!function)
{
- /* First time through in this backend? If so, init hashtable */
- if (!plpgsql_HashTable)
- plpgsql_HashTableInit();
-
/* Compute hashkey using function signature and actual arg types */
compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
hashkey_valid = true;
--- 170,175 ----
***************
*** 205,216 ****
if (!(function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
function->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data)))
{
! /*
! * Nope, drop the hashtable entry. XXX someday, free all the
! * subsidiary storage as well.
! */
! plpgsql_HashTableDelete(function);
!
function = NULL;
}
}
--- 184,191 ----
if (!(function->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
function->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data)))
{
! /* Nope, drop the function and associated storage */
! delete_function(function);
function = NULL;
}
}
***************
*** 273,278 ****
--- 248,255 ----
int parse_rc;
Oid rettypeid;
char **argnames;
+ MemoryContext old_cxt;
+ MemoryContext func_cxt;
/*
* Setup the scanner input and error info. We assume that this
***************
*** 293,299 ****
* Setup error traceback support for ereport()
*/
plerrcontext.callback = plpgsql_compile_error_callback;
! plerrcontext.arg = forValidator ? proc_source : (char *) NULL;
plerrcontext.previous = error_context_stack;
error_context_stack = &plerrcontext;
--- 270,276 ----
* Setup error traceback support for ereport()
*/
plerrcontext.callback = plpgsql_compile_error_callback;
! plerrcontext.arg = forValidator ? proc_source : NULL;
plerrcontext.previous = error_context_stack;
error_context_stack = &plerrcontext;
***************
*** 302,308 ****
*/
plpgsql_ns_init();
plpgsql_ns_push(NULL);
! plpgsql_DumpExecTree = 0;
datums_alloc = 128;
plpgsql_nDatums = 0;
--- 279,285 ----
*/
plpgsql_ns_init();
plpgsql_ns_push(NULL);
! plpgsql_DumpExecTree = false;
datums_alloc = 128;
plpgsql_nDatums = 0;
***************
*** 310,331 ****
datums_last = 0;
/*
! * Create the new function node
! */
! function = malloc(sizeof(PLpgSQL_function));
! MemSet(function, 0, sizeof(PLpgSQL_function));
plpgsql_curr_compile = function;
! function->fn_name = strdup(NameStr(procStruct->proname));
function->fn_oid = fcinfo->flinfo->fn_oid;
function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
function->fn_functype = functype;
switch (functype)
{
case T_FUNCTION:
-
/*
* Check for a polymorphic returntype. If found, use the
* actual returntype type from the caller's FuncExpr node, if
--- 287,316 ----
datums_last = 0;
/*
! * Create the new function node. We allocate the function and all
! * of its compile-time storage (e.g. parse tree) in its own memory
! * context. This allows us to reclaim the function's storage
! * cleanly.
! */
! func_cxt = AllocSetContextCreate(TopMemoryContext,
! "PL/PgSQL function context",
! ALLOCSET_DEFAULT_MINSIZE,
! ALLOCSET_DEFAULT_INITSIZE,
! ALLOCSET_DEFAULT_MAXSIZE);
! old_cxt = MemoryContextSwitchTo(func_cxt);
! function = palloc0(sizeof(*function));
plpgsql_curr_compile = function;
! function->fn_name = pstrdup(NameStr(procStruct->proname));
function->fn_oid = fcinfo->flinfo->fn_oid;
function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
function->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
function->fn_functype = functype;
+ function->fn_cxt = func_cxt;
switch (functype)
{
case T_FUNCTION:
/*
* Check for a polymorphic returntype. If found, use the
* actual returntype type from the caller's FuncExpr node, if
***************
*** 398,404 ****
function->fn_retbyval = typeStruct->typbyval;
function->fn_rettyplen = typeStruct->typlen;
function->fn_rettypioparam = getTypeIOParam(typeTup);
! perm_fmgr_info(typeStruct->typinput, &(function->fn_retinput));
/*
* install $0 reference, but only for polymorphic return
--- 383,389 ----
function->fn_retbyval = typeStruct->typbyval;
function->fn_rettyplen = typeStruct->typlen;
function->fn_rettypioparam = getTypeIOParam(typeTup);
! fmgr_info(typeStruct->typinput, &(function->fn_retinput));
/*
* install $0 reference, but only for polymorphic return
***************
*** 407,413 ****
if (procStruct->prorettype == ANYARRAYOID ||
procStruct->prorettype == ANYELEMENTOID)
{
! (void) plpgsql_build_variable(strdup("$0"), 0,
build_datatype(typeTup, -1),
true);
}
--- 392,398 ----
if (procStruct->prorettype == ANYARRAYOID ||
procStruct->prorettype == ANYELEMENTOID)
{
! (void) plpgsql_build_variable("$0", 0,
build_datatype(typeTup, -1),
true);
}
***************
*** 449,455 ****
format_type_be(argtypeid))));
/* Build variable and add to datum list */
! argvariable = plpgsql_build_variable(strdup(buf), 0,
argdtype, false);
if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
--- 434,440 ----
format_type_be(argtypeid))));
/* Build variable and add to datum list */
! argvariable = plpgsql_build_variable(buf, 0,
argdtype, false);
if (argvariable->dtype == PLPGSQL_DTYPE_VAR)
***************
*** 478,486 ****
break;
case T_TRIGGER:
-
/*
! * Trigger procedures return type is unknown yet
*/
function->fn_rettype = InvalidOid;
function->fn_retbyval = false;
--- 463,470 ----
break;
case T_TRIGGER:
/*
! * Trigger procedure's return type is unknown yet
*/
function->fn_rettype = InvalidOid;
function->fn_retbyval = false;
***************
*** 490,499 ****
/*
* Add the record for referencing NEW
*/
! rec = malloc(sizeof(PLpgSQL_rec));
! memset(rec, 0, sizeof(PLpgSQL_rec));
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = strdup("new");
rec->tup = NULL;
rec->tupdesc = NULL;
rec->freetup = false;
--- 474,482 ----
/*
* Add the record for referencing NEW
*/
! rec = palloc0(sizeof(PLpgSQL_rec));
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = pstrdup("new");
rec->tup = NULL;
rec->tupdesc = NULL;
rec->freetup = false;
***************
*** 504,513 ****
/*
* Add the record for referencing OLD
*/
! rec = malloc(sizeof(PLpgSQL_rec));
! memset(rec, 0, sizeof(PLpgSQL_rec));
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = strdup("old");
rec->tup = NULL;
rec->tupdesc = NULL;
rec->freetup = false;
--- 487,495 ----
/*
* Add the record for referencing OLD
*/
! rec = palloc0(sizeof(PLpgSQL_rec));
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = pstrdup("old");
rec->tup = NULL;
rec->tupdesc = NULL;
rec->freetup = false;
***************
*** 518,524 ****
/*
* Add the variable tg_name
*/
! var = plpgsql_build_variable(strdup("tg_name"), 0,
plpgsql_build_datatype(NAMEOID, -1),
true);
function->tg_name_varno = var->dno;
--- 500,506 ----
/*
* Add the variable tg_name
*/
! var = plpgsql_build_variable("tg_name", 0,
plpgsql_build_datatype(NAMEOID, -1),
true);
function->tg_name_varno = var->dno;
***************
*** 526,532 ****
/*
* Add the variable tg_when
*/
! var = plpgsql_build_variable(strdup("tg_when"), 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_when_varno = var->dno;
--- 508,514 ----
/*
* Add the variable tg_when
*/
! var = plpgsql_build_variable("tg_when", 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_when_varno = var->dno;
***************
*** 534,540 ****
/*
* Add the variable tg_level
*/
! var = plpgsql_build_variable(strdup("tg_level"), 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_level_varno = var->dno;
--- 516,522 ----
/*
* Add the variable tg_level
*/
! var = plpgsql_build_variable("tg_level", 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_level_varno = var->dno;
***************
*** 542,548 ****
/*
* Add the variable tg_op
*/
! var = plpgsql_build_variable(strdup("tg_op"), 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_op_varno = var->dno;
--- 524,530 ----
/*
* Add the variable tg_op
*/
! var = plpgsql_build_variable("tg_op", 0,
plpgsql_build_datatype(TEXTOID, -1),
true);
function->tg_op_varno = var->dno;
***************
*** 550,556 ****
/*
* Add the variable tg_relid
*/
! var = plpgsql_build_variable(strdup("tg_relid"), 0,
plpgsql_build_datatype(OIDOID, -1),
true);
function->tg_relid_varno = var->dno;
--- 532,538 ----
/*
* Add the variable tg_relid
*/
! var = plpgsql_build_variable("tg_relid", 0,
plpgsql_build_datatype(OIDOID, -1),
true);
function->tg_relid_varno = var->dno;
***************
*** 558,564 ****
/*
* Add the variable tg_relname
*/
! var = plpgsql_build_variable(strdup("tg_relname"), 0,
plpgsql_build_datatype(NAMEOID, -1),
true);
function->tg_relname_varno = var->dno;
--- 540,546 ----
/*
* Add the variable tg_relname
*/
! var = plpgsql_build_variable("tg_relname", 0,
plpgsql_build_datatype(NAMEOID, -1),
true);
function->tg_relname_varno = var->dno;
***************
*** 566,572 ****
/*
* Add the variable tg_nargs
*/
! var = plpgsql_build_variable(strdup("tg_nargs"), 0,
plpgsql_build_datatype(INT4OID, -1),
true);
function->tg_nargs_varno = var->dno;
--- 548,554 ----
/*
* Add the variable tg_nargs
*/
! var = plpgsql_build_variable("tg_nargs", 0,
plpgsql_build_datatype(INT4OID, -1),
true);
function->tg_nargs_varno = var->dno;
***************
*** 584,590 ****
/*
* Create the magic FOUND variable.
*/
! var = plpgsql_build_variable(strdup("found"), 0,
plpgsql_build_datatype(BOOLOID, -1),
true);
function->found_varno = var->dno;
--- 566,572 ----
/*
* Create the magic FOUND variable.
*/
! var = plpgsql_build_variable("found", 0,
plpgsql_build_datatype(BOOLOID, -1),
true);
function->found_varno = var->dno;
***************
*** 611,617 ****
for (i = 0; i < function->fn_nargs; i++)
function->fn_argvarnos[i] = arg_varnos[i];
function->ndatums = plpgsql_nDatums;
! function->datums = malloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
for (i = 0; i < plpgsql_nDatums; i++)
function->datums[i] = plpgsql_Datums[i];
function->action = plpgsql_yylval.program;
--- 593,599 ----
for (i = 0; i < function->fn_nargs; i++)
function->fn_argvarnos[i] = arg_varnos[i];
function->ndatums = plpgsql_nDatums;
! function->datums = palloc(sizeof(PLpgSQL_datum *) * plpgsql_nDatums);
for (i = 0; i < plpgsql_nDatums; i++)
function->datums[i] = plpgsql_Datums[i];
function->action = plpgsql_yylval.program;
***************
*** 632,637 ****
--- 614,621 ----
plpgsql_error_funcname = NULL;
plpgsql_error_lineno = 0;
+ MemoryContextSwitchTo(old_cxt);
+
return function;
}
***************
*** 725,735 ****
{
if (strcmp(cp[0], "tg_argv") == 0)
{
! int save_spacescanned = plpgsql_SpaceScanned;
PLpgSQL_trigarg *trigarg;
! trigarg = malloc(sizeof(PLpgSQL_trigarg));
! memset(trigarg, 0, sizeof(PLpgSQL_trigarg));
trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
if (plpgsql_yylex() != '[')
--- 709,718 ----
{
if (strcmp(cp[0], "tg_argv") == 0)
{
! bool save_spacescanned = plpgsql_SpaceScanned;
PLpgSQL_trigarg *trigarg;
! trigarg = palloc0(sizeof(PLpgSQL_trigarg));
trigarg->dtype = PLPGSQL_DTYPE_TRIGARG;
if (plpgsql_yylex() != '[')
***************
*** 851,859 ****
*/
PLpgSQL_recfield *new;
! new = malloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
! new->fieldname = strdup(cp[1]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
--- 834,842 ----
*/
PLpgSQL_recfield *new;
! new = palloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
! new->fieldname = pstrdup(cp[1]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
***************
*** 957,965 ****
*/
PLpgSQL_recfield *new;
! new = malloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
! new->fieldname = strdup(cp[2]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
--- 940,948 ----
*/
PLpgSQL_recfield *new;
! new = palloc(sizeof(PLpgSQL_recfield));
new->dtype = PLPGSQL_DTYPE_RECFIELD;
! new->fieldname = pstrdup(cp[2]);
new->recparentno = ns->itemno;
plpgsql_adddatum((PLpgSQL_datum *) new);
***************
*** 1038,1044 ****
pfree(cp[1]);
/*
! * Do a lookup on the compilers namestack. But ensure it moves up to
* the toplevel.
*/
old_nsstate = plpgsql_ns_setlocal(false);
--- 1021,1027 ----
pfree(cp[1]);
/*
! * Do a lookup on the compiler's namestack. But ensure it moves up to
* the toplevel.
*/
old_nsstate = plpgsql_ns_setlocal(false);
***************
*** 1433,1446 ****
}
/*
! * plpgsql_build_variable - build a datum-array entry of a given datatype
*
! * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or PLpgSQL_rec
! * depending on the given datatype. The struct is automatically added
! * to the current datum array, and optionally to the current namespace.
*/
PLpgSQL_variable *
! plpgsql_build_variable(char *refname, int lineno, PLpgSQL_type *dtype,
bool add2namespace)
{
PLpgSQL_variable *result;
--- 1416,1431 ----
}
/*
! * plpgsql_build_variable - build a datum-array entry of a given
! * datatype
*
! * The returned struct may be a PLpgSQL_var, PLpgSQL_row, or
! * PLpgSQL_rec depending on the given datatype, and is allocated via
! * palloc. The struct is automatically added to the current datum
! * array, and optionally to the current namespace.
*/
PLpgSQL_variable *
! plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype,
bool add2namespace)
{
PLpgSQL_variable *result;
***************
*** 1452,1462 ****
/* Ordinary scalar datatype */
PLpgSQL_var *var;
! var = malloc(sizeof(PLpgSQL_var));
! memset(var, 0, sizeof(PLpgSQL_var));
!
var->dtype = PLPGSQL_DTYPE_VAR;
! var->refname = refname;
var->lineno = lineno;
var->datatype = dtype;
/* other fields might be filled by caller */
--- 1437,1445 ----
/* Ordinary scalar datatype */
PLpgSQL_var *var;
! var = palloc0(sizeof(PLpgSQL_var));
var->dtype = PLPGSQL_DTYPE_VAR;
! var->refname = pstrdup(refname);
var->lineno = lineno;
var->datatype = dtype;
/* other fields might be filled by caller */
***************
*** 1482,1488 ****
row = build_row_var(dtype->typrelid);
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = refname;
row->lineno = lineno;
plpgsql_adddatum((PLpgSQL_datum *) row);
--- 1465,1471 ----
row = build_row_var(dtype->typrelid);
row->dtype = PLPGSQL_DTYPE_ROW;
! row->refname = pstrdup(refname);
row->lineno = lineno;
plpgsql_adddatum((PLpgSQL_datum *) row);
***************
*** 1501,1511 ****
*/
PLpgSQL_rec *rec;
! rec = malloc(sizeof(PLpgSQL_rec));
! memset(rec, 0, sizeof(PLpgSQL_rec));
!
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = refname;
rec->lineno = lineno;
plpgsql_adddatum((PLpgSQL_datum *) rec);
--- 1484,1492 ----
*/
PLpgSQL_rec *rec;
! rec = palloc0(sizeof(PLpgSQL_rec));
rec->dtype = PLPGSQL_DTYPE_REC;
! rec->refname = pstrdup(refname);
rec->lineno = lineno;
plpgsql_adddatum((PLpgSQL_datum *) rec);
***************
*** 1517,1530 ****
break;
}
case PLPGSQL_TTYPE_PSEUDO:
! {
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("variable \"%s\" has pseudo-type %s",
! refname, format_type_be(dtype->typoid))));
! result = NULL; /* keep compiler quiet */
! break;
! }
default:
elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
result = NULL; /* keep compiler quiet */
--- 1498,1509 ----
break;
}
case PLPGSQL_TTYPE_PSEUDO:
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("variable \"%s\" has pseudo-type %s",
! refname, format_type_be(dtype->typoid))));
! result = NULL; /* keep compiler quiet */
! break;
default:
elog(ERROR, "unrecognized ttype: %d", dtype->ttype);
result = NULL; /* keep compiler quiet */
***************
*** 1545,1551 ****
Form_pg_class classStruct;
const char *relname;
int i;
- MemoryContext oldcxt;
/*
* Open the relation to get info.
--- 1524,1529 ----
***************
*** 1567,1589 ****
* Create a row datum entry and all the required variables that it
* will point to.
*/
! row = malloc(sizeof(PLpgSQL_row));
! memset(row, 0, sizeof(PLpgSQL_row));
!
row->dtype = PLPGSQL_DTYPE_ROW;
-
- /*
- * This is a bit ugly --- need a permanent copy of the rel's tupdesc.
- * Someday all these mallocs should go away in favor of a per-function
- * memory context ...
- */
- oldcxt = MemoryContextSwitchTo(TopMemoryContext);
row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
- MemoryContextSwitchTo(oldcxt);
-
row->nfields = classStruct->relnatts;
! row->fieldnames = malloc(sizeof(char *) * row->nfields);
! row->varnos = malloc(sizeof(int) * row->nfields);
for (i = 0; i < row->nfields; i++)
{
--- 1545,1556 ----
* Create a row datum entry and all the required variables that it
* will point to.
*/
! row = palloc0(sizeof(PLpgSQL_row));
row->dtype = PLPGSQL_DTYPE_ROW;
row->rowtupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
row->nfields = classStruct->relnatts;
! row->fieldnames = palloc(sizeof(char *) * row->nfields);
! row->varnos = palloc(sizeof(int) * row->nfields);
for (i = 0; i < row->nfields; i++)
{
***************
*** 1592,1610 ****
/*
* Get the attribute and check for dropped column
*/
! attrStruct = RelationGetDescr(rel)->attrs[i];
if (!attrStruct->attisdropped)
{
! const char *attname;
! char *refname;
PLpgSQL_variable *var;
attname = NameStr(attrStruct->attname);
! refname = malloc(strlen(relname) + strlen(attname) + 2);
! strcpy(refname, relname);
! strcat(refname, ".");
! strcat(refname, attname);
/*
* Create the internal variable for the field
--- 1559,1574 ----
/*
* Get the attribute and check for dropped column
*/
! attrStruct = row->rowtupdesc->attrs[i];
if (!attrStruct->attisdropped)
{
! char *attname;
! char refname[(NAMEDATALEN * 2) + 100];
PLpgSQL_variable *var;
attname = NameStr(attrStruct->attname);
! snprintf(refname, sizeof(refname), "%s.%s", relname, attname);
/*
* Create the internal variable for the field
***************
*** 1624,1630 ****
/*
* Add the variable to the row.
*/
! row->fieldnames[i] = strdup(attname);
row->varnos[i] = var->dno;
}
else
--- 1588,1595 ----
/*
* Add the variable to the row.
*/
! /* XXX: does this need to be pstrdup'd? */
! row->fieldnames[i] = attname;
row->varnos[i] = var->dno;
}
else
***************
*** 1697,1705 ****
errmsg("type \"%s\" is only a shell",
NameStr(typeStruct->typname))));
! typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
! typ->typname = strdup(NameStr(typeStruct->typname));
typ->typoid = HeapTupleGetOid(typeTup);
switch (typeStruct->typtype)
{
--- 1662,1670 ----
errmsg("type \"%s\" is only a shell",
NameStr(typeStruct->typname))));
! typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
! typ->typname = pstrdup(NameStr(typeStruct->typname));
typ->typoid = HeapTupleGetOid(typeTup);
switch (typeStruct->typtype)
{
***************
*** 1726,1732 ****
typ->typbyval = typeStruct->typbyval;
typ->typrelid = typeStruct->typrelid;
typ->typioparam = getTypeIOParam(typeTup);
! perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
typ->atttypmod = typmod;
return typ;
--- 1691,1697 ----
typ->typbyval = typeStruct->typbyval;
typ->typrelid = typeStruct->typrelid;
typ->typioparam = getTypeIOParam(typeTup);
! fmgr_info(typeStruct->typinput, &(typ->typinput));
typ->atttypmod = typmod;
return typ;
***************
*** 1757,1763 ****
*/
if (strcmp(condname, "others") == 0)
{
! new = malloc(sizeof(PLpgSQL_condition));
new->sqlerrstate = 0;
new->condname = condname;
new->next = NULL;
--- 1722,1728 ----
*/
if (strcmp(condname, "others") == 0)
{
! new = palloc(sizeof(PLpgSQL_condition));
new->sqlerrstate = 0;
new->condname = condname;
new->next = NULL;
***************
*** 1769,1775 ****
{
if (strcmp(condname, exception_label_map[i].label) == 0)
{
! new = malloc(sizeof(PLpgSQL_condition));
new->sqlerrstate = exception_label_map[i].sqlerrstate;
new->condname = condname;
new->next = prev;
--- 1734,1740 ----
{
if (strcmp(condname, exception_label_map[i].label) == 0)
{
! new = palloc(sizeof(PLpgSQL_condition));
new->sqlerrstate = exception_label_map[i].sqlerrstate;
new->condname = condname;
new->next = prev;
***************
*** 1836,1842 ****
{
if (n > 0)
{
! *varnos = (int *) malloc(sizeof(int) * n);
n = 0;
for (i = datums_last; i < plpgsql_nDatums; i++)
--- 1801,1807 ----
{
if (n > 0)
{
! *varnos = (int *) palloc(sizeof(int) * n);
n = 0;
for (i = datums_last; i < plpgsql_nDatums; i++)
***************
*** 1930,1941 ****
--- 1895,1924 ----
}
}
+ static void
+ delete_function(PLpgSQL_function *func)
+ {
+ /* remove function from hash table */
+ plpgsql_HashTableDelete(func);
+
+ /* release the function's storage */
+ MemoryContextDelete(func->fn_cxt);
+
+ /*
+ * Caller should be sure not to use passed-in pointer, as it now
+ * points to pfree'd storage
+ */
+ }
+
/* exported so we can call it from plpgsql_init() */
void
plpgsql_HashTableInit(void)
{
HASHCTL ctl;
+ /* don't allow double-initialization */
+ Assert(plpgsql_HashTable == NULL);
+
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = sizeof(PLpgSQL_func_hashkey);
ctl.entrysize = sizeof(plpgsql_HashEnt);
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.127
diff -c -r1.127 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c 13 Jan 2005 23:07:34 -0000 1.127
--- src/pl/plpgsql/src/pl_exec.c 19 Jan 2005 23:52:06 -0000
***************
*** 74,86 ****
* Local function forward declarations
************************************************************/
static void plpgsql_exec_error_callback(void *arg);
static PLpgSQL_var *copy_var(PLpgSQL_var *var);
static PLpgSQL_rec *copy_rec(PLpgSQL_rec *rec);
static int exec_stmt_block(PLpgSQL_execstate *estate,
PLpgSQL_stmt_block *block);
static int exec_stmts(PLpgSQL_execstate *estate,
! PLpgSQL_stmts *stmts);
static int exec_stmt(PLpgSQL_execstate *estate,
PLpgSQL_stmt *stmt);
static int exec_stmt_assign(PLpgSQL_execstate *estate,
--- 74,87 ----
* Local function forward declarations
************************************************************/
static void plpgsql_exec_error_callback(void *arg);
+ static PLpgSQL_datum *copy_plpgsql_datum(PLpgSQL_datum *datum);
static PLpgSQL_var *copy_var(PLpgSQL_var *var);
static PLpgSQL_rec *copy_rec(PLpgSQL_rec *rec);
static int exec_stmt_block(PLpgSQL_execstate *estate,
PLpgSQL_stmt_block *block);
static int exec_stmts(PLpgSQL_execstate *estate,
! List *stmts);
static int exec_stmt(PLpgSQL_execstate *estate,
PLpgSQL_stmt *stmt);
static int exec_stmt_assign(PLpgSQL_execstate *estate,
***************
*** 212,240 ****
*/
estate.err_text = gettext_noop("during initialization of execution state");
for (i = 0; i < func->ndatums; i++)
! {
! switch (func->datums[i]->dtype)
! {
! case PLPGSQL_DTYPE_VAR:
! estate.datums[i] = (PLpgSQL_datum *)
! copy_var((PLpgSQL_var *) (func->datums[i]));
! break;
!
! case PLPGSQL_DTYPE_REC:
! estate.datums[i] = (PLpgSQL_datum *)
! copy_rec((PLpgSQL_rec *) (func->datums[i]));
! break;
!
! case PLPGSQL_DTYPE_ROW:
! case PLPGSQL_DTYPE_RECFIELD:
! case PLPGSQL_DTYPE_ARRAYELEM:
! estate.datums[i] = func->datums[i];
! break;
!
! default:
! elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
! }
! }
/*
* Store the actual call argument values into the variables
--- 213,219 ----
*/
estate.err_text = gettext_noop("during initialization of execution state");
for (i = 0; i < func->ndatums; i++)
! estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
/*
* Store the actual call argument values into the variables
***************
*** 467,496 ****
*/
estate.err_text = gettext_noop("during initialization of execution state");
for (i = 0; i < func->ndatums; i++)
! {
! switch (func->datums[i]->dtype)
! {
! case PLPGSQL_DTYPE_VAR:
! estate.datums[i] = (PLpgSQL_datum *)
! copy_var((PLpgSQL_var *) (func->datums[i]));
! break;
!
! case PLPGSQL_DTYPE_REC:
! estate.datums[i] = (PLpgSQL_datum *)
! copy_rec((PLpgSQL_rec *) (func->datums[i]));
! break;
!
! case PLPGSQL_DTYPE_ROW:
! case PLPGSQL_DTYPE_RECFIELD:
! case PLPGSQL_DTYPE_ARRAYELEM:
! case PLPGSQL_DTYPE_TRIGARG:
! estate.datums[i] = func->datums[i];
! break;
!
! default:
! elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
! }
! }
/*
* Put the OLD and NEW tuples into record variables
--- 446,452 ----
*/
estate.err_text = gettext_noop("during initialization of execution state");
for (i = 0; i < func->ndatums; i++)
! estate.datums[i] = copy_plpgsql_datum(func->datums[i]);
/*
* Put the OLD and NEW tuples into record variables
***************
*** 758,763 ****
--- 714,748 ----
* Support functions for copying local execution variables
* ----------
*/
+ static PLpgSQL_datum *
+ copy_plpgsql_datum(PLpgSQL_datum *datum)
+ {
+ PLpgSQL_datum *result = NULL;
+
+ switch (datum->dtype)
+ {
+ case PLPGSQL_DTYPE_VAR:
+ result = (PLpgSQL_datum *) copy_var((PLpgSQL_var *) datum);
+ break;
+
+ case PLPGSQL_DTYPE_REC:
+ result = (PLpgSQL_datum *) copy_rec((PLpgSQL_rec *) datum);
+ break;
+
+ case PLPGSQL_DTYPE_ROW:
+ case PLPGSQL_DTYPE_RECFIELD:
+ case PLPGSQL_DTYPE_ARRAYELEM:
+ case PLPGSQL_DTYPE_TRIGARG:
+ result = datum;
+ break;
+
+ default:
+ elog(ERROR, "unrecognized dtype: %d", datum->dtype);
+ }
+
+ return result;
+ }
+
static PLpgSQL_var *
copy_var(PLpgSQL_var *var)
{
***************
*** 920,928 ****
}
PG_CATCH();
{
! ErrorData *edata;
! PLpgSQL_exceptions *exceptions;
! int j;
/* Save error info */
MemoryContextSwitchTo(oldcontext);
--- 905,912 ----
}
PG_CATCH();
{
! ErrorData *edata;
! ListCell *e;
/* Save error info */
MemoryContextSwitchTo(oldcontext);
***************
*** 942,951 ****
SPI_restore_connection();
/* Look for a matching exception handler */
! exceptions = block->exceptions;
! for (j = 0; j < exceptions->exceptions_used; j++)
{
! PLpgSQL_exception *exception = exceptions->exceptions[j];
if (exception_matches_conditions(edata, exception->conditions))
{
--- 926,934 ----
SPI_restore_connection();
/* Look for a matching exception handler */
! foreach (e, block->exceptions)
{
! PLpgSQL_exception *exception = (PLpgSQL_exception *) lfirst(e);
if (exception_matches_conditions(edata, exception->conditions))
{
***************
*** 955,961 ****
}
/* If no match found, re-throw the error */
! if (j >= exceptions->exceptions_used)
ReThrowError(edata);
else
FreeErrorData(edata);
--- 938,944 ----
}
/* If no match found, re-throw the error */
! if (e == NULL)
ReThrowError(edata);
else
FreeErrorData(edata);
***************
*** 1005,1018 ****
* ----------
*/
static int
! exec_stmts(PLpgSQL_execstate *estate, PLpgSQL_stmts *stmts)
{
! int rc;
! int i;
! for (i = 0; i < stmts->stmts_used; i++)
{
! rc = exec_stmt(estate, stmts->stmts[i]);
if (rc != PLPGSQL_RC_OK)
return rc;
}
--- 988,1001 ----
* ----------
*/
static int
! exec_stmts(PLpgSQL_execstate *estate, List *stmts)
{
! ListCell *s;
! foreach (s, stmts)
{
! PLpgSQL_stmt *stmt = (PLpgSQL_stmt *) lfirst(s);
! int rc = exec_stmt(estate, stmt);
if (rc != PLPGSQL_RC_OK)
return rc;
}
***************
*** 1242,1253 ****
if (!isnull && value)
{
! if (stmt->true_body != NULL)
return exec_stmts(estate, stmt->true_body);
}
else
{
! if (stmt->false_body != NULL)
return exec_stmts(estate, stmt->false_body);
}
--- 1225,1236 ----
if (!isnull && value)
{
! if (stmt->true_body != NIL)
return exec_stmts(estate, stmt->true_body);
}
else
{
! if (stmt->false_body != NIL)
return exec_stmts(estate, stmt->false_body);
}
Index: src/pl/plpgsql/src/pl_funcs.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/pl_funcs.c,v
retrieving revision 1.38
diff -c -r1.38 pl_funcs.c
*** src/pl/plpgsql/src/pl_funcs.c 10 Oct 2004 23:37:45 -0000 1.38
--- src/pl/plpgsql/src/pl_funcs.c 19 Jan 2005 23:52:06 -0000
***************
*** 187,193 ****
* ----------
*/
void
! plpgsql_ns_additem(int itemtype, int itemno, char *name)
{
PLpgSQL_ns *ns = ns_current;
PLpgSQL_nsitem *nse;
--- 187,193 ----
* ----------
*/
void
! plpgsql_ns_additem(int itemtype, int itemno, const char *name)
{
PLpgSQL_ns *ns = ns_current;
PLpgSQL_nsitem *nse;
***************
*** 286,296 ****
int i;
/*
! * Lookup in the current namespace only
! */
!
! /*
! * Lookup name in the namestack
*/
for (ns = ns_current; ns != NULL; ns = ns->upper)
{
--- 286,293 ----
int i;
/*
! * Lookup name in the namestack; do the lookup in the current
! * namespace only.
*/
for (ns = ns_current; ns != NULL; ns = ns->upper)
{
***************
*** 584,603 ****
}
static void
! dump_stmts(PLpgSQL_stmts *stmts)
{
! int i;
dump_indent += 2;
! for (i = 0; i < stmts->stmts_used; i++)
! dump_stmt(stmts->stmts[i]);
dump_indent -= 2;
}
static void
dump_block(PLpgSQL_stmt_block *block)
{
- int i;
char *name;
if (block->label == NULL)
--- 581,599 ----
}
static void
! dump_stmts(List *stmts)
{
! ListCell *s;
dump_indent += 2;
! foreach (s, stmts)
! dump_stmt((PLpgSQL_stmt *) lfirst(s));
dump_indent -= 2;
}
static void
dump_block(PLpgSQL_stmt_block *block)
{
char *name;
if (block->label == NULL)
***************
*** 612,620 ****
if (block->exceptions)
{
! for (i = 0; i < block->exceptions->exceptions_used; i++)
{
! PLpgSQL_exception *exc = block->exceptions->exceptions[i];
PLpgSQL_condition *cond;
dump_ind();
--- 608,618 ----
if (block->exceptions)
{
! ListCell *e;
!
! foreach (e, block->exceptions)
{
! PLpgSQL_exception *exc = (PLpgSQL_exception *) lfirst(e);
PLpgSQL_condition *cond;
dump_ind();
Index: src/pl/plpgsql/src/pl_handler.c
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/pl_handler.c,v
retrieving revision 1.23
diff -c -r1.23 pl_handler.c
*** src/pl/plpgsql/src/pl_handler.c 1 Aug 2004 17:32:22 -0000 1.23
--- src/pl/plpgsql/src/pl_handler.c 19 Jan 2005 23:52:06 -0000
***************
*** 47,53 ****
extern DLLIMPORT bool check_function_bodies;
! static int plpgsql_firstcall = 1;
static void plpgsql_init_all(void);
--- 47,53 ----
extern DLLIMPORT bool check_function_bodies;
! static bool plpgsql_firstcall = true;
static void plpgsql_init_all(void);
***************
*** 65,74 ****
return;
plpgsql_HashTableInit();
-
RegisterXactCallback(plpgsql_xact_cb, NULL);
!
! plpgsql_firstcall = 0;
}
/*
--- 65,72 ----
return;
plpgsql_HashTableInit();
RegisterXactCallback(plpgsql_xact_cb, NULL);
! plpgsql_firstcall = false;
}
/*
***************
*** 78,91 ****
plpgsql_init_all(void)
{
/* Execute any postmaster-startup safe initialization */
! if (plpgsql_firstcall)
! plpgsql_init();
/*
* Any other initialization that must be done each time a new backend
* starts -- currently none
*/
-
}
/* ----------
--- 76,87 ----
plpgsql_init_all(void)
{
/* Execute any postmaster-startup safe initialization */
! plpgsql_init();
/*
* Any other initialization that must be done each time a new backend
* starts -- currently none
*/
}
/* ----------
Index: src/pl/plpgsql/src/plpgsql.h
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/plpgsql.h,v
retrieving revision 1.56
diff -c -r1.56 plpgsql.h
*** src/pl/plpgsql/src/plpgsql.h 16 Sep 2004 16:58:44 -0000 1.56
--- src/pl/plpgsql/src/plpgsql.h 19 Jan 2005 23:52:06 -0000
***************
*** 50,56 ****
**********************************************************************/
/* ----------
! * Compilers namestack item types
* ----------
*/
enum
--- 50,56 ----
**********************************************************************/
/* ----------
! * Compiler's namestack item types
* ----------
*/
enum
***************
*** 298,303 ****
--- 298,304 ----
} PLpgSQL_nsitem;
+ /* XXX: consider adapting this to use List */
typedef struct PLpgSQL_ns
{ /* Compiler namestack level */
int items_alloc;
***************
*** 314,327 ****
} PLpgSQL_stmt;
- typedef struct
- { /* List of execution nodes */
- int stmts_alloc; /* XXX this oughta just be a List ... */
- int stmts_used;
- PLpgSQL_stmt **stmts;
- } PLpgSQL_stmts;
-
-
typedef struct PLpgSQL_condition
{ /* One EXCEPTION condition name */
int sqlerrstate; /* SQLSTATE code */
--- 315,320 ----
***************
*** 333,358 ****
{ /* One EXCEPTION ... WHEN clause */
int lineno;
PLpgSQL_condition *conditions;
! PLpgSQL_stmts *action;
} PLpgSQL_exception;
typedef struct
- { /* List of WHEN clauses */
- int exceptions_alloc; /* XXX this oughta just be a List
- * ... */
- int exceptions_used;
- PLpgSQL_exception **exceptions;
- } PLpgSQL_exceptions;
-
-
- typedef struct
{ /* Block of statements */
int cmd_type;
int lineno;
char *label;
! PLpgSQL_stmts *body;
! PLpgSQL_exceptions *exceptions;
int n_initvars;
int *initvarnos;
} PLpgSQL_stmt_block;
--- 326,342 ----
{ /* One EXCEPTION ... WHEN clause */
int lineno;
PLpgSQL_condition *conditions;
! List *action; /* List of statements */
} PLpgSQL_exception;
typedef struct
{ /* Block of statements */
int cmd_type;
int lineno;
char *label;
! List *body; /* List of statements */
! List *exceptions; /* List of WHEN clauses */
int n_initvars;
int *initvarnos;
} PLpgSQL_stmt_block;
***************
*** 393,400 ****
int cmd_type;
int lineno;
PLpgSQL_expr *cond;
! PLpgSQL_stmts *true_body;
! PLpgSQL_stmts *false_body;
} PLpgSQL_stmt_if;
--- 377,384 ----
int cmd_type;
int lineno;
PLpgSQL_expr *cond;
! List *true_body; /* List of statements */
! List *false_body; /* List of statements */
} PLpgSQL_stmt_if;
***************
*** 403,409 ****
int cmd_type;
int lineno;
char *label;
! PLpgSQL_stmts *body;
} PLpgSQL_stmt_loop;
--- 387,393 ----
int cmd_type;
int lineno;
char *label;
! List *body; /* List of statements */
} PLpgSQL_stmt_loop;
***************
*** 413,419 ****
int lineno;
char *label;
PLpgSQL_expr *cond;
! PLpgSQL_stmts *body;
} PLpgSQL_stmt_while;
--- 397,403 ----
int lineno;
char *label;
PLpgSQL_expr *cond;
! List *body; /* List of statements */
} PLpgSQL_stmt_while;
***************
*** 426,432 ****
PLpgSQL_expr *lower;
PLpgSQL_expr *upper;
int reverse;
! PLpgSQL_stmts *body;
} PLpgSQL_stmt_fori;
--- 410,416 ----
PLpgSQL_expr *lower;
PLpgSQL_expr *upper;
int reverse;
! List *body; /* List of statements */
} PLpgSQL_stmt_fori;
***************
*** 438,444 ****
PLpgSQL_rec *rec;
PLpgSQL_row *row;
PLpgSQL_expr *query;
! PLpgSQL_stmts *body;
} PLpgSQL_stmt_fors;
--- 422,428 ----
PLpgSQL_rec *rec;
PLpgSQL_row *row;
PLpgSQL_expr *query;
! List *body; /* List of statements */
} PLpgSQL_stmt_fors;
***************
*** 450,456 ****
PLpgSQL_rec *rec;
PLpgSQL_row *row;
PLpgSQL_expr *query;
! PLpgSQL_stmts *body;
} PLpgSQL_stmt_dynfors;
--- 434,440 ----
PLpgSQL_rec *rec;
PLpgSQL_row *row;
PLpgSQL_expr *query;
! List *body; /* List of statements */
} PLpgSQL_stmt_dynfors;
***************
*** 577,582 ****
--- 561,567 ----
CommandId fn_cmin;
int fn_functype;
PLpgSQL_func_hashkey *fn_hashkey; /* back-link to hashtable key */
+ MemoryContext fn_cxt;
Oid fn_rettype;
int fn_rettyplen;
***************
*** 649,656 ****
* Global variable declarations
**********************************************************************/
! extern int plpgsql_DumpExecTree;
! extern int plpgsql_SpaceScanned;
extern int plpgsql_nDatums;
extern PLpgSQL_datum **plpgsql_Datums;
--- 634,641 ----
* Global variable declarations
**********************************************************************/
! extern bool plpgsql_DumpExecTree;
! extern bool plpgsql_SpaceScanned;
extern int plpgsql_nDatums;
extern PLpgSQL_datum **plpgsql_Datums;
***************
*** 684,690 ****
extern int plpgsql_parse_dblwordrowtype(char *word);
extern PLpgSQL_type *plpgsql_parse_datatype(const char *string);
extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod);
! extern PLpgSQL_variable *plpgsql_build_variable(char *refname, int lineno,
PLpgSQL_type *dtype,
bool add2namespace);
extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname);
--- 669,675 ----
extern int plpgsql_parse_dblwordrowtype(char *word);
extern PLpgSQL_type *plpgsql_parse_datatype(const char *string);
extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod);
! extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno,
PLpgSQL_type *dtype,
bool add2namespace);
extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname);
***************
*** 727,733 ****
extern bool plpgsql_ns_setlocal(bool flag);
extern void plpgsql_ns_push(char *label);
extern void plpgsql_ns_pop(void);
! extern void plpgsql_ns_additem(int itemtype, int itemno, char *name);
extern PLpgSQL_nsitem *plpgsql_ns_lookup(char *name, char *nsname);
extern void plpgsql_ns_rename(char *oldname, char *newname);
--- 712,718 ----
extern bool plpgsql_ns_setlocal(bool flag);
extern void plpgsql_ns_push(char *label);
extern void plpgsql_ns_pop(void);
! extern void plpgsql_ns_additem(int itemtype, int itemno, const char *name);
extern PLpgSQL_nsitem *plpgsql_ns_lookup(char *name, char *nsname);
extern void plpgsql_ns_rename(char *oldname, char *newname);
Index: src/pl/plpgsql/src/scan.l
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/scan.l,v
retrieving revision 1.38
diff -c -r1.38 scan.l
*** src/pl/plpgsql/src/scan.l 17 Dec 2004 03:51:36 -0000 1.38
--- src/pl/plpgsql/src/scan.l 19 Jan 2005 23:52:06 -0000
***************
*** 54,60 ****
static const char *scanstr; /* original input string */
static int scanner_functype;
! static int scanner_typereported;
static int pushback_token;
static bool have_pushback_token;
static int lookahead_token;
--- 54,60 ----
static const char *scanstr; /* original input string */
static int scanner_functype;
! static bool scanner_typereported;
static int pushback_token;
static bool have_pushback_token;
static int lookahead_token;
***************
*** 64,70 ****
static char *dolqstart; /* current $foo$ quote start string */
static int dolqlen; /* signal to plpgsql_get_string_value */
! int plpgsql_SpaceScanned = 0;
%}
%option 8bit
--- 64,70 ----
static char *dolqstart; /* current $foo$ quote start string */
static int dolqlen; /* signal to plpgsql_get_string_value */
! bool plpgsql_SpaceScanned = false;
%}
%option 8bit
***************
*** 114,120 ****
* ----------
*/
BEGIN(INITIAL);
! plpgsql_SpaceScanned = 0;
/* ----------
* On the first call to a new source report the
--- 114,120 ----
* ----------
*/
BEGIN(INITIAL);
! plpgsql_SpaceScanned = false;
/* ----------
* On the first call to a new source report the
***************
*** 123,129 ****
*/
if (!scanner_typereported)
{
! scanner_typereported = 1;
return scanner_functype;
}
--- 123,129 ----
*/
if (!scanner_typereported)
{
! scanner_typereported = true;
return scanner_functype;
}
***************
*** 255,261 ****
* Ignore whitespaces but remember this happened
* ----------
*/
! {space}+ { plpgsql_SpaceScanned = 1; }
/* ----------
* Eat up comments
--- 255,261 ----
* Ignore whitespaces but remember this happened
* ----------
*/
! {space}+ { plpgsql_SpaceScanned = true; }
/* ----------
* Eat up comments
***************
*** 266,272 ****
\/\* { start_lineno = plpgsql_scanner_lineno();
BEGIN(IN_COMMENT);
}
! <IN_COMMENT>\*\/ { BEGIN(INITIAL); plpgsql_SpaceScanned = 1; }
<IN_COMMENT>\n ;
<IN_COMMENT>. ;
<IN_COMMENT><<EOF>> {
--- 266,272 ----
\/\* { start_lineno = plpgsql_scanner_lineno();
BEGIN(IN_COMMENT);
}
! <IN_COMMENT>\*\/ { BEGIN(INITIAL); plpgsql_SpaceScanned = true; }
<IN_COMMENT>\n ;
<IN_COMMENT>. ;
<IN_COMMENT><<EOF>> {
***************
*** 502,508 ****
scanstr = str;
scanner_functype = functype;
! scanner_typereported = 0;
have_pushback_token = false;
have_lookahead_token = false;
--- 502,508 ----
scanstr = str;
scanner_functype = functype;
! scanner_typereported = false;
have_pushback_token = false;
have_lookahead_token = false;
create function refcursor_test2(int) returns boolean as $$
declare
c1 cursor (param0 integer, param1 integer, param2 integer, param3 integer, param4 integer, param5 integer, param6 integer, param7 integer, param8 integer, param9 integer, param10 integer, param11 integer, param12 integer, param13 integer, param14 integer, param15 integer, param16 integer, param17 integer, param18 integer, param19 integer, param20 integer, param21 integer, param22 integer, param23 integer, param24 integer, param25 integer, param26 integer, param27 integer, param28 integer, param29 integer, param30 integer, param31 integer, param32 integer, param33 integer, param34 integer, param35 integer, param36 integer, param37 integer, param38 integer, param39 integer, param40 integer, param41 integer, param42 integer, param43 integer, param44 integer, param45 integer, param46 integer, param47 integer, param48 integer, param49 integer, param50 integer, param51 integer, param52 integer, param53 integer, param54 integer, param55 integer, param56 integer, param57 integer, param58 integer, param59 integer, param60 integer, param61 integer, param62 integer, param63 integer, param64 integer, param65 integer, param66 integer, param67 integer, param68 integer, param69 integer, param70 integer, param71 integer, param72 integer, param73 integer, param74 integer, param75 integer, param76 integer, param77 integer, param78 integer, param79 integer, param80 integer, param81 integer, param82 integer, param83 integer, param84 integer, param85 integer, param86 integer, param87 integer, param88 integer, param89 integer, param90 integer, param91 integer, param92 integer, param93 integer, param94 integer, param95 integer, param96 integer, param97 integer, param98 integer, param99 integer, param100 integer, param101 integer, param102 integer, param103 integer, param104 integer, param105 integer, param106 integer, param107 integer, param108 integer, param109 integer, param110 integer, param111 integer, param112 integer, param113 integer, param114 integer, param115 integer, param116 integer, param117 integer, param118 integer, param119 integer, param120 integer, param121 integer, param122 integer, param123 integer, param124 integer, param125 integer, param126 integer, param127 integer, param128 integer, param129 integer, param130 integer, param131 integer, param132 integer, param133 integer, param134 integer, param135 integer, param136 integer, param137 integer, param138 integer, param139 integer, param140 integer, param141 integer, param142 integer, param143 integer, param144 integer, param145 integer, param146 integer, param147 integer, param148 integer, param149 integer, param150 integer, param151 integer, param152 integer, param153 integer, param154 integer, param155 integer, param156 integer, param157 integer, param158 integer, param159 integer, param160 integer, param161 integer, param162 integer, param163 integer, param164 integer, param165 integer, param166 integer, param167 integer, param168 integer, param169 integer, param170 integer, param171 integer, param172 integer, param173 integer, param174 integer, param175 integer, param176 integer, param177 integer, param178 integer, param179 integer, param180 integer, param181 integer, param182 integer, param183 integer, param184 integer, param185 integer, param186 integer, param187 integer, param188 integer, param189 integer, param190 integer, param191 integer, param192 integer, param193 integer, param194 integer, param195 integer, param196 integer, param197 integer, param198 integer, param199 integer, param200 integer, param201 integer, param202 integer, param203 integer, param204 integer, param205 integer, param206 integer, param207 integer, param208 integer, param209 integer, param210 integer, param211 integer, param212 integer, param213 integer, param214 integer, param215 integer, param216 integer, param217 integer, param218 integer, param219 integer, param220 integer, param221 integer, param222 integer, param223 integer, param224 integer, param225 integer, param226 integer, param227 integer, param228 integer, param229 integer, param230 integer, param231 integer, param232 integer, param233 integer, param234 integer, param235 integer, param236 integer, param237 integer, param238 integer, param239 integer, param240 integer, param241 integer, param242 integer, param243 integer, param244 integer, param245 integer, param246 integer, param247 integer, param248 integer, param249 integer, param250 integer, param251 integer, param252 integer, param253 integer, param254 integer, param255 integer, param256 integer, param257 integer, param258 integer, param259 integer, param260 integer, param261 integer, param262 integer, param263 integer, param264 integer, param265 integer, param266 integer, param267 integer, param268 integer, param269 integer, param270 integer, param271 integer, param272 integer, param273 integer, param274 integer, param275 integer, param276 integer, param277 integer, param278 integer, param279 integer, param280 integer, param281 integer, param282 integer, param283 integer, param284 integer, param285 integer, param286 integer, param287 integer, param288 integer, param289 integer, param290 integer, param291 integer, param292 integer, param293 integer, param294 integer, param295 integer, param296 integer, param297 integer, param298 integer, param299 integer, param300 integer, param301 integer, param302 integer, param303 integer, param304 integer, param305 integer, param306 integer, param307 integer, param308 integer, param309 integer, param310 integer, param311 integer, param312 integer, param313 integer, param314 integer, param315 integer, param316 integer, param317 integer, param318 integer, param319 integer, param320 integer, param321 integer, param322 integer, param323 integer, param324 integer, param325 integer, param326 integer, param327 integer, param328 integer, param329 integer, param330 integer, param331 integer, param332 integer, param333 integer, param334 integer, param335 integer, param336 integer, param337 integer, param338 integer, param339 integer, param340 integer, param341 integer, param342 integer, param343 integer, param344 integer, param345 integer, param346 integer, param347 integer, param348 integer, param349 integer, param350 integer, param351 integer, param352 integer, param353 integer, param354 integer, param355 integer, param356 integer, param357 integer, param358 integer, param359 integer, param360 integer, param361 integer, param362 integer, param363 integer, param364 integer, param365 integer, param366 integer, param367 integer, param368 integer, param369 integer, param370 integer, param371 integer, param372 integer, param373 integer, param374 integer, param375 integer, param376 integer, param377 integer, param378 integer, param379 integer, param380 integer, param381 integer, param382 integer, param383 integer, param384 integer, param385 integer, param386 integer, param387 integer, param388 integer, param389 integer, param390 integer, param391 integer, param392 integer, param393 integer, param394 integer, param395 integer, param396 integer, param397 integer, param398 integer, param399 integer, param400 integer, param401 integer, param402 integer, param403 integer, param404 integer, param405 integer, param406 integer, param407 integer, param408 integer, param409 integer, param410 integer, param411 integer, param412 integer, param413 integer, param414 integer, param415 integer, param416 integer, param417 integer, param418 integer, param419 integer, param420 integer, param421 integer, param422 integer, param423 integer, param424 integer, param425 integer, param426 integer, param427 integer, param428 integer, param429 integer, param430 integer, param431 integer, param432 integer, param433 integer, param434 integer, param435 integer, param436 integer, param437 integer, param438 integer, param439 integer, param440 integer, param441 integer, param442 integer, param443 integer, param444 integer, param445 integer, param446 integer, param447 integer, param448 integer, param449 integer, param450 integer, param451 integer, param452 integer, param453 integer, param454 integer, param455 integer, param456 integer, param457 integer, param458 integer, param459 integer, param460 integer, param461 integer, param462 integer, param463 integer, param464 integer, param465 integer, param466 integer, param467 integer, param468 integer, param469 integer, param470 integer, param471 integer, param472 integer, param473 integer, param474 integer, param475 integer, param476 integer, param477 integer, param478 integer, param479 integer, param480 integer, param481 integer, param482 integer, param483 integer, param484 integer, param485 integer, param486 integer, param487 integer, param488 integer, param489 integer, param490 integer, param491 integer, param492 integer, param493 integer, param494 integer, param495 integer, param496 integer, param497 integer, param498 integer, param499 integer, param500 integer, param501 integer, param502 integer, param503 integer, param504 integer, param505 integer, param506 integer, param507 integer, param508 integer, param509 integer, param510 integer, param511 integer, param512 integer, param513 integer, param514 integer, param515 integer, param516 integer, param517 integer, param518 integer, param519 integer, param520 integer, param521 integer, param522 integer, param523 integer, param524 integer, param525 integer, param526 integer, param527 integer, param528 integer, param529 integer, param530 integer, param531 integer, param532 integer, param533 integer, param534 integer, param535 integer, param536 integer, param537 integer, param538 integer, param539 integer, param540 integer, param541 integer, param542 integer, param543 integer, param544 integer, param545 integer, param546 integer, param547 integer, param548 integer, param549 integer, param550 integer, param551 integer, param552 integer, param553 integer, param554 integer, param555 integer, param556 integer, param557 integer, param558 integer, param559 integer, param560 integer, param561 integer, param562 integer, param563 integer, param564 integer, param565 integer, param566 integer, param567 integer, param568 integer, param569 integer, param570 integer, param571 integer, param572 integer, param573 integer, param574 integer, param575 integer, param576 integer, param577 integer, param578 integer, param579 integer, param580 integer, param581 integer, param582 integer, param583 integer, param584 integer, param585 integer, param586 integer, param587 integer, param588 integer, param589 integer, param590 integer, param591 integer, param592 integer, param593 integer, param594 integer, param595 integer, param596 integer, param597 integer, param598 integer, param599 integer, param600 integer, param601 integer, param602 integer, param603 integer, param604 integer, param605 integer, param606 integer, param607 integer, param608 integer, param609 integer, param610 integer, param611 integer, param612 integer, param613 integer, param614 integer, param615 integer, param616 integer, param617 integer, param618 integer, param619 integer, param620 integer, param621 integer, param622 integer, param623 integer, param624 integer, param625 integer, param626 integer, param627 integer, param628 integer, param629 integer, param630 integer, param631 integer, param632 integer, param633 integer, param634 integer, param635 integer, param636 integer, param637 integer, param638 integer, param639 integer, param640 integer, param641 integer, param642 integer, param643 integer, param644 integer, param645 integer, param646 integer, param647 integer, param648 integer, param649 integer, param650 integer, param651 integer, param652 integer, param653 integer, param654 integer, param655 integer, param656 integer, param657 integer, param658 integer, param659 integer, param660 integer, param661 integer, param662 integer, param663 integer, param664 integer, param665 integer, param666 integer, param667 integer, param668 integer, param669 integer, param670 integer, param671 integer, param672 integer, param673 integer, param674 integer, param675 integer, param676 integer, param677 integer, param678 integer, param679 integer, param680 integer, param681 integer, param682 integer, param683 integer, param684 integer, param685 integer, param686 integer, param687 integer, param688 integer, param689 integer, param690 integer, param691 integer, param692 integer, param693 integer, param694 integer, param695 integer, param696 integer, param697 integer, param698 integer, param699 integer, param700 integer, param701 integer, param702 integer, param703 integer, param704 integer, param705 integer, param706 integer, param707 integer, param708 integer, param709 integer, param710 integer, param711 integer, param712 integer, param713 integer, param714 integer, param715 integer, param716 integer, param717 integer, param718 integer, param719 integer, param720 integer, param721 integer, param722 integer, param723 integer, param724 integer, param725 integer, param726 integer, param727 integer, param728 integer, param729 integer, param730 integer, param731 integer, param732 integer, param733 integer, param734 integer, param735 integer, param736 integer, param737 integer, param738 integer, param739 integer, param740 integer, param741 integer, param742 integer, param743 integer, param744 integer, param745 integer, param746 integer, param747 integer, param748 integer, param749 integer, param750 integer, param751 integer, param752 integer, param753 integer, param754 integer, param755 integer, param756 integer, param757 integer, param758 integer, param759 integer, param760 integer, param761 integer, param762 integer, param763 integer, param764 integer, param765 integer, param766 integer, param767 integer, param768 integer, param769 integer, param770 integer, param771 integer, param772 integer, param773 integer, param774 integer, param775 integer, param776 integer, param777 integer, param778 integer, param779 integer, param780 integer, param781 integer, param782 integer, param783 integer, param784 integer, param785 integer, param786 integer, param787 integer, param788 integer, param789 integer, param790 integer, param791 integer, param792 integer, param793 integer, param794 integer, param795 integer, param796 integer, param797 integer, param798 integer, param799 integer, param800 integer, param801 integer, param802 integer, param803 integer, param804 integer, param805 integer, param806 integer, param807 integer, param808 integer, param809 integer, param810 integer, param811 integer, param812 integer, param813 integer, param814 integer, param815 integer, param816 integer, param817 integer, param818 integer, param819 integer, param820 integer, param821 integer, param822 integer, param823 integer, param824 integer, param825 integer, param826 integer, param827 integer, param828 integer, param829 integer, param830 integer, param831 integer, param832 integer, param833 integer, param834 integer, param835 integer, param836 integer, param837 integer, param838 integer, param839 integer, param840 integer, param841 integer, param842 integer, param843 integer, param844 integer, param845 integer, param846 integer, param847 integer, param848 integer, param849 integer, param850 integer, param851 integer, param852 integer, param853 integer, param854 integer, param855 integer, param856 integer, param857 integer, param858 integer, param859 integer, param860 integer, param861 integer, param862 integer, param863 integer, param864 integer, param865 integer, param866 integer, param867 integer, param868 integer, param869 integer, param870 integer, param871 integer, param872 integer, param873 integer, param874 integer, param875 integer, param876 integer, param877 integer, param878 integer, param879 integer, param880 integer, param881 integer, param882 integer, param883 integer, param884 integer, param885 integer, param886 integer, param887 integer, param888 integer, param889 integer, param890 integer, param891 integer, param892 integer, param893 integer, param894 integer, param895 integer, param896 integer, param897 integer, param898 integer, param899 integer, param900 integer, param901 integer, param902 integer, param903 integer, param904 integer, param905 integer, param906 integer, param907 integer, param908 integer, param909 integer, param910 integer, param911 integer, param912 integer, param913 integer, param914 integer, param915 integer, param916 integer, param917 integer, param918 integer, param919 integer, param920 integer, param921 integer, param922 integer, param923 integer, param924 integer, param925 integer, param926 integer, param927 integer, param928 integer, param929 integer, param930 integer, param931 integer, param932 integer, param933 integer, param934 integer, param935 integer, param936 integer, param937 integer, param938 integer, param939 integer, param940 integer, param941 integer, param942 integer, param943 integer, param944 integer, param945 integer, param946 integer, param947 integer, param948 integer, param949 integer, param950 integer, param951 integer, param952 integer, param953 integer, param954 integer, param955 integer, param956 integer, param957 integer, param958 integer, param959 integer, param960 integer, param961 integer, param962 integer, param963 integer, param964 integer, param965 integer, param966 integer, param967 integer, param968 integer, param969 integer, param970 integer, param971 integer, param972 integer, param973 integer, param974 integer, param975 integer, param976 integer, param977 integer, param978 integer, param979 integer, param980 integer, param981 integer, param982 integer, param983 integer, param984 integer, param985 integer, param986 integer, param987 integer, param988 integer, param989 integer, param990 integer, param991 integer, param992 integer, param993 integer, param994 integer, param995 integer, param996 integer, param997 integer, param998 integer, param999 integer, param1000 integer, param1001 integer, param1002 integer, param1003 integer, param1004 integer, param1005 integer, param1006 integer, param1007 integer, param1008 integer, param1009 integer, param1010 integer, param1011 integer, param1012 integer, param1013 integer, param1014 integer, param1015 integer, param1016 integer, param1017 integer, param1018 integer, param1019 integer, param1020 integer, param1021 integer, param1022 integer, param1023 integer, param1024 integer, param1025 integer, param1026 integer, param1027 integer, param1028 integer, param1029 integer, param1030 integer, param1031 integer, param1032 integer, param1033 integer, param1034 integer, param1035 integer, param1036 integer, param1037 integer, param1038 integer, param1039 integer, param1040 integer, param1041 integer, param1042 integer, param1043 integer, param1044 integer, param1045 integer, param1046 integer, param1047 integer, param1048 integer, param1049 integer, param1050 integer, param1051 integer, param1052 integer, param1053 integer, param1054 integer, param1055 integer, param1056 integer, param1057 integer, param1058 integer, param1059 integer, param1060 integer, param1061 integer, param1062 integer, param1063 integer, param1064 integer, param1065 integer, param1066 integer, param1067 integer, param1068 integer, param1069 integer, param1070 integer, param1071 integer, param1072 integer, param1073 integer, param1074 integer, param1075 integer, param1076 integer, param1077 integer, param1078 integer, param1079 integer, param1080 integer, param1081 integer, param1082 integer, param1083 integer, param1084 integer, param1085 integer, param1086 integer, param1087 integer, param1088 integer, param1089 integer, param1090 integer, param1091 integer, param1092 integer, param1093 integer, param1094 integer, param1095 integer, param1096 integer, param1097 integer, param1098 integer, param1099 integer, param1100 integer, param1101 integer, param1102 integer, param1103 integer, param1104 integer, param1105 integer, param1106 integer, param1107 integer, param1108 integer, param1109 integer, param1110 integer, param1111 integer, param1112 integer, param1113 integer, param1114 integer, param1115 integer, param1116 integer, param1117 integer, param1118 integer, param1119 integer, param1120 integer, param1121 integer, param1122 integer, param1123 integer, param1124 integer, param1125 integer, param1126 integer, param1127 integer, param1128 integer, param1129 integer, param1130 integer, param1131 integer, param1132 integer, param1133 integer, param1134 integer, param1135 integer, param1136 integer, param1137 integer, param1138 integer, param1139 integer, param1140 integer, param1141 integer, param1142 integer, param1143 integer, param1144 integer, param1145 integer, param1146 integer, param1147 integer, param1148 integer, param1149 integer, param1150 integer, param1151 integer, param1152 integer, param1153 integer, param1154 integer, param1155 integer, param1156 integer, param1157 integer, param1158 integer, param1159 integer, param1160 integer, param1161 integer, param1162 integer, param1163 integer, param1164 integer, param1165 integer, param1166 integer, param1167 integer, param1168 integer, param1169 integer, param1170 integer, param1171 integer, param1172 integer, param1173 integer, param1174 integer, param1175 integer, param1176 integer, param1177 integer, param1178 integer, param1179 integer, param1180 integer, param1181 integer, param1182 integer, param1183 integer, param1184 integer, param1185 integer, param1186 integer, param1187 integer, param1188 integer, param1189 integer, param1190 integer, param1191 integer, param1192 integer, param1193 integer, param1194 integer, param1195 integer, param1196 integer, param1197 integer, param1198 integer, param1199 integer) for select * from rc_test where a > param1;
nonsense record;
begin
open c1($1);
fetch c1 into nonsense;
close c1;
if found then
return true;
else
return false;
end if;
end
$$ language 'plpgsql';
Index: src/pl/plpgsql/src/gram.y
===================================================================
RCS file: /var/lib/cvs/pgsql/src/pl/plpgsql/src/gram.y,v
retrieving revision 1.64
diff -c -r1.64 gram.y
*** src/pl/plpgsql/src/gram.y 25 Oct 2004 06:27:21 -0000 1.64
--- src/pl/plpgsql/src/gram.y 20 Jan 2005 04:39:01 -0000
***************
*** 474,479 ****
--- 474,483 ----
{
int i = $1->nfields++;
+ /* Guard against overflowing the array on malicious input */
+ if (i >= 1024)
+ yyerror("too many parameters specified for refcursor");
+
$1->fieldnames[i] = $3->refname;
$1->varnos[i] = $3->dno;
Home |
Main Index |
Thread Index