Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit edfbd07

Browse files
committed
Avoid leaking memory while reading toasted entries from pg_rewrite,
and nail a couple more system indexes into cache. This doesn't make any difference in normal system operation, but when forcing constant cache resets it's difficult to get through the rules regression test without these changes.
1 parent 44b928e commit edfbd07

File tree

1 file changed

+39
-21
lines changed

1 file changed

+39
-21
lines changed

src/backend/utils/cache/relcache.c

+39-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.234 2006/01/05 10:07:46 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.235 2006/01/08 20:04:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -565,10 +565,9 @@ RelationBuildRuleLock(Relation relation)
565565
{
566566
Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(rewrite_tuple);
567567
bool isnull;
568-
Datum ruleaction;
569-
Datum rule_evqual;
570-
char *ruleaction_str;
571-
char *rule_evqual_str;
568+
Datum rule_datum;
569+
text *rule_text;
570+
char *rule_str;
572571
RewriteRule *rule;
573572

574573
rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
@@ -580,31 +579,41 @@ RelationBuildRuleLock(Relation relation)
580579
rule->attrno = rewrite_form->ev_attr;
581580
rule->isInstead = rewrite_form->is_instead;
582581

583-
/* Must use heap_getattr to fetch ev_qual and ev_action */
584-
585-
ruleaction = heap_getattr(rewrite_tuple,
582+
/*
583+
* Must use heap_getattr to fetch ev_action and ev_qual. Also,
584+
* the rule strings are often large enough to be toasted. To avoid
585+
* leaking memory in the caller's context, do the detoasting here
586+
* so we can free the detoasted version.
587+
*/
588+
rule_datum = heap_getattr(rewrite_tuple,
586589
Anum_pg_rewrite_ev_action,
587590
rewrite_tupdesc,
588591
&isnull);
589592
Assert(!isnull);
590-
ruleaction_str = DatumGetCString(DirectFunctionCall1(textout,
591-
ruleaction));
593+
rule_text = DatumGetTextP(rule_datum);
594+
rule_str = DatumGetCString(DirectFunctionCall1(textout,
595+
PointerGetDatum(rule_text)));
592596
oldcxt = MemoryContextSwitchTo(rulescxt);
593-
rule->actions = (List *) stringToNode(ruleaction_str);
597+
rule->actions = (List *) stringToNode(rule_str);
594598
MemoryContextSwitchTo(oldcxt);
595-
pfree(ruleaction_str);
599+
pfree(rule_str);
600+
if ((Pointer) rule_text != DatumGetPointer(rule_datum))
601+
pfree(rule_text);
596602

597-
rule_evqual = heap_getattr(rewrite_tuple,
598-
Anum_pg_rewrite_ev_qual,
599-
rewrite_tupdesc,
600-
&isnull);
603+
rule_datum = heap_getattr(rewrite_tuple,
604+
Anum_pg_rewrite_ev_qual,
605+
rewrite_tupdesc,
606+
&isnull);
601607
Assert(!isnull);
602-
rule_evqual_str = DatumGetCString(DirectFunctionCall1(textout,
603-
rule_evqual));
608+
rule_text = DatumGetTextP(rule_datum);
609+
rule_str = DatumGetCString(DirectFunctionCall1(textout,
610+
PointerGetDatum(rule_text)));
604611
oldcxt = MemoryContextSwitchTo(rulescxt);
605-
rule->qual = (Node *) stringToNode(rule_evqual_str);
612+
rule->qual = (Node *) stringToNode(rule_str);
606613
MemoryContextSwitchTo(oldcxt);
607-
pfree(rule_evqual_str);
614+
pfree(rule_str);
615+
if ((Pointer) rule_text != DatumGetPointer(rule_datum))
616+
pfree(rule_text);
608617

609618
if (numlocks >= maxlocks)
610619
{
@@ -2207,6 +2216,13 @@ RelationCacheInitializePhase2(void)
22072216
* true. (NOTE: perhaps it would be possible to reload them by
22082217
* temporarily setting criticalRelcachesBuilt to false again. For now,
22092218
* though, we just nail 'em in.)
2219+
*
2220+
* RewriteRelRulenameIndexId and TriggerRelidNameIndexId are not critical
2221+
* in the same way as the others, because the critical catalogs don't
2222+
* (currently) have any rules or triggers, and so these indexes can be
2223+
* rebuilt without inducing recursion. However they are used during
2224+
* relcache load when a rel does have rules or triggers, so we choose to
2225+
* nail them for performance reasons.
22102226
*/
22112227
if (!criticalRelcachesBuilt)
22122228
{
@@ -2225,8 +2241,10 @@ RelationCacheInitializePhase2(void)
22252241
LOAD_CRIT_INDEX(AccessMethodStrategyIndexId);
22262242
LOAD_CRIT_INDEX(AccessMethodProcedureIndexId);
22272243
LOAD_CRIT_INDEX(OperatorOidIndexId);
2244+
LOAD_CRIT_INDEX(RewriteRelRulenameIndexId);
2245+
LOAD_CRIT_INDEX(TriggerRelidNameIndexId);
22282246

2229-
#define NUM_CRITICAL_INDEXES 6 /* fix if you change list above */
2247+
#define NUM_CRITICAL_INDEXES 8 /* fix if you change list above */
22302248

22312249
criticalRelcachesBuilt = true;
22322250
}

0 commit comments

Comments
 (0)