Commit 4c9e1bd0 authored by Andres Freund's avatar Andres Freund

Reset memory context once per tuple in validateForeignKeyConstraint.

When using tableam ExecFetchSlotHeapTuple() might return a separately
allocated tuple. We could use the shouldFree argument to explicitly
free it, but it seems more robust to to protect

Also add a CHECK_FOR_INTERRUPTS() after each tuple. It's likely that
each AM has (heap does) a CFI somewhere in the relevant path, but it
seems more robust to have one in validateForeignKeyConstraint()
itself.

Note that this only affects the cases that couldn't be optimized to be
verified with a query.

Author: Andres Freund
Reviewed-By: Tom Lane (in an earlier version)
Discussion:
    https://postgr.es/m/19030.1554574075@sss.pgh.pa.us
    https://postgr.es/m/CAKJS1f_SHKcPYMsi39An5aUjhAcEMZb6Cx1Sj1QWEWSiKJkBVQ@mail.gmail.com
    https://postgr.es/m/20180711185628.mrvl46bjgk2uxoki@alap3.anarazel.de
parent 41f5e04a
...@@ -9593,6 +9593,8 @@ validateForeignKeyConstraint(char *conname, ...@@ -9593,6 +9593,8 @@ validateForeignKeyConstraint(char *conname,
TableScanDesc scan; TableScanDesc scan;
Trigger trig; Trigger trig;
Snapshot snapshot; Snapshot snapshot;
MemoryContext oldcxt;
MemoryContext perTupCxt;
ereport(DEBUG1, ereport(DEBUG1,
(errmsg("validating foreign key constraint \"%s\"", conname))); (errmsg("validating foreign key constraint \"%s\"", conname)));
...@@ -9628,11 +9630,18 @@ validateForeignKeyConstraint(char *conname, ...@@ -9628,11 +9630,18 @@ validateForeignKeyConstraint(char *conname,
slot = table_slot_create(rel, NULL); slot = table_slot_create(rel, NULL);
scan = table_beginscan(rel, snapshot, 0, NULL); scan = table_beginscan(rel, snapshot, 0, NULL);
perTupCxt = AllocSetContextCreate(CurrentMemoryContext,
"validateForeignKeyConstraint",
ALLOCSET_SMALL_SIZES);
oldcxt = MemoryContextSwitchTo(perTupCxt);
while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) while (table_scan_getnextslot(scan, ForwardScanDirection, slot))
{ {
LOCAL_FCINFO(fcinfo, 0); LOCAL_FCINFO(fcinfo, 0);
TriggerData trigdata; TriggerData trigdata;
CHECK_FOR_INTERRUPTS();
/* /*
* Make a call to the trigger function * Make a call to the trigger function
* *
...@@ -9649,13 +9658,18 @@ validateForeignKeyConstraint(char *conname, ...@@ -9649,13 +9658,18 @@ validateForeignKeyConstraint(char *conname,
trigdata.tg_trigtuple = ExecFetchSlotHeapTuple(slot, false, NULL); trigdata.tg_trigtuple = ExecFetchSlotHeapTuple(slot, false, NULL);
trigdata.tg_trigslot = slot; trigdata.tg_trigslot = slot;
trigdata.tg_newtuple = NULL; trigdata.tg_newtuple = NULL;
trigdata.tg_newslot = NULL;
trigdata.tg_trigger = &trig; trigdata.tg_trigger = &trig;
fcinfo->context = (Node *) &trigdata; fcinfo->context = (Node *) &trigdata;
RI_FKey_check_ins(fcinfo); RI_FKey_check_ins(fcinfo);
MemoryContextReset(perTupCxt);
} }
MemoryContextSwitchTo(oldcxt);
MemoryContextDelete(perTupCxt);
table_endscan(scan); table_endscan(scan);
UnregisterSnapshot(snapshot); UnregisterSnapshot(snapshot);
ExecDropSingleTupleTableSlot(slot); ExecDropSingleTupleTableSlot(slot);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment