> 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