Skip to content

Commit eaf0292

Browse files
committed
Fix unsafe memory management in CloneRowTriggersToPartition().
It's not really supported to call systable_getnext() in a different memory context than systable_beginscan() was called in, and it's *definitely* not safe to do so and then reset that context between calls. I'm not very clear on how this code survived CLOBBER_CACHE_ALWAYS testing ... but Alexander Lakhin found a case that would crash it pretty reliably. Per bug #15828. Fix, and backpatch to v11 where this code came in. Discussion: https://postgr.es/m/15828-f6ddd7df4852f473@postgresql.org
1 parent 05d36b6 commit eaf0292

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

src/backend/commands/tablecmds.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15772,8 +15772,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
1577215772
ScanKeyData key;
1577315773
SysScanDesc scan;
1577415774
HeapTuple tuple;
15775-
MemoryContext oldcxt,
15776-
perTupCxt;
15775+
MemoryContext perTupCxt;
1577715776

1577815777
ScanKeyInit(&key, Anum_pg_trigger_tgrelid, BTEqualStrategyNumber,
1577915778
F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(parent)));
@@ -15783,18 +15782,16 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
1578315782

1578415783
perTupCxt = AllocSetContextCreate(CurrentMemoryContext,
1578515784
"clone trig", ALLOCSET_SMALL_SIZES);
15786-
oldcxt = MemoryContextSwitchTo(perTupCxt);
1578715785

1578815786
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1578915787
{
15790-
Form_pg_trigger trigForm;
15788+
Form_pg_trigger trigForm = (Form_pg_trigger) GETSTRUCT(tuple);
1579115789
CreateTrigStmt *trigStmt;
1579215790
Node *qual = NULL;
1579315791
Datum value;
1579415792
bool isnull;
1579515793
List *cols = NIL;
15796-
15797-
trigForm = (Form_pg_trigger) GETSTRUCT(tuple);
15794+
MemoryContext oldcxt;
1579815795

1579915796
/*
1580015797
* Ignore statement-level triggers; those are not cloned.
@@ -15813,6 +15810,9 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
1581315810
elog(ERROR, "unexpected trigger \"%s\" found",
1581415811
NameStr(trigForm->tgname));
1581515812

15813+
/* Use short-lived context for CREATE TRIGGER */
15814+
oldcxt = MemoryContextSwitchTo(perTupCxt);
15815+
1581615816
/*
1581715817
* If there is a WHEN clause, generate a 'cooked' version of it that's
1581815818
* appropriate for the partition.
@@ -15876,10 +15876,10 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
1587615876
trigForm->tgfoid, trigForm->oid, qual,
1587715877
false, true);
1587815878

15879+
MemoryContextSwitchTo(oldcxt);
1587915880
MemoryContextReset(perTupCxt);
1588015881
}
1588115882

15882-
MemoryContextSwitchTo(oldcxt);
1588315883
MemoryContextDelete(perTupCxt);
1588415884

1588515885
systable_endscan(scan);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy