> 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)
signature.asc
Description: This is a digitally signed message part
