Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9a8ee1d

Browse files
committed
tableam: Add and use table_fetch_row_version().
This is essentially the tableam version of heapam_fetch(),i.e. fetching a tuple identified by a tid, performing visibilitychecks.Note that this different from table_index_fetch_tuple(), which is forindex lookups. It therefore has to handle a tid pointing to an earlierversion of a tuple if the AM uses an optimization like heap's HOT. Addcomments to that end.This commit removes the stats_relation argument from heap_fetch, asit's been unused for a long time.Author: Andres FreundReviewed-By: Haribabu KommiDiscussion:https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
1 parentc77e122 commit9a8ee1d

File tree

9 files changed

+91
-111
lines changed

9 files changed

+91
-111
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,8 +1388,7 @@ bool
13881388
heap_fetch(Relationrelation,
13891389
Snapshotsnapshot,
13901390
HeapTupletuple,
1391-
Buffer*userbuf,
1392-
Relationstats_relation)
1391+
Buffer*userbuf)
13931392
{
13941393
ItemPointertid=&(tuple->t_self);
13951394
ItemIdlp;
@@ -1468,10 +1467,6 @@ heap_fetch(Relation relation,
14681467
*/
14691468
*userbuf=buffer;
14701469

1471-
/* Count the successful fetch against appropriate rel, if any */
1472-
if (stats_relation!=NULL)
1473-
pgstat_count_heap_fetch(stats_relation);
1474-
14751470
return true;
14761471
}
14771472

@@ -5097,7 +5092,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
50975092
block=ItemPointerGetBlockNumber(&tupid);
50985093
ItemPointerCopy(&tupid,&(mytup.t_self));
50995094

5100-
if (!heap_fetch(rel,SnapshotAny,&mytup,&buf,NULL))
5095+
if (!heap_fetch(rel,SnapshotAny,&mytup,&buf))
51015096
{
51025097
/*
51035098
* if we fail to find the updated version of the tuple, it's

‎src/backend/access/heap/heapam_handler.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,30 @@ heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
148148
* ------------------------------------------------------------------------
149149
*/
150150

151+
staticbool
152+
heapam_fetch_row_version(Relationrelation,
153+
ItemPointertid,
154+
Snapshotsnapshot,
155+
TupleTableSlot*slot)
156+
{
157+
BufferHeapTupleTableSlot*bslot= (BufferHeapTupleTableSlot*)slot;
158+
Bufferbuffer;
159+
160+
Assert(TTS_IS_BUFFERTUPLE(slot));
161+
162+
bslot->base.tupdata.t_self=*tid;
163+
if (heap_fetch(relation,snapshot,&bslot->base.tupdata,&buffer))
164+
{
165+
/* store in slot, transferring existing pin */
166+
ExecStorePinnedBufferHeapTuple(&bslot->base.tupdata,slot,buffer);
167+
slot->tts_tableOid=RelationGetRelid(relation);
168+
169+
return true;
170+
}
171+
172+
return false;
173+
}
174+
151175
staticbool
152176
heapam_tuple_satisfies_snapshot(Relationrel,TupleTableSlot*slot,
153177
Snapshotsnapshot)
@@ -338,7 +362,7 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
338362
errmsg("tuple to be locked was already moved to another partition due to concurrent update")));
339363

