aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2019-03-25 00:13:42 -0700
committerAndres Freund <andres@anarazel.de>2019-03-25 00:17:59 -0700
commit9a8ee1dc650be623c32b1df103254847be974d01 (patch)
treeff0b827f8a082f076037a17cbd91a9a2ca0b743f /src/backend/commands/trigger.c
parentc77e12208cd8540a209cc698373a3cfba8802639 (diff)
downloadpostgresql-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.c69
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
{