Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0518ece

Browse files
committed
Adjust HeapTupleSatisfies* routines to take a HeapTuple.
Previously, these functions took a HeapTupleHeader, but upcoming patches for logical replication will introduce new a new snapshot type under which the tuple's TID will be used to lookup (CMIN, CMAX) for visibility determination purposes. This makes that information available. Code churn is minimal since HeapTupleSatisfiesVisibility took the HeapTuple anyway, and deferenced it before calling the satisfies function. Independently of logical replication, this allows t_tableOid and t_self to be cross-checked via assertions in tqual.c. This seems like a useful way to make sure that all callers are setting these values properly, which has been previously put forward as desirable. Andres Freund, reviewed by Álvaro Herrera
1 parent 0aeb5ae commit 0518ece

File tree

12 files changed

+91
-38
lines changed

12 files changed

+91
-38
lines changed

contrib/pgrowlocks/pgrowlocks.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
131131
/* must hold a buffer lock to call HeapTupleSatisfiesUpdate */
132132
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
133133

134-
htsu = HeapTupleSatisfiesUpdate(tuple->t_data,
134+
htsu = HeapTupleSatisfiesUpdate(tuple,
135135
GetCurrentCommandId(false),
136136
scan->rs_cbuf);
137137
xmax = HeapTupleHeaderGetRawXmax(tuple->t_data);

src/backend/access/heap/heapam.c

+8-5
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ heapgetpage(HeapScanDesc scan, BlockNumber page)
387387
HeapTupleData loctup;
388388
bool valid;
389389

390+
loctup.t_tableOid = RelationGetRelid(scan->rs_rd);
390391
loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp);
391392
loctup.t_len = ItemIdGetLength(lpp);
392393
ItemPointerSet(&(loctup.t_self), page, lineoff);
@@ -1715,7 +1716,7 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
17151716

17161717
heapTuple->t_data = (HeapTupleHeader) PageGetItem(dp, lp);
17171718
heapTuple->t_len = ItemIdGetLength(lp);
1718-
heapTuple->t_tableOid = relation->rd_id;
1719+
heapTuple->t_tableOid = RelationGetRelid(relation);
17191720
heapTuple->t_self = *tid;
17201721

17211722
/*
@@ -1763,7 +1764,7 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
17631764
* transactions.
17641765
*/
17651766
if (all_dead && *all_dead &&
1766-
!HeapTupleIsSurelyDead(heapTuple->t_data, RecentGlobalXmin))
1767+
!HeapTupleIsSurelyDead(heapTuple, RecentGlobalXmin))
17671768
*all_dead = false;
17681769

17691770
/*
@@ -1893,6 +1894,7 @@ heap_get_latest_tid(Relation relation,
18931894
tp.t_self = ctid;
18941895
tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
18951896
tp.t_len = ItemIdGetLength(lp);
1897+
tp.t_tableOid = RelationGetRelid(relation);
18961898

18971899
/*
18981900
* After following a t_ctid link, we might arrive at an unrelated
@@ -2591,12 +2593,13 @@ heap_delete(Relation relation, ItemPointer tid,
25912593
lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
25922594
Assert(ItemIdIsNormal(lp));
25932595

2596+
tp.t_tableOid = RelationGetRelid(relation);
25942597
tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
25952598
tp.t_len = ItemIdGetLength(lp);
25962599
tp.t_self = *tid;
25972600

25982601
l1:
2599-
result = HeapTupleSatisfiesUpdate(tp.t_data, cid, buffer);
2602+
result = HeapTupleSatisfiesUpdate(&tp, cid, buffer);
26002603

26012604
if (result == HeapTupleInvisible)
26022605
{
@@ -3070,7 +3073,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
30703073
l2:
30713074
checked_lockers = false;
30723075
locker_remains = false;
3073-
result = HeapTupleSatisfiesUpdate(oldtup.t_data, cid, buffer);
3076+
result = HeapTupleSatisfiesUpdate(&oldtup, cid, buffer);
30743077

30753078
/* see below about the "no wait" case */
30763079
Assert(result != HeapTupleBeingUpdated || wait);
@@ -3941,7 +3944,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
39413944
tuple->t_tableOid = RelationGetRelid(relation);
39423945