340364
tuple->t_self=*tid;
341-
if (heap_fetch(relation,&SnapshotDirty,tuple,&buffer,NULL))
365+
if (heap_fetch(relation,&SnapshotDirty,tuple,&buffer))
342366
{
343367
/*
344368
* If xmin isn't what we're expecting, the slot must have
@@ -517,6 +541,7 @@ static const TableAmRoutine heapam_methods = {
517541
.tuple_update=heapam_tuple_update,
518542
.tuple_lock=heapam_tuple_lock,
519543

544+
.tuple_fetch_row_version=heapam_fetch_row_version,
520545
.tuple_satisfies_snapshot=heapam_tuple_satisfies_snapshot,
521546
};
522547

‎src/backend/access/table/tableamapi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ GetTableAmRoutine(Oid amhandler)
6262
Assert(routine->index_fetch_end!=NULL);
6363
Assert(routine->index_fetch_tuple!=NULL);
6464

65+
Assert(routine->tuple_fetch_row_version!=NULL);
6566
Assert(routine->tuple_satisfies_snapshot!=NULL);
6667

6768
Assert(routine->tuple_insert!=NULL);

‎src/backend/commands/trigger.c

Lines changed: 12 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
#include"postgres.h"
1515

1616
#include"access/genam.h"
17-
#include"access/heapam.h"
18-
#include"access/tableam.h"
19-
#include"access/sysattr.h"
2017
#include"access/htup_details.h"
18+
#include"access/relation.h"
19+
#include"access/sysattr.h"
20+
#include"access/table.h"
21+
#include"access/tableam.h"
2122
#include"access/xact.h"
2223
#include"catalog/catalog.h"
2324
#include"catalog/dependency.h"
@@ -3379,42 +3380,12 @@ GetTupleForTrigger(EState *estate,
33793380
}
33803381
else
33813382
{
3382-
Pagepage;
3383-
ItemIdlp;
3384-
Bufferbuffer;
3385-
BufferHeapTupleTableSlot*boldslot;
3386-
HeapTupletuple;
3387-
3388-
Assert(TTS_IS_BUFFERTUPLE(oldslot));
3389-
ExecClearTuple(oldslot);
3390-
boldslot= (BufferHeapTupleTableSlot*)oldslot;
3391-
tuple=&boldslot->base.tupdata;
3392-
3393-
buffer=ReadBuffer(relation,ItemPointerGetBlockNumber(tid));
3394-
33953383
/*
3396-
* Although we already know this tuple is valid, we must lock the
3397-
* buffer to ensure that no one has a buffer cleanup lock; otherwise
3398-
* they might move the tuple while we try to copy it. But we can
3399-
* release the lock before actually doing the heap_copytuple call,
3400-
* since holding pin is sufficient to prevent anyone from getting a
3401-
* cleanup lock they don't already hold.
3384+
* We expect the tuple to be present, thus very simple error handling
3385+
* suffices.
34023386
*/
3403-
LockBuffer(buffer,BUFFER_LOCK_SHARE);
3404-
3405-
page=BufferGetPage(buffer);
3406-
lp=PageGetItemId(page,ItemPointerGetOffsetNumber(tid));
3407-
3408-
Assert(ItemIdIsNormal(lp));
3409-
3410-
tuple->t_data= (HeapTupleHeader)PageGetItem(page,lp);
3411-
tuple->t_len=ItemIdGetLength(lp);
3412-
tuple->t_self=*tid;
3413-
tuple->t_tableOid=RelationGetRelid(relation);
3414-
3415-
LockBuffer(buffer,BUFFER_LOCK_UNLOCK);
3416-
3417-
ExecStorePinnedBufferHeapTuple(tuple,oldslot,buffer);
3387+
if (!table_fetch_row_version(relation,tid,SnapshotAny,oldslot))
3388+
elog(ERROR,"failed to fetch tuple for trigger");
34183389
}
34193390

