Repair memory leak introduced by recent change to make SPI return a

tupdesc even with zero tuples returned: some plpgsql routines assumed
they didn't need to do SPI_freetuptable() after retrieving no tuples.
This commit is contained in:
Tom Lane 2003-03-02 20:45:47 +00:00
parent 191ef2b407
commit a1dbe521bc
1 changed files with 31 additions and 31 deletions

View File

@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.79 2003/02/16 02:30:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.80 2003/03/02 20:45:47 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -1388,11 +1388,12 @@ exec_stmt_fors(PLpgSQL_execstate * estate, PLpgSQL_stmt_fors * stmt)
if (rc != PLPGSQL_RC_OK)
{
/*
* We're aborting the loop, so cleanup and set FOUND
* We're aborting the loop, so cleanup and set FOUND.
* (This code should match the code after the loop.)
*/
exec_set_found(estate, found);
SPI_freetuptable(tuptab);
SPI_cursor_close(portal);
exec_set_found(estate, found);
if (rc == PLPGSQL_RC_EXIT)
{
@ -1429,6 +1430,11 @@ exec_stmt_fors(PLpgSQL_execstate * estate, PLpgSQL_stmt_fors * stmt)
tuptab = SPI_tuptable;
}
/*
* Release last group of tuples
*/
SPI_freetuptable(tuptab);
/*
* Close the implicit cursor
*/
@ -2381,7 +2387,7 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
if (n == 0)
exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
else
found = true;
found = true; /* processed at least one tuple */
/*
* Now do the loop
@ -2400,14 +2406,15 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
*/
rc = exec_stmts(estate, stmt->body);
/*
* We're aborting the loop, so cleanup and set FOUND
*/
if (rc != PLPGSQL_RC_OK)
{
exec_set_found(estate, found);
/*
* We're aborting the loop, so cleanup and set FOUND.
* (This code should match the code after the loop.)
*/
SPI_freetuptable(tuptab);
SPI_cursor_close(portal);
exec_set_found(estate, found);
if (rc == PLPGSQL_RC_EXIT)
{
@ -2445,7 +2452,12 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
}
/*
* Close the cursor
* Release last group of tuples
*/
SPI_freetuptable(tuptab);
/*
* Close the implicit cursor
*/
SPI_cursor_close(portal);
@ -2753,25 +2765,16 @@ exec_stmt_fetch(PLpgSQL_execstate * estate, PLpgSQL_stmt_fetch * stmt)
elog(ERROR, "cursor \"%s\" is invalid", curname);
pfree(curname);
/* ----------
* Initialize the global found variable to false
* ----------
*/
exec_set_found(estate, false);
/* ----------
* Determine if we fetch into a record or a row
* ----------
*/
if (stmt->rec != NULL)
rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
else if (stmt->row != NULL)
row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
else
{
if (stmt->row != NULL)
row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
else
elog(ERROR, "unsupported target in exec_stmt_select()");
}
elog(ERROR, "unsupported target in exec_stmt_fetch()");
/* ----------
* Fetch 1 tuple from the cursor
@ -2782,22 +2785,19 @@ exec_stmt_fetch(PLpgSQL_execstate * estate, PLpgSQL_stmt_fetch * stmt)
n = SPI_processed;
/* ----------
* If the FETCH didn't return a row, set the target
* to NULL and return with FOUND = false.
* Set the target and the global FOUND variable appropriately.
* ----------
*/
if (n == 0)
{
exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
return PLPGSQL_RC_OK;
exec_set_found(estate, false);
}
else
{
exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
exec_set_found(estate, true);
}
/* ----------
* Put the result into the target and set found to true
* ----------
*/
exec_move_row(estate, rec, row, tuptab->vals[0], tuptab->tupdesc);
exec_set_found(estate, true);
SPI_freetuptable(tuptab);