Heikki Linnakangas wrote:
Attached is a simple patch to fix that by disallowing
CREATE+DROP+PREPARE TRANSACTION more reliably.
That patch was missing changes to header files. New patch attached.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
Index: src/backend/access/transam/twophase.c
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/transam/twophase.c,v
retrieving revision 1.39
diff -c -r1.39 twophase.c
*** src/backend/access/transam/twophase.c 1 Jan 2008 19:45:48 -0000 1.39
--- src/backend/access/transam/twophase.c 29 Feb 2008 13:05:24 -0000
***************
*** 793,798 ****
--- 793,799 ----
TransactionId *children;
RelFileNode *commitrels;
RelFileNode *abortrels;
+ bool haveTempCommit, haveTempAbort;
/* Initialize linked list */
records.head = palloc0(sizeof(XLogRecData));
***************
*** 815,824 ****
hdr.prepared_at = gxact->prepared_at;
hdr.owner = gxact->owner;
hdr.nsubxacts = xactGetCommittedChildren(&children);
! hdr.ncommitrels = smgrGetPendingDeletes(true, &commitrels, NULL);
! hdr.nabortrels = smgrGetPendingDeletes(false, &abortrels, NULL);
StrNCpy(hdr.gid, gxact->gid, GIDSIZE);
save_state_data(&hdr, sizeof(TwoPhaseFileHeader));
/* Add the additional info about subxacts and deletable files */
--- 816,830 ----
hdr.prepared_at = gxact->prepared_at;
hdr.owner = gxact->owner;
hdr.nsubxacts = xactGetCommittedChildren(&children);
! hdr.ncommitrels = smgrGetPendingDeletes(true, &commitrels, NULL, &haveTempCommit);
! hdr.nabortrels = smgrGetPendingDeletes(false, &abortrels, NULL, &haveTempAbort);
StrNCpy(hdr.gid, gxact->gid, GIDSIZE);
+ if (haveTempCommit || haveTempAbort)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
+
save_state_data(&hdr, sizeof(TwoPhaseFileHeader));
/* Add the additional info about subxacts and deletable files */
Index: src/backend/access/transam/xact.c
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.257
diff -c -r1.257 xact.c
*** src/backend/access/transam/xact.c 15 Jan 2008 18:56:59 -0000 1.257
--- src/backend/access/transam/xact.c 29 Feb 2008 13:05:24 -0000
***************
*** 802,808 ****
TransactionId *children;
/* Get data needed for commit record */
! nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
nchildren = xactGetCommittedChildren(&children);
/*
--- 802,808 ----
TransactionId *children;
/* Get data needed for commit record */
! nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp, NULL);
nchildren = xactGetCommittedChildren(&children);
/*
***************
*** 1174,1180 ****
xid);
/* Fetch the data we need for the abort record */
! nrels = smgrGetPendingDeletes(false, &rels, NULL);
nchildren = xactGetCommittedChildren(&children);
/* XXX do we really need a critical section here? */
--- 1174,1180 ----
xid);
/* Fetch the data we need for the abort record */
! nrels = smgrGetPendingDeletes(false, &rels, NULL, NULL);
nchildren = xactGetCommittedChildren(&children);
/* XXX do we really need a critical section here? */
Index: src/backend/storage/smgr/smgr.c
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/backend/storage/smgr/smgr.c,v
retrieving revision 1.109
diff -c -r1.109 smgr.c
*** src/backend/storage/smgr/smgr.c 1 Jan 2008 19:45:52 -0000 1.109
--- src/backend/storage/smgr/smgr.c 29 Feb 2008 13:05:24 -0000
***************
*** 678,689 ****
*
* If haveNonTemp isn't NULL, the bool it points to gets set to true if
* there is any non-temp table pending to be deleted; false if not.
*
* Note that the list does not include anything scheduled for termination
* by upper-level transactions.
*/
int
! smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr, bool *haveNonTemp)
{
int nestLevel = GetCurrentTransactionNestLevel();
int nrels;
--- 678,692 ----
*
* If haveNonTemp isn't NULL, the bool it points to gets set to true if
* there is any non-temp table pending to be deleted; false if not.
+ * haveTemp is similar, but gets set if there is any temp table deletions
+ * pending.
*
* Note that the list does not include anything scheduled for termination
* by upper-level transactions.
*/
int
! smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr,
! bool *haveNonTemp, bool *haveTemp)
{
int nestLevel = GetCurrentTransactionNestLevel();
int nrels;
***************
*** 693,698 ****
--- 696,703 ----
nrels = 0;
if (haveNonTemp)
*haveNonTemp = false;
+ if (haveTemp)
+ *haveTemp = false;
for (pending = pendingDeletes; pending != NULL; pending = pending->next)
{
if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit)
***************
*** 711,716 ****
--- 716,723 ----
*rptr++ = pending->relnode;
if (haveNonTemp && !pending->isTemp)
*haveNonTemp = true;
+ if (haveTemp && pending->isTemp)
+ *haveTemp = true;
}
return nrels;
}
Index: src/include/storage/smgr.h
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/storage/smgr.h,v
retrieving revision 1.62
diff -c -r1.62 smgr.h
*** src/include/storage/smgr.h 1 Jan 2008 19:45:59 -0000 1.62
--- src/include/storage/smgr.h 29 Feb 2008 09:47:24 -0000
***************
*** 77,83 ****
extern void smgrimmedsync(SMgrRelation reln);
extern void smgrDoPendingDeletes(bool isCommit);
extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr,
! bool *haveNonTemp);
extern void AtSubCommit_smgr(void);
extern void AtSubAbort_smgr(void);
extern void PostPrepare_smgr(void);
--- 77,83 ----
extern void smgrimmedsync(SMgrRelation reln);
extern void smgrDoPendingDeletes(bool isCommit);
extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr,
! bool *haveNonTemp, bool *haveTemp);
extern void AtSubCommit_smgr(void);
extern void AtSubAbort_smgr(void);
extern void PostPrepare_smgr(void);
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq