diff options
author | Andres Freund <andres@anarazel.de> | 2019-03-25 00:13:42 -0700 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2019-03-25 00:17:59 -0700 |
commit | 9a8ee1dc650be623c32b1df103254847be974d01 (patch) | |
tree | ff0b827f8a082f076037a17cbd91a9a2ca0b743f /src/backend/commands/trigger.c | |
parent | c77e12208cd8540a209cc698373a3cfba8802639 (diff) | |
download | postgresql-9a8ee1dc650be623c32b1df103254847be974d01.tar.gz postgresql-9a8ee1dc650be623c32b1df103254847be974d01.zip |
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 visibility
checks.
Note that this different from table_index_fetch_tuple(), which is for
index lookups. It therefore has to handle a tid pointing to an earlier
version of a tuple if the AM uses an optimization like heap's HOT. Add
comments to that end.
This commit removes the stats_relation argument from heap_fetch, as
it's been unused for a long time.
Author: Andres Freund
Reviewed-By: Haribabu Kommi
Discussion: https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r-- | src/backend/commands/trigger.c | 69 |
1 files changed, 12 insertions, 57 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index bf12b848105..e03ffdde387 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -14,10 +14,11 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" -#include "access/tableam.h" -#include "access/sysattr.h" #include "access/htup_details.h" +#include "access/relation.h" +#include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" @@ -3379,42 +3380,12 @@ GetTupleForTrigger(EState *estate, } else { - Page page; - ItemId lp; - Buffer buffer; - BufferHeapTupleTableSlot *boldslot; - HeapTuple tuple; - - Assert(TTS_IS_BUFFERTUPLE(oldslot)); - ExecClearTuple(oldslot); - boldslot = (BufferHeapTupleTableSlot *) oldslot; - tuple = &boldslot->base.tupdata; - - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); - /* - * Although we already know this tuple is valid, we must lock the - * buffer to ensure that no one has a buffer cleanup lock; otherwise - * they might move the tuple while we try to copy it. But we can - * release the lock before actually doing the heap_copytuple call, - * since holding pin is sufficient to prevent anyone from getting a - * cleanup lock they don't already hold. + * We expect the tuple to be present, thus very simple error handling + * suffices. */ - LockBuffer(buffer, BUFFER_LOCK_SHARE); - - page = BufferGetPage(buffer); - lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid)); - - Assert(ItemIdIsNormal(lp)); - - tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp); - tuple->t_len = ItemIdGetLength(lp); - tuple->t_self = *tid; - tuple->t_tableOid = RelationGetRelid(relation); - - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - - ExecStorePinnedBufferHeapTuple(tuple, oldslot, buffer); + if (!table_fetch_row_version(relation, tid, SnapshotAny, oldslot)) + elog(ERROR, "failed to fetch tuple for trigger"); } return true; @@ -4193,8 +4164,6 @@ AfterTriggerExecute(EState *estate, AfterTriggerShared evtshared = GetTriggerSharedData(event); Oid tgoid = evtshared->ats_tgoid; TriggerData LocTriggerData; - HeapTupleData tuple1; - HeapTupleData tuple2; HeapTuple rettuple; int tgindx; bool should_free_trig = false; @@ -4271,19 +4240,12 @@ AfterTriggerExecute(EState *estate, default: if (ItemPointerIsValid(&(event->ate_ctid1))) { - Buffer buffer; - LocTriggerData.tg_trigslot = ExecGetTriggerOldSlot(estate, relInfo); - ItemPointerCopy(&(event->ate_ctid1), &(tuple1.t_self)); - if (!heap_fetch(rel, SnapshotAny, &tuple1, &buffer, NULL)) + if (!table_fetch_row_version(rel, &(event->ate_ctid1), SnapshotAny, LocTriggerData.tg_trigslot)) elog(ERROR, "failed to fetch tuple1 for AFTER trigger"); - ExecStorePinnedBufferHeapTuple(&tuple1, - LocTriggerData.tg_trigslot, - buffer); LocTriggerData.tg_trigtuple = - ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, - &should_free_trig); + ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, &should_free_trig); } else { @@ -4295,19 +4257,12 @@ AfterTriggerExecute(EState *estate, AFTER_TRIGGER_2CTID && ItemPointerIsValid(&(event->ate_ctid2))) { - Buffer buffer; - LocTriggerData.tg_newslot = ExecGetTriggerNewSlot(estate, relInfo); - ItemPointerCopy(&(event->ate_ctid2), &(tuple2.t_self)); - if (!heap_fetch(rel, SnapshotAny, &tuple2, &buffer, NULL)) + if (!table_fetch_row_version(rel, &(event->ate_ctid2), SnapshotAny, LocTriggerData.tg_newslot)) elog(ERROR, "failed to fetch tuple2 for AFTER trigger"); - ExecStorePinnedBufferHeapTuple(&tuple2, - LocTriggerData.tg_newslot, - buffer); LocTriggerData.tg_newtuple = - ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, - &should_free_new); + ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, &should_free_new); } else { |