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{
566566Form_pg_rewrite rewrite_form = (Form_pg_rewrite )GETSTRUCT (rewrite_tuple );
567567bool 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 ;
572571RewriteRule * rule ;
573572
574573rule = (RewriteRule * )MemoryContextAlloc (rulescxt ,
@@ -580,31 +579,41 @@ RelationBuildRuleLock(Relation relation)
580579rule -> attrno = rewrite_form -> ev_attr ;
581580rule -> 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 ,
586589Anum_pg_rewrite_ev_action ,
587590rewrite_tupdesc ,
588591& isnull );
589592Assert (!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 )));
592596oldcxt = MemoryContextSwitchTo (rulescxt );
593- rule -> actions = (List * )stringToNode (ruleaction_str );
597+ rule -> actions = (List * )stringToNode (rule_str );
594598MemoryContextSwitchTo (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 );
601607Assert (!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 )));
604611oldcxt = MemoryContextSwitchTo (rulescxt );
605- rule -> qual = (Node * )stringToNode (rule_evqual_str );
612+ rule -> qual = (Node * )stringToNode (rule_str );
606613MemoryContextSwitchTo (oldcxt );
607- pfree (rule_evqual_str );
614+ pfree (rule_str );
615+ if ((Pointer )rule_text != DatumGetPointer (rule_datum ))
616+ pfree (rule_text );
608617
609618if (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 */
22112227if (!criticalRelcachesBuilt )
22122228{
@@ -2225,8 +2241,10 @@ RelationCacheInitializePhase2(void)
22252241LOAD_CRIT_INDEX (AccessMethodStrategyIndexId );
22262242LOAD_CRIT_INDEX (AccessMethodProcedureIndexId );
22272243LOAD_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
22312249criticalRelcachesBuilt = true;
22322250}