34203391
return true;
@@ -4193,8 +4164,6 @@ AfterTriggerExecute(EState *estate,
41934164
AfterTriggerSharedevtshared=GetTriggerSharedData(event);
41944165
Oidtgoid=evtshared->ats_tgoid;
41954166
TriggerDataLocTriggerData;
4196-
HeapTupleDatatuple1;
4197-
HeapTupleDatatuple2;
41984167
HeapTuplerettuple;
41994168
inttgindx;
42004169
boolshould_free_trig= false;
@@ -4271,19 +4240,12 @@ AfterTriggerExecute(EState *estate,
42714240
default:
42724241
if (ItemPointerIsValid(&(event->ate_ctid1)))
42734242
{
4274-
Bufferbuffer;
4275-
42764243
LocTriggerData.tg_trigslot=ExecGetTriggerOldSlot(estate,relInfo);
42774244

4278-
ItemPointerCopy(&(event->ate_ctid1),&(tuple1.t_self));
4279-
if (!heap_fetch(rel,SnapshotAny,&tuple1,&buffer,NULL))
4245+
if (!table_fetch_row_version(rel,&(event->ate_ctid1),SnapshotAny,LocTriggerData.tg_trigslot))
42804246
elog(ERROR,"failed to fetch tuple1 for AFTER trigger");
4281-
ExecStorePinnedBufferHeapTuple(&tuple1,
4282-
LocTriggerData.tg_trigslot,
4283-
buffer);
42844247
LocTriggerData.tg_trigtuple=
4285-
ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false,
4286-
&should_free_trig);
4248+
ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false,&should_free_trig);
42874249
}
42884250
else
42894251
{
@@ -4295,19 +4257,12 @@ AfterTriggerExecute(EState *estate,
42954257
AFTER_TRIGGER_2CTID&&
42964258
ItemPointerIsValid(&(event->ate_ctid2)))
42974259
{
4298-
Bufferbuffer;
4299-
43004260
LocTriggerData.tg_newslot=ExecGetTriggerNewSlot(estate,relInfo);
43014261

4302-
ItemPointerCopy(&(event->ate_ctid2),&(tuple2.t_self));
4303-
if (!heap_fetch(rel,SnapshotAny,&tuple2,&buffer,NULL))
4262+
if (!table_fetch_row_version(rel,&(event->ate_ctid2),SnapshotAny,LocTriggerData.tg_newslot))
43044263
elog(ERROR,"failed to fetch tuple2 for AFTER trigger");
4305-
ExecStorePinnedBufferHeapTuple(&tuple2,
4306-
LocTriggerData.tg_newslot,
4307-
buffer);
43084264
LocTriggerData.tg_newtuple=
4309-
ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false,
4310-
&should_free_new);
4265+
ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false,&should_free_new);
43114266
}
43124267
else
43134268
{

‎src/backend/executor/execMain.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,17 +2649,10 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
26492649
else
26502650
{
26512651
/* ordinary table, fetch the tuple */
2652-
HeapTupleDatatuple;
2653-
Bufferbuffer;
2654-
2655-
tuple.t_self=*((ItemPointer)DatumGetPointer(datum));
2656-
if (!heap_fetch(erm->relation,SnapshotAny,&tuple,&buffer,
2657-
NULL))
2652+
if (!table_fetch_row_version(erm->relation,
2653+
(ItemPointer)DatumGetPointer(datum),
2654+
SnapshotAny,slot))
26582655
elog(ERROR,"failed to fetch tuple for EvalPlanQual recheck");
2659-
2660-
/* successful, store tuple */
2661-
ExecStorePinnedBufferHeapTuple(&tuple,slot,buffer);
2662-
ExecMaterializeSlot(slot);
26632656
}
26642657
}
26652658
else

‎src/backend/executor/nodeModifyTable.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,13 @@ ExecCheckTIDVisible(EState *estate,
229229
TupleTableSlot*tempSlot)
230230
{
231231
Relationrel=relinfo->ri_RelationDesc;
232-
Bufferbuffer;
233-
HeapTupleDatatuple;
234232

235233
/* Redundantly check isolation level */
236234
if (!IsolationUsesXactSnapshot())
237235
return;
238236

239-
tuple.t_self=*tid;
240-
if (!heap_fetch(rel,SnapshotAny,&tuple,&buffer,NULL))
237+
if (!table_fetch_row_version(rel,tid,SnapshotAny,tempSlot))
241238
elog(ERROR,"failed to fetch conflicting tuple for ON CONFLICT");
242-
ExecStorePinnedBufferHeapTuple(&tuple,tempSlot,buffer);
243239
ExecCheckTupleVisible(estate,rel,tempSlot);
244240
ExecClearTuple(tempSlot);
245241
}
@@ -874,21 +870,9 @@ ldelete:;
874870
}
875871
else
876872
{
877-
BufferHeapTupleTableSlot*bslot;
878-
HeapTupledeltuple;
879-
Bufferbuffer;
880-
881-
Assert(TTS_IS_BUFFERTUPLE(slot));
882-
ExecClearTuple(slot);
883-
bslot= (BufferHeapTupleTableSlot*)slot;
884-
deltuple=&bslot->base.tupdata;
885-
886-
deltuple->t_self=*tupleid;
887-
if (!heap_fetch(resultRelationDesc,SnapshotAny,
888-
deltuple,&buffer,NULL))
873+
if (!table_fetch_row_version(resultRelationDesc,tupleid,
874+
SnapshotAny,slot))
889875
elog(ERROR,"failed to fetch deleted tuple for DELETE RETURNING");
890-
891-
ExecStorePinnedBufferHeapTuple(deltuple,slot,buffer);
892876
}
893877
}
894878

‎src/backend/executor/nodeTidscan.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ TidNext(TidScanState *node)
310310
RelationheapRelation;
311311
HeapTupletuple;
312312
TupleTableSlot*slot;
313-
Bufferbuffer=InvalidBuffer;
314313
ItemPointerData*tidList;
315314
intnumTids;
316315
boolbBackward;
@@ -376,19 +375,10 @@ TidNext(TidScanState *node)
376375
if (node->tss_isCurrentOf)
377376
heap_get_latest_tid(heapRelation,snapshot,&tuple->t_self);
378377

