* PredicateLockTuple(Relation relation, HeapTuple tuple,
* Snapshot snapshot)
* PredicateLockPageSplit(Relation relation, BlockNumber oldblkno,
- * BlockNumber newblkno);
+ * BlockNumber newblkno)
* PredicateLockPageCombine(Relation relation, BlockNumber oldblkno,
- * BlockNumber newblkno);
+ * BlockNumber newblkno)
* TransferPredicateLocksToHeapRelation(Relation relation)
* ReleasePredicateLocks(bool isCommit)
*
* this entry, you can ensure that there's enough scratch space available for
* inserting one entry in the hash table. This is an otherwise-invalid tag.
*/
-static const PREDICATELOCKTARGETTAG ScratchTargetTag = {0, 0, 0, 0, 0};
+static const PREDICATELOCKTARGETTAG ScratchTargetTag = {0, 0, 0, 0};
static uint32 ScratchTargetTagHash;
static int ScratchPartitionLock;
}
}
}
- else
- targetxmin = InvalidTransactionId;
/*
* Do quick-but-not-definitive test for a relation lock first. This will
relation->rd_node.dbNode,
relation->rd_id,
ItemPointerGetBlockNumber(tid),
- ItemPointerGetOffsetNumber(tid),
- targetxmin);
+ ItemPointerGetOffsetNumber(tid));
PredicateLockAcquire(&tag);
}
relation->rd_node.dbNode,
relation->rd_id,
ItemPointerGetBlockNumber(&(tuple->t_data->t_ctid)),
- ItemPointerGetOffsetNumber(&(tuple->t_data->t_ctid)),
- HeapTupleHeaderGetXmin(tuple->t_data));
+ ItemPointerGetOffsetNumber(&(tuple->t_data->t_ctid)));
CheckTargetForConflictsIn(&targettag);
}
* be the target of predicate locks.
*
* Note that the hash function being used doesn't properly respect tag
- * length -- it will go to a four byte boundary past the end of the tag.
- * If you change this struct, make sure any slack space is initialized,
- * so that any random bytes in the middle or at the end are not included
- * in the hash.
+ * length -- if the length of the structure isn't a multiple of four bytes it
+ * will go to a four byte boundary past the end of the tag. If you change
+ * this struct, make sure any slack space is initialized, so that any random
+ * bytes in the middle or at the end are not included in the hash.
*
* TODO SSI: If we always use the same fields for the same type of value, we
* should rename these. Holding off until it's clear there are no exceptions.
uint32 locktag_field2; /* a 32-bit ID field */
uint32 locktag_field3; /* a 32-bit ID field */
uint32 locktag_field4; /* a 32-bit ID field */
- uint32 locktag_field5; /* a 32-bit ID field */
} PREDICATELOCKTARGETTAG;
/*
* added when a predicate lock is requested on an object which doesn't
* already have one. An entry is removed when the last lock is removed from
* its list.
- *
- * Because a particular target might become obsolete, due to update to a new
- * version, before the reading transaction is obsolete, we need some way to
- * prevent errors from reuse of a tuple ID. Rather than attempting to clean
- * up the targets as the related tuples are pruned or vacuumed, we check the
- * xmin on access. This should be far less costly.
*/
typedef struct PREDICATELOCKTARGET
{
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = InvalidBlockNumber, \
- (locktag).locktag_field4 = InvalidOffsetNumber, \
- (locktag).locktag_field5 = InvalidTransactionId)
+ (locktag).locktag_field4 = InvalidOffsetNumber)
#define SET_PREDICATELOCKTARGETTAG_PAGE(locktag,dboid,reloid,blocknum) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = (blocknum), \
- (locktag).locktag_field4 = InvalidOffsetNumber, \
- (locktag).locktag_field5 = InvalidTransactionId)
+ (locktag).locktag_field4 = InvalidOffsetNumber)
-#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum,xmin) \
+#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = (blocknum), \
- (locktag).locktag_field4 = (offnum), \
- (locktag).locktag_field5 = (xmin))
+ (locktag).locktag_field4 = (offnum))
#define GET_PREDICATELOCKTARGETTAG_DB(locktag) \
((Oid) (locktag).locktag_field1)
((BlockNumber) (locktag).locktag_field3)
#define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag) \
((OffsetNumber) (locktag).locktag_field4)
-#define GET_PREDICATELOCKTARGETTAG_XMIN(locktag) \
- ((TransactionId) (locktag).locktag_field5)
#define GET_PREDICATELOCKTARGETTAG_TYPE(locktag) \
(((locktag).locktag_field4 != InvalidOffsetNumber) ? PREDLOCKTAG_TUPLE : \
(((locktag).locktag_field3 != InvalidBlockNumber) ? PREDLOCKTAG_PAGE : \
typedef struct TwoPhasePredicateLockRecord
{
PREDICATELOCKTARGETTAG target;
+ uint32 filler; /* to avoid length change in back-patched fix */
} TwoPhasePredicateLockRecord;
typedef struct TwoPhasePredicateRecord