> There's a minor bug in the ON_ERROR_ROLLBACK code in psql. In 
> HEAD, at line 878 the storage pointed to by "results" is 
> released by a PQclear(), but is referenced by the 
> PQcmdStatus() calls on lines 898, 899, and 900.
>
> I'm busy at the moment -- if someone wants to fix this 
> (backport to 8.1 please!), have at it.

Attached is a quick patch for HEAD and 8.1, which should do the job.
Thanks for finding this.

--
Greg Sabino Mullane [EMAIL PROTECTED]
PGP Key: 0x14964AC8 200606301039
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8

Index: common.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/common.c,v
retrieving revision 1.119
diff -u -u -r1.119 common.c
--- common.c	14 Jun 2006 16:49:02 -0000	1.119
+++ common.c	30 Jun 2006 13:33:31 -0000
@@ -875,8 +875,6 @@
 	if (OK)
 		OK = PrintQueryResults(results);
 
-	PQclear(results);
-
 	/* If we made a temporary savepoint, possibly release/rollback */
 	if (on_error_rollback_savepoint)
 	{
@@ -884,23 +882,35 @@
 
 		/* We always rollback on an error */
 		if (transaction_status == PQTRANS_INERROR)
+		{
+			PQclear(results);
 			results = PQexec(pset.db, "ROLLBACK TO pg_psql_temporary_savepoint");
+		}
 		/* If they are no longer in a transaction, then do nothing */
 		else if (transaction_status != PQTRANS_INTRANS)
+		{
+			PQclear(results);
 			results = NULL;
+		}
 		else
 		{
 			/*
-			 * Do nothing if they are messing with savepoints themselves: If
+			 * Do nothing if they are messing with savepoints themselves: if
 			 * the user did RELEASE or ROLLBACK, our savepoint is gone. If
 			 * they issued a SAVEPOINT, releasing ours would remove theirs.
 			 */
 			if (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
 				strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
 				strcmp(PQcmdStatus(results), "ROLLBACK") == 0)
+			{
+				PQclear(results);
 				results = NULL;
+			}
 			else
+			{
+				PQclear(results);
 				results = PQexec(pset.db, "RELEASE pg_psql_temporary_savepoint");
+			}
 		}
 		if (PQresultStatus(results) != PGRES_COMMAND_OK)
 		{
@@ -909,8 +919,8 @@
 			ResetCancelConn();
 			return false;
 		}
-		PQclear(results);
 	}
+	PQclear(results);
 
 	/* Possible microtiming output */
 	if (OK && pset.timing)
Index: common.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/common.c,v
retrieving revision 1.110.2.1
diff -u -u -r1.110.2.1 common.c
--- common.c	22 Nov 2005 18:23:27 -0000	1.110.2.1
+++ common.c	30 Jun 2006 13:42:29 -0000
@@ -1067,8 +1067,6 @@
 	if (OK)
 		OK = PrintQueryResults(results);
 
-	PQclear(results);
-
 	/* If we made a temporary savepoint, possibly release/rollback */
 	if (on_error_rollback_savepoint)
 	{
@@ -1076,23 +1074,35 @@
 
 		/* We always rollback on an error */
 		if (transaction_status == PQTRANS_INERROR)
+		{
+			PQclear(results);
 			results = PQexec(pset.db, "ROLLBACK TO pg_psql_temporary_savepoint");
+		}
 		/* If they are no longer in a transaction, then do nothing */
 		else if (transaction_status != PQTRANS_INTRANS)
+		{
+			PQclear(results);
 			results = NULL;
+		}
 		else
 		{
 			/*
-			 * Do nothing if they are messing with savepoints themselves: If
+			 * Do nothing if they are messing with savepoints themselves: if
 			 * the user did RELEASE or ROLLBACK, our savepoint is gone. If
 			 * they issued a SAVEPOINT, releasing ours would remove theirs.
 			 */
 			if (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
 				strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
 				strcmp(PQcmdStatus(results), "ROLLBACK") == 0)
+			{
+				PQclear(results);
 				results = NULL;
+			}
 			else
+			{
+				PQclear(results);
 				results = PQexec(pset.db, "RELEASE pg_psql_temporary_savepoint");
+			}
 		}
 		if (PQresultStatus(results) != PGRES_COMMAND_OK)
 		{
@@ -1101,8 +1111,8 @@
 			ResetCancelConn();
 			return false;
 		}
-		PQclear(results);
 	}
+	PQclear(results);
 
 	/* Possible microtiming output */
 	if (OK && pset.timing)

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to