39433946
l3:
3944-
result = HeapTupleSatisfiesUpdate(tuple->t_data, cid, *buffer);
3947+
result = HeapTupleSatisfiesUpdate(tuple, cid, *buffer);
39453948

39463949
if (result == HeapTupleInvisible)
39473950
{

src/backend/access/heap/pruneheap.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
339339
OffsetNumber chainitems[MaxHeapTuplesPerPage];
340340
int nchain = 0,
341341
i;
342+
HeapTupleData tup;
343+
344+
tup.t_tableOid = RelationGetRelid(relation);
342345

343346
rootlp = PageGetItemId(dp, rootoffnum);
344347

@@ -348,6 +351,12 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
348351
if (ItemIdIsNormal(rootlp))
349352
{
350353
htup = (HeapTupleHeader) PageGetItem(dp, rootlp);
354+
355+
tup.t_data = htup;
356+
tup.t_len = ItemIdGetLength(rootlp);
357+
tup.t_tableOid = RelationGetRelid(relation);
358+
ItemPointerSet(&(tup.t_self), BufferGetBlockNumber(buffer), rootoffnum);
359+
351360
if (HeapTupleHeaderIsHeapOnly(htup))
352361
{
353362
/*
@@ -368,7 +377,7 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
368377
* either here or while following a chain below. Whichever path
369378
* gets there first will mark the tuple unused.
370379
*/
371-
if (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer)
380+
if (HeapTupleSatisfiesVacuum(&tup, OldestXmin, buffer)
372381
== HEAPTUPLE_DEAD && !HeapTupleHeaderIsHotUpdated(htup))
373382
{
374383
heap_prune_record_unused(prstate, rootoffnum);
@@ -431,6 +440,10 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
431440
Assert(ItemIdIsNormal(lp));
432441
htup = (HeapTupleHeader) PageGetItem(dp, lp);
433442

443+
tup.t_data = htup;
444+
tup.t_len = ItemIdGetLength(lp);
445+
ItemPointerSet(&(tup.t_self), BufferGetBlockNumber(buffer), offnum);
446+
434447
/*
435448
* Check the tuple XMIN against prior XMAX, if any
436449
*/
@@ -448,7 +461,7 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
448461
*/
449462
tupdead = recent_dead = false;
450463

451-
switch (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer))
464+
switch (HeapTupleSatisfiesVacuum(&tup, OldestXmin, buffer))
452465
{
453466
case HEAPTUPLE_DEAD:
454467
tupdead = true;

src/backend/catalog/index.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ IndexBuildHeapScan(Relation heapRelation,
22512251
*/
22522252
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
22532253

2254-
switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, OldestXmin,
2254+
switch (HeapTupleSatisfiesVacuum(heapTuple, OldestXmin,
22552255
scan->rs_cbuf))
22562256
{
22572257
case HEAPTUPLE_DEAD:

src/backend/commands/analyze.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1138,10 +1138,11 @@ acquire_sample_rows(Relation onerel, int elevel,
11381138

11391139
ItemPointerSet(&targtuple.t_self, targblock, targoffset);
11401140

1141+
targtuple.t_tableOid = RelationGetRelid(onerel);
11411142
targtuple.t_data = (HeapTupleHeader) PageGetItem(targpage, itemid);
11421143
targtuple.t_len = ItemIdGetLength(itemid);
11431144

1144-
switch (HeapTupleSatisfiesVacuum(targtuple.t_data,
1145+
switch (HeapTupleSatisfiesVacuum(&targtuple,
11451146
OldestXmin,
11461147
targbuffer))
11471148
{

src/backend/commands/cluster.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
979979

980980
LockBuffer(buf, BUFFER_LOCK_SHARE);
981981

982-
switch (HeapTupleSatisfiesVacuum(tuple->t_data, OldestXmin, buf))
982+
switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf))
983983
{
984984
case HEAPTUPLE_DEAD:
985985
/* Definitely dead */

src/backend/commands/vacuumlazy.c

+8-5
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static void lazy_record_dead_tuple(LVRelStats *vacrelstats,
151151
ItemPointer itemptr);
152152
static bool lazy_tid_reaped(ItemPointer itemptr, void *state);
153153
static int vac_cmp_itemptr(const void *left, const void *right);
154-
static bool heap_page_is_all_visible(Buffer buf,
154+
static bool heap_page_is_all_visible(Relation rel, Buffer buf,
155155
TransactionId *visibility_cutoff_xid);
156156

157157

@@ -756,10 +756,11 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
756756

757757
tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
758758
tuple.t_len = ItemIdGetLength(itemid);
759+
tuple.t_tableOid = RelationGetRelid(onerel);
759760

760761
tupgone = false;
761762

762-
switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf))
763+
switch (HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf))
763764
{
764765
case HEAPTUPLE_DEAD:
765766

@@ -1168,7 +1169,7 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
11681169
* check if the page has become all-visible.
11691170
*/
11701171
if (!visibilitymap_test(onerel, blkno, vmbuffer) &&
1171-
heap_page_is_all_visible(buffer, &visibility_cutoff_xid))
1172+
heap_page_is_all_visible(onerel, buffer, &visibility_cutoff_xid))
11721173
{
11731174
Assert(BufferIsValid(*vmbuffer));
11741175
PageSetAllVisible(page);
@@ -1676,7 +1677,7 @@ vac_cmp_itemptr(const void *left, const void *right)
16761677
* xmin amongst the visible tuples.
16771678
*/
16781679
static bool
1679-
heap_page_is_all_visible(Buffer buf, TransactionId *visibility_cutoff_xid)
1680+
heap_page_is_all_visible(Relation rel, Buffer buf, TransactionId *visibility_cutoff_xid)
16801681
{
16811682
Page page = BufferGetPage(buf);
16821683
OffsetNumber offnum,
@@ -1718,8 +1719,10 @@ heap_page_is_all_visible(Buffer buf, TransactionId *visibility_cutoff_xid)
17181719
Assert(ItemIdIsNormal(itemid));
17191720

17201721
tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
1722+
tuple.t_len = ItemIdGetLength(itemid);
1723+
tuple.t_tableOid = RelationGetRelid(rel);
17211724

1722-
switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf))
1725+
switch (HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf))
17231726
{
17241727
case HEAPTUPLE_LIVE:
17251728
{

src/backend/executor/nodeBitmapHeapscan.c

+1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
258258

259259
scan->rs_ctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
260260
scan->rs_ctup.t_len = ItemIdGetLength(lp);
261+
scan->rs_ctup.t_tableOid = scan->rs_rd->rd_id;
261262
ItemPointerSet(&scan->rs_ctup.t_self, tbmres->blockno, targoffset);
262263

263264
pgstat_count_heap_fetch(scan->rs_rd);

src/backend/storage/lmgr/predicate.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3895,7 +3895,7 @@ CheckForSerializableConflictOut(bool visible, Relation relation,
38953895
* tuple is visible to us, while HeapTupleSatisfiesVacuum checks what else
38963896
* is going on with it.
38973897
*/
3898-
htsvResult = HeapTupleSatisfiesVacuum(tuple->t_data, TransactionXmin, buffer);
3898+
htsvResult = HeapTupleSatisfiesVacuum(tuple, TransactionXmin, buffer);
38993899
switch (htsvResult)
39003900
{
39013901
case HEAPTUPLE_LIVE:

src/backend/utils/time/tqual.c

+41-9
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,12 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
163163
* Xmax is not committed))) that has not been committed
164164
*/
165165
bool
166-
HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
166+
HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
167167
{
168+
HeapTupleHeader tuple = htup->t_data;
169+
Assert(ItemPointerIsValid(&htup->t_self));
170+
Assert(htup->t_tableOid != InvalidOid);
171+
168172
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
169173
{
170174
if (tuple->t_infomask & HEAP_XMIN_INVALID)
@@ -351,8 +355,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
351355
*
352356
*/
353357
bool
354-
HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
358+
HeapTupleSatisfiesNow(HeapTuple htup, Snapshot snapshot, Buffer buffer)
355359
{
360+
HeapTupleHeader tuple = htup->t_data;
361+
Assert(ItemPointerIsValid(&htup->t_self));
362+
Assert(htup->t_tableOid != InvalidOid);
363+
356364
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
357365
{
358366
if (tuple->t_infomask & HEAP_XMIN_INVALID)
@@ -526,7 +534,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
526534
* Dummy "satisfies" routine: any tuple satisfies SnapshotAny.
527535
*/
528536
bool
529-
HeapTupleSatisfiesAny(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
537+
HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer)
530538
{
531539
return true;
532540
}
@@ -546,9 +554,13 @@ HeapTupleSatisfiesAny(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
546554
* table.
547555
*/
548556
bool
549-
HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
557+
HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
550558
Buffer buffer)
551559
{
560+
HeapTupleHeader tuple = htup->t_data;
561+
Assert(ItemPointerIsValid(&htup->t_self));
562+
Assert(htup->t_tableOid != InvalidOid);
563+
552564
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
553565
{
554566
if (tuple->t_infomask & HEAP_XMIN_INVALID)
@@ -627,9 +639,13 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
627639
* distinguish that case must test for it themselves.)
628640
*/
629641
HTSU_Result
630-
HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
642+
HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
631643
Buffer buffer)
632644
{
645+
HeapTupleHeader tuple = htup->t_data;
646+
Assert(ItemPointerIsValid(&htup->t_self));
647+
Assert(htup->t_tableOid != InvalidOid);
648+
633649
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
634650
{
635651
if (tuple->t_infomask & HEAP_XMIN_INVALID)
@@ -849,9 +865,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
849865
* for snapshot->xmax and the tuple's xmax.
850866
*/
851867
bool
852-
HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
868+
HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
853869
Buffer buffer)
854870
{
871+
HeapTupleHeader tuple = htup->t_data;
872+
Assert(ItemPointerIsValid(&htup->t_self));
873+
Assert(htup->t_tableOid != InvalidOid);
874+
855875
snapshot->xmin = snapshot->xmax = InvalidTransactionId;
856876

857877
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
@@ -1040,9 +1060,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
10401060
* can't see it.)
10411061
*/
10421062
bool
1043-
HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
1063+
HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
10441064
Buffer buffer)
10451065
{
1066+
HeapTupleHeader tuple = htup->t_data;
1067+
Assert(ItemPointerIsValid(&htup->t_self));
1068+
Assert(htup->t_tableOid != InvalidOid);
1069+
10461070
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
10471071
{
10481072
if (tuple->t_infomask & HEAP_XMIN_INVALID)
@@ -1233,9 +1257,13 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
12331257
* even if we see that the deleting transaction has committed.
12341258
*/
12351259
HTSV_Result
1236-
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
1260+
HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
12371261
Buffer buffer)
12381262
{
1263+
HeapTupleHeader tuple = htup->t_data;
1264+
Assert(ItemPointerIsValid(&htup->t_self));
1265+
Assert(htup->t_tableOid != InvalidOid);
1266+
12391267
/*
12401268
* Has inserting transaction committed?
12411269
*
@@ -1466,8 +1494,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
14661494
* just whether or not the tuple is surely dead).
14671495
*/
14681496
bool
1469-
HeapTupleIsSurelyDead(HeapTupleHeader tuple, TransactionId OldestXmin)
1497+
HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin)
14701498
{
1499+
HeapTupleHeader tuple = htup->t_data;
1500+
Assert(ItemPointerIsValid(&htup->t_self));
1501+
Assert(htup->t_tableOid != InvalidOid);
1502+
14711503
/*
14721504
* If the inserting transaction is marked invalid, then it aborted, and
14731505
* the tuple is definitely dead. If it's marked neither committed nor

src/include/utils/snapshot.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ typedef struct SnapshotData *Snapshot;
2727
* The specific semantics of a snapshot are encoded by the "satisfies"
2828
* function.
2929
*/
30-
typedef bool (*SnapshotSatisfiesFunc) (HeapTupleHeader tuple,
31-
Snapshot snapshot, Buffer buffer);
30+
typedef bool (*SnapshotSatisfiesFunc) (HeapTuple htup,
31+
Snapshot snapshot, Buffer buffer);
3232

3333
typedef struct SnapshotData
3434
{

0 commit comments

Comments
 (0)