summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorTom Lane2004-07-28 14:23:31 +0000
committerTom Lane2004-07-28 14:23:31 +0000
commit1bf3d615047eb214b1ddde31bd268dabf96cc3fa (patch)
tree0fdb8cc0a4203c338b6f73130c9ef74b64d4a74e /src/backend/utils
parentcc813fc2b8d9293bbd4d0e0d6a6f3b9cf02fe32f (diff)
Fix subtransaction behavior for large objects, temp namespace, files,
password/group files. Also allow read-only subtransactions of a read-write parent, but not vice versa. These are the reasonably noncontroversial parts of Alvaro's recent mop-up patch, plus further work on large objects to minimize use of the TopTransactionResourceOwner.
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/cache/inval.c6
-rw-r--r--src/backend/utils/misc/guc.c15
-rw-r--r--src/backend/utils/time/tqual.c65
3 files changed, 67 insertions, 19 deletions
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index e54a74fae4b..946bd0c9eb7 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.63 2004/07/01 00:51:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.64 2004/07/28 14:23:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -678,7 +678,7 @@ AtEOXact_Inval(bool isCommit)
}
/*
- * AtSubEOXact_Inval
+ * AtEOSubXact_Inval
* Process queued-up invalidation messages at end of subtransaction.
*
* If isCommit, process CurrentCmdInvalidMsgs if any (there probably aren't),
@@ -695,7 +695,7 @@ AtEOXact_Inval(bool isCommit)
* (if aborting).
*/
void
-AtSubEOXact_Inval(bool isCommit)
+AtEOSubXact_Inval(bool isCommit)
{
TransInvalidationInfo *myInfo = transInvalInfo;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index b9865462a4e..22df3effc32 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <[email protected]>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.224 2004/07/24 19:51:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.225 2004/07/28 14:23:29 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -5436,10 +5436,15 @@ assign_log_stats(bool newval, bool doit, GucSource source)
static bool
assign_transaction_read_only(bool newval, bool doit, GucSource source)
{
- if (doit && source >= PGC_S_INTERACTIVE && IsSubTransaction())
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot set transaction read only mode inside a subtransaction")));
+ /* Can't go to r/w mode inside a r/o transaction */
+ if (newval == false && XactReadOnly && IsSubTransaction())
+ {
+ if (source >= PGC_S_INTERACTIVE)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot set transaction read-write mode inside a read-only transaction")));
+ return false;
+ }
return true;
}
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 446ee4b72c5..d1a7179484e 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -16,7 +16,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.73 2004/07/01 00:51:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.74 2004/07/28 14:23:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -118,7 +118,10 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
/* deleting subtransaction aborted */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
+ {
+ tuple->t_infomask |= HEAP_XMAX_INVALID;
return true;
+ }
Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));
@@ -268,7 +271,10 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
/* deleting subtransaction aborted */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
+ {
+ tuple->t_infomask |= HEAP_XMAX_INVALID;
return true;
+ }
Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));
@@ -452,7 +458,10 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid)
/* deleting subtransaction aborted */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
+ {
+ tuple->t_infomask |= HEAP_XMAX_INVALID;
return HeapTupleMayBeUpdated;
+ }
Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));
@@ -590,7 +599,10 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
/* deleting subtransaction aborted */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
+ {
+ tuple->t_infomask |= HEAP_XMAX_INVALID;
return true;
+ }
Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));
@@ -732,7 +744,10 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
/* deleting subtransaction aborted */
/* FIXME -- is this correct w.r.t. the cmax of the tuple? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
+ {
+ tuple->t_infomask |= HEAP_XMAX_INVALID;
return true;
+ }
Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));
@@ -757,21 +772,36 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
/*
* By here, the inserting transaction has committed - have to check
* when...
+ *
+ * Note that the provided snapshot contains only top-level XIDs, so
+ * we have to convert a subxact XID to its parent for comparison.
+ * However, we can make first-pass range checks with the given XID,
+ * because a subxact with XID < xmin has surely also got a parent with
+ * XID < xmin, while one with XID >= xmax must belong to a parent that
+ * was not yet committed at the time of this snapshot.
*/
if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple),
snapshot->xmin))
{
- uint32 i;
+ TransactionId parentXid;
if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple),
snapshot->xmax))
return false;
- for (i = 0; i < snapshot->xcnt; i++)
+ parentXid = SubTransGetTopmostTransaction(HeapTupleHeaderGetXmin(tuple));
+
+ if (TransactionIdFollowsOrEquals(parentXid, snapshot->xmin))
{
- if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple),
- snapshot->xip[i]))
- return false;
+ uint32 i;
+
+ /* no point in checking parentXid against xmax here */
+
+ for (i = 0; i < snapshot->xcnt; i++)
+ {
+ if (TransactionIdEquals(parentXid, snapshot->xip[i]))
+ return false;
+ }
}
}
@@ -804,18 +834,31 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
/*
* OK, the deleting transaction committed too ... but when?
+ *
+ * See notes for the similar tests on tuple xmin, above.
*/
- if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple), snapshot->xmin))
+ if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple),
+ snapshot->xmin))
{
- uint32 i;
+ TransactionId parentXid;
if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmax(tuple),
snapshot->xmax))
return true;
- for (i = 0; i < snapshot->xcnt; i++)
+
+ parentXid = SubTransGetTopmostTransaction(HeapTupleHeaderGetXmax(tuple));
+
+ if (TransactionIdFollowsOrEquals(parentXid, snapshot->xmin))
{
- if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmax(tuple), snapshot->xip[i]))
- return true;
+ uint32 i;
+
+ /* no point in checking parentXid against xmax here */
+
+ for (i = 0; i < snapshot->xcnt; i++)
+ {
+ if (TransactionIdEquals(parentXid, snapshot->xip[i]))
+ return true;
+ }
}
}