mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 14:41:24 +02:00
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
This commit is contained in:
parent
41f5e04aec
commit
4c9e1bd0a3
@ -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,
|
|||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user