Commit 8f2a289d authored by Tom Lane's avatar Tom Lane

Arrange to copy relcache's trigdesc structure at the start of any

query that uses it.  This ensures that triggers will be applied consistently
throughout a query even if someone commits changes to the relation's
pg_class.reltriggers field meanwhile.  Per crash report from Laurette Cisneros.
While at it, simplify memory management in relcache.c, which no longer
needs the old hack to try to keep trigger info in the same place over
a relcache entry rebuild.  (Should try to fix rd_att and rewrite-rule
access similarly, someday.)  And make RelationBuildTriggers simpler and
more robust by making it build the trigdesc in working memory and then
CopyTriggerDesc() into cache memory.
parent 8fc1f413
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.175 2002/09/20 16:56:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.176 2002/10/14 16:51:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -780,7 +780,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
resultRelInfo = makeNode(ResultRelInfo);
resultRelInfo->ri_RangeTableIndex = 1; /* dummy */
resultRelInfo->ri_RelationDesc = rel;
resultRelInfo->ri_TrigDesc = rel->trigdesc;
resultRelInfo->ri_TrigDesc = CopyTriggerDesc(rel->trigdesc);
ExecOpenIndices(resultRelInfo);
......
This diff is collapsed.
......@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.179 2002/09/23 22:57:44 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.180 2002/10/14 16:51:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -799,7 +799,8 @@ initResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo->ri_NumIndices = 0;
resultRelInfo->ri_IndexRelationDescs = NULL;
resultRelInfo->ri_IndexRelationInfo = NULL;
resultRelInfo->ri_TrigDesc = resultRelationDesc->trigdesc;
/* make a copy so as not to depend on relcache info not changing... */
resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
resultRelInfo->ri_TrigFunctions = NULL;
resultRelInfo->ri_ConstraintExprs = NULL;
resultRelInfo->ri_junkFilter = NULL;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.176 2002/09/22 20:56:28 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.177 2002/10/14 16:51:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1716,11 +1716,11 @@ RelationClearRelation(Relation relation, bool rebuild)
/*
* Free all the subsidiary data structures of the relcache entry. We
* cannot free rd_att if we are trying to rebuild the entry, however,
* because pointers to it may be cached in various places. The trigger
* manager might also have pointers into the trigdesc, and the rule
* manager might have pointers into the rewrite rules. So to begin
* because pointers to it may be cached in various places. The rule
* manager might also have pointers into the rewrite rules. So to begin
* with, we can only get rid of these fields:
*/
FreeTriggerDesc(relation->trigdesc);
if (relation->rd_index)
pfree(relation->rd_index);
if (relation->rd_am)
......@@ -1743,22 +1743,20 @@ RelationClearRelation(Relation relation, bool rebuild)
FreeTupleDesc(relation->rd_att);
if (relation->rd_rulescxt)
MemoryContextDelete(relation->rd_rulescxt);
FreeTriggerDesc(relation->trigdesc);
pfree(relation);
}
else
{
/*
* When rebuilding an open relcache entry, must preserve ref count
* and rd_isnew flag. Also attempt to preserve the tupledesc,
* rewrite rules, and trigger substructures in place.
* and rd_isnew flag. Also attempt to preserve the tupledesc and
* rewrite-rule substructures in place.
*/
int old_refcnt = relation->rd_refcnt;
bool old_isnew = relation->rd_isnew;
TupleDesc old_att = relation->rd_att;
RuleLock *old_rules = relation->rd_rules;
MemoryContext old_rulescxt = relation->rd_rulescxt;
TriggerDesc *old_trigdesc = relation->trigdesc;
RelationBuildDescInfo buildinfo;
buildinfo.infotype = INFO_RELID;
......@@ -1770,7 +1768,6 @@ RelationClearRelation(Relation relation, bool rebuild)
FreeTupleDesc(old_att);
if (old_rulescxt)
MemoryContextDelete(old_rulescxt);
FreeTriggerDesc(old_trigdesc);
pfree(relation);
elog(ERROR, "RelationClearRelation: relation %u deleted while still in use",
buildinfo.i.info_id);
......@@ -1796,13 +1793,6 @@ RelationClearRelation(Relation relation, bool rebuild)
if (old_rulescxt)
MemoryContextDelete(old_rulescxt);
}
if (equalTriggerDescs(old_trigdesc, relation->trigdesc))
{
FreeTriggerDesc(relation->trigdesc);
relation->trigdesc = old_trigdesc;
}
else
FreeTriggerDesc(old_trigdesc);
/*
* Update rd_nblocks. This is kind of expensive, but I think we
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: trigger.h,v 1.38 2002/09/04 20:31:42 momjian Exp $
* $Id: trigger.h,v 1.39 2002/10/14 16:51:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -112,9 +112,9 @@ extern void renametrig(Oid relid, const char *oldname, const char *newname);
extern void RelationBuildTriggers(Relation relation);
extern void FreeTriggerDesc(TriggerDesc *trigdesc);
extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc);
extern bool equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2);
extern void FreeTriggerDesc(TriggerDesc *trigdesc);
extern HeapTuple ExecBRInsertTriggers(EState *estate,
ResultRelInfo *relinfo,
......
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