379-
if (heap_fetch(heapRelation,snapshot,tuple,&buffer,NULL))
380-
{
381-
/*
382-
* Store the scanned tuple in the scan tuple slot of the scan
383-
* state, transferring the pin to the slot.
384-
*/
385-
ExecStorePinnedBufferHeapTuple(tuple,/* tuple to store */
386-
slot,/* slot to store in */
387-
buffer);/* buffer associated with
388-
* tuple */
389-
378+
if (table_fetch_row_version(heapRelation,&tuple->t_self,snapshot,
379+
slot))
390380
returnslot;
391-
}
381+
392382
/* Bad TID or failed snapshot qual; try next */
393383
if (bBackward)
394384
node->tss_TidPtr--;

‎src/include/access/heapam.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ extern bool heap_getnextslot(TableScanDesc sscan,
128128
ScanDirectiondirection,structTupleTableSlot*slot);
129129

130130
externboolheap_fetch(Relationrelation,Snapshotsnapshot,
131-
HeapTupletuple,Buffer*userbuf,Relationstats_relation);
131+
HeapTupletuple,Buffer*userbuf);
132132
externboolheap_hot_search_buffer(ItemPointertid,Relationrelation,
133133
Bufferbuffer,Snapshotsnapshot,HeapTupleheapTuple,
134134
bool*all_dead,boolfirst_call);

‎src/include/access/tableam.h

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,17 @@ typedef struct TableAmRoutine
271271
* ------------------------------------------------------------------------
272272
*/
273273

274+
275+
/*
276+
* Fetch tuple at `tid` into `slot, after doing a visibility test
277+
* according to `snapshot`. If a tuple was found and passed the visibility
278+
* test, returns true, false otherwise.
279+
*/
280+
bool(*tuple_fetch_row_version) (Relationrel,
281+
ItemPointertid,
282+
Snapshotsnapshot,
283+
TupleTableSlot*slot);
284+
274285
/*
275286
* Does the tuple in `slot` satisfy `snapshot`? The slot needs to be of
276287
* the appropriate type for the AM.
@@ -574,9 +585,9 @@ table_index_fetch_end(struct IndexFetchTableData *scan)
574585
}
575586

576587
/*
577-
* Fetchestuple at `tid` into `slot`, after doing a visibility test according
578-
* to `snapshot`. If a tuple was found and passed the visibility test, returns
579-
* true, false otherwise.
588+
* Fetches, as part of an index scan,tuple at `tid` into `slot`, after doing
589+
*a visibility test accordingto `snapshot`. If a tuple was found and passed
590+
*the visibility test, returnstrue, false otherwise.
580591
*
581592
* *call_again needs to be false on the first call to table_index_fetch_tuple() for
582593
* a tid. If there potentially is another tuple matching the tid, *call_again
@@ -586,6 +597,13 @@ table_index_fetch_end(struct IndexFetchTableData *scan)
586597
* *all_dead will be set to true by table_index_fetch_tuple() iff it is guaranteed
587598
* that no backend needs to see that tuple. Index AMs can use that do avoid
588599
* returning that tid in future searches.
600+
*
601+
* The difference between this function and table_fetch_row_version is that
602+
* this function returns the currently visible version of a row if the AM
603+
* supports storing multiple row versions reachable via a single index entry
604+
* (like heap's HOT). Whereas table_fetch_row_version only evaluates the the
605+
* tuple exactly at `tid`. Outside of index entry ->table tuple lookups,
606+
* table_fetch_row_version is what's usually needed.
589607
*/
590608
staticinlinebool
591609
table_index_fetch_tuple(structIndexFetchTableData*scan,
@@ -606,6 +624,25 @@ table_index_fetch_tuple(struct IndexFetchTableData *scan,
606624
* ------------------------------------------------------------------------
607625
*/
608626

627+
628+
/*
629+
* Fetch tuple at `tid` into `slot, after doing a visibility test according to
630+
* `snapshot`. If a tuple was found and passed the visibility test, returns
631+
* true, false otherwise.
632+
*
633+
* See table_index_fetch_tuple's comment about what the difference between
634+
* these functions is. This function is the correct to use outside of
635+
* index entry->table tuple lookups.
636+
*/
637+
staticinlinebool
638+
table_fetch_row_version(Relationrel,
639+
ItemPointertid,
640+
Snapshotsnapshot,
641+
TupleTableSlot*slot)
642+
{
643+
returnrel->rd_tableam->tuple_fetch_row_version(rel,tid,snapshot,slot);
644+
}
645+
609646
/*
610647
* Return true iff tuple in slot satisfies the snapshot.
611648
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp