aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/heap/heapam.c14
-rw-r--r--src/backend/access/transam/xact.c30
-rw-r--r--src/backend/storage/lmgr/lmgr.c41
-rw-r--r--src/backend/storage/lmgr/lock.c9
-rw-r--r--src/include/access/xact.h5
-rw-r--r--src/include/storage/lmgr.h5
6 files changed, 49 insertions, 55 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 1889d09784c..aade7a29c13 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.222.2.1 2007/02/04 20:00:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.222.2.2 2008/03/04 19:54:23 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -699,6 +699,10 @@ relation_open(Oid relationId, LOCKMODE lockmode)
if (!RelationIsValid(r))
elog(ERROR, "could not open relation with OID %u", relationId);
+ /* Make note that we've accessed a temporary relation */
+ if (r->rd_istemp)
+ MyXactAccessedTempRel = true;
+
return r;
}
@@ -741,6 +745,10 @@ try_relation_open(Oid relationId, LOCKMODE lockmode)
if (!RelationIsValid(r))
elog(ERROR, "could not open relation with OID %u", relationId);
+ /* Make note that we've accessed a temporary relation */
+ if (r->rd_istemp)
+ MyXactAccessedTempRel = true;
+
return r;
}
@@ -785,6 +793,10 @@ relation_open_nowait(Oid relationId, LOCKMODE lockmode)
if (!RelationIsValid(r))
elog(ERROR, "could not open relation with OID %u", relationId);
+ /* Make note that we've accessed a temporary relation */
+ if (r->rd_istemp)
+ MyXactAccessedTempRel = true;
+
return r;
}
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index e000547b327..6ef1f5a7420 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.229.2.3 2008/01/03 21:23:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.229.2.4 2008/03/04 19:54:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,6 +57,13 @@ bool XactReadOnly;
int CommitDelay = 0; /* precommit delay in microseconds */
int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
+/*
+ * MyXactAccessedTempRel is set when a temporary relation is accessed.
+ * We don't allow PREPARE TRANSACTION in that case. (This is global
+ * so that it can be set from heapam.c.)
+ */
+bool MyXactAccessedTempRel = false;
+
/*
* transaction states - transaction state from server perspective
@@ -1389,6 +1396,7 @@ StartTransaction(void)
FreeXactSnapshot();
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
+ MyXactAccessedTempRel = false;
/*
* reinitialize within-transaction counters
@@ -1715,6 +1723,26 @@ PrepareTransaction(void)
/* NOTIFY and flatfiles will be handled below */
+ /*
+ * Don't allow PREPARE TRANSACTION if we've accessed a temporary table
+ * in this transaction. Having the prepared xact hold locks on another
+ * backend's temp table seems a bad idea --- for instance it would prevent
+ * the backend from exiting. There are other problems too, such as how
+ * to clean up the source backend's local buffers and ON COMMIT state
+ * if the prepared xact includes a DROP of a temp table.
+ *
+ * We must check this after executing any ON COMMIT actions, because
+ * they might still access a temp relation.
+ *
+ * XXX In principle this could be relaxed to allow some useful special
+ * cases, such as a temp table created and dropped all within the
+ * transaction. That seems to require much more bookkeeping though.
+ */
+ if (MyXactAccessedTempRel)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
+
/* Prevent cancel/die interrupt while cleaning up */
HOLD_INTERRUPTS();
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 4a4c0990ad2..25cd40cd1bd 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.89 2006/10/04 00:29:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.89.2.1 2008/03/04 19:54:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,12 +19,10 @@
#include "access/transam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
-#include "catalog/namespace.h"
#include "miscadmin.h"
#include "storage/lmgr.h"
#include "storage/procarray.h"
#include "utils/inval.h"
-#include "utils/lsyscache.h"
/*
@@ -598,40 +596,3 @@ UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
LockRelease(&tag, lockmode, false);
}
-
-
-/*
- * LockTagIsTemp
- * Determine whether a locktag is for a lock on a temporary object
- *
- * We need this because 2PC cannot deal with temp objects
- */
-bool
-LockTagIsTemp(const LOCKTAG *tag)
-{
- switch (tag->locktag_type)
- {
- case LOCKTAG_RELATION:
- case LOCKTAG_RELATION_EXTEND:
- case LOCKTAG_PAGE:
- case LOCKTAG_TUPLE:
- /* check for lock on a temp relation */
- /* field1 is dboid, field2 is reloid for all of these */
- if ((Oid) tag->locktag_field1 == InvalidOid)
- return false; /* shared, so not temp */
- if (isTempNamespace(get_rel_namespace((Oid) tag->locktag_field2)))
- return true;
- break;
- case LOCKTAG_TRANSACTION:
- /* there are no temp transactions */
- break;
- case LOCKTAG_OBJECT:
- /* there are currently no non-table temp objects */
- break;
- case LOCKTAG_USERLOCK:
- case LOCKTAG_ADVISORY:
- /* assume these aren't temp */
- break;
- }
- return false; /* default case */
-}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index a8d2ad01d9f..a49002e4d07 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.174.2.1 2008/02/02 22:26:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.174.2.2 2008/03/04 19:54:23 tgl Exp $
*
* NOTES
* A lock table is a shared memory hash table. When
@@ -37,7 +37,6 @@
#include "access/twophase_rmgr.h"
#include "miscadmin.h"
#include "pgstat.h"
-#include "storage/lmgr.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/resowner.h"
@@ -1849,12 +1848,6 @@ AtPrepare_Locks(void)
elog(ERROR, "cannot PREPARE when session locks exist");
}
- /* Can't handle it if the lock is on a temporary object */
- if (LockTagIsTemp(&locallock->tag.lock))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
-
/*
* Create a 2PC record.
*/
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 5b4411d77be..ede75c6518a 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.83 2006/07/11 18:26:11 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.83.2.1 2008/03/04 19:54:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,6 +41,9 @@ extern int XactIsoLevel;
extern bool DefaultXactReadOnly;
extern bool XactReadOnly;
+/* Kluge for 2PC support */
+extern bool MyXactAccessedTempRel;
+
/*
* start- and end-of-transaction callbacks for dynamically loaded modules
*/
diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h
index ea7a1bf948f..832f3e201bc 100644
--- a/src/include/storage/lmgr.h
+++ b/src/include/storage/lmgr.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/lmgr.h,v 1.56 2006/08/18 16:09:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/lmgr.h,v 1.56.2.1 2008/03/04 19:54:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,7 +66,4 @@ extern void LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
extern void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
LOCKMODE lockmode);
-/* Knowledge about which locktags describe temp objects */
-extern bool LockTagIsTemp(const LOCKTAG *tag);
-
#endif /* LMGR_H */