From fccf99f0c81ac2ad9af6e6fa746375c39ca7ab0b Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 26 Dec 2006 16:56:18 +0000
Subject: [PATCH] Repair bug #2836: SPI_execute_plan returned zero if none of
 the querytrees were marked canSetTag.  While it's certainly correct to return
 the result of the last one that is marked canSetTag, it's less clear what to
 do when none of them are.  Since plpgsql will complain if zero is returned,
 the 8.2.0 behavior isn't good.  I've fixed it to restore the prior behavior
 of returning the physically last query's result code when there are no
 canSetTag queries.

---
 src/backend/executor/spi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 90336e4be25..394e9454277 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.166 2006/12/08 00:40:27 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.167 2006/12/26 16:56:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1341,6 +1341,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
 	volatile uint32 my_processed = 0;
 	volatile Oid my_lastoid = InvalidOid;
 	SPITupleTable *volatile my_tuptable = NULL;
+	volatile int res = 0;
 	Snapshot	saveActiveSnapshot;
 
 	/* Be sure to restore ActiveSnapshot on error exit */
@@ -1396,7 +1397,6 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
 				Plan	   *planTree;
 				QueryDesc  *qdesc;
 				DestReceiver *dest;
-				int			res;
 
 				planTree = lfirst(plan_list_item);
 				plan_list_item = lnext(plan_list_item);
@@ -1546,6 +1546,13 @@ fail:
 	/* tuptable now is caller's responsibility, not SPI's */
 	_SPI_current->tuptable = NULL;
 
+	/*
+	 * If none of the queries had canSetTag, we return the last query's result
+	 * code, but not its auxiliary results (for backwards compatibility).
+	 */
+	if (my_res == 0)
+		my_res = res;
+
 	return my_res;
 }
 
-- 
GitLab