Commit 29fa0513 authored by Tom Lane's avatar Tom Lane

When executing a list of queries derived from rule expansion,

_SPI_execute_plan's return code should reflect the type of the query
that is marked canSetTag, not necessarily the last one in the list.

This is arguably a bug fix, but I'm hesitant to back-patch it because
it's the sort of subtle change that might break someone's code, and it's
best not to do that kind of thing in point releases.
parent c859294c
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.155 2006/08/12 20:05:55 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.156 2006/08/14 13:40:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1306,7 +1306,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1306,7 +1306,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
Snapshot snapshot, Snapshot crosscheck_snapshot, Snapshot snapshot, Snapshot crosscheck_snapshot,
bool read_only, long tcount) bool read_only, long tcount)
{ {
volatile int res = 0; volatile int my_res = 0;
volatile uint32 my_processed = 0; volatile uint32 my_processed = 0;
volatile Oid my_lastoid = InvalidOid; volatile Oid my_lastoid = InvalidOid;
SPITupleTable *volatile my_tuptable = NULL; SPITupleTable *volatile my_tuptable = NULL;
...@@ -1364,6 +1364,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1364,6 +1364,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
Plan *planTree; Plan *planTree;
QueryDesc *qdesc; QueryDesc *qdesc;
DestReceiver *dest; DestReceiver *dest;
int res;
planTree = lfirst(plan_list_item); planTree = lfirst(plan_list_item);
plan_list_item = lnext(plan_list_item); plan_list_item = lnext(plan_list_item);
...@@ -1380,7 +1381,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1380,7 +1381,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
if (stmt->filename == NULL) if (stmt->filename == NULL)
{ {
res = SPI_ERROR_COPY; my_res = SPI_ERROR_COPY;
goto fail; goto fail;
} }
} }
...@@ -1388,12 +1389,12 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1388,12 +1389,12 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
IsA(queryTree->utilityStmt, ClosePortalStmt) || IsA(queryTree->utilityStmt, ClosePortalStmt) ||
IsA(queryTree->utilityStmt, FetchStmt)) IsA(queryTree->utilityStmt, FetchStmt))
{ {
res = SPI_ERROR_CURSOR; my_res = SPI_ERROR_CURSOR;
goto fail; goto fail;
} }
else if (IsA(queryTree->utilityStmt, TransactionStmt)) else if (IsA(queryTree->utilityStmt, TransactionStmt))
{ {
res = SPI_ERROR_TRANSACTION; my_res = SPI_ERROR_TRANSACTION;
goto fail; goto fail;
} }
} }
...@@ -1459,7 +1460,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1459,7 +1460,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
ActiveSnapshot = NULL; ActiveSnapshot = NULL;
/* /*
* The last canSetTag query sets the auxiliary values returned * The last canSetTag query sets the status values returned
* to the caller. Be careful to free any tuptables not * to the caller. Be careful to free any tuptables not
* returned, to avoid intratransaction memory leak. * returned, to avoid intratransaction memory leak.
*/ */
...@@ -1469,6 +1470,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1469,6 +1470,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
my_lastoid = _SPI_current->lastoid; my_lastoid = _SPI_current->lastoid;
SPI_freetuptable(my_tuptable); SPI_freetuptable(my_tuptable);
my_tuptable = _SPI_current->tuptable; my_tuptable = _SPI_current->tuptable;
my_res = res;
} }
else else
{ {
...@@ -1477,7 +1479,10 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls, ...@@ -1477,7 +1479,10 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
} }
/* we know that the receiver doesn't need a destroy call */ /* we know that the receiver doesn't need a destroy call */
if (res < 0) if (res < 0)
{
my_res = res;
goto fail; goto fail;
}
} }
} }
...@@ -1503,7 +1508,7 @@ fail: ...@@ -1503,7 +1508,7 @@ fail:
SPI_lastoid = my_lastoid; SPI_lastoid = my_lastoid;
SPI_tuptable = my_tuptable; SPI_tuptable = my_tuptable;
return res; return my_res;
} }
static int static int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment