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