8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -565,10 +565,9 @@ RelationBuildRuleLock(Relation relation)
565
565
{
566
566
Form_pg_rewrite rewrite_form = (Form_pg_rewrite ) GETSTRUCT (rewrite_tuple );
567
567
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 ;
572
571
RewriteRule * rule ;
573
572
574
573
rule = (RewriteRule * ) MemoryContextAlloc (rulescxt ,
@@ -580,31 +579,41 @@ RelationBuildRuleLock(Relation relation)
580
579
rule -> attrno = rewrite_form -> ev_attr ;
581
580
rule -> isInstead = rewrite_form -> is_instead ;
582
581
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 ,
586
589
Anum_pg_rewrite_ev_action ,
587
590
rewrite_tupdesc ,
588
591
& isnull );
589
592
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 )));
592
596
oldcxt = MemoryContextSwitchTo (rulescxt );
593
- rule -> actions = (List * ) stringToNode (ruleaction_str );
597
+ rule -> actions = (List * ) stringToNode (rule_str );
594
598
MemoryContextSwitchTo (oldcxt );
595
- pfree (ruleaction_str );
599
+ pfree (rule_str );
600
+ if ((Pointer ) rule_text != DatumGetPointer (rule_datum ))
601
+ pfree (rule_text );
596
602
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 );
601
607
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 )));
604
611
oldcxt = MemoryContextSwitchTo (rulescxt );
605
- rule -> qual = (Node * ) stringToNode (rule_evqual_str );
612
+ rule -> qual = (Node * ) stringToNode (rule_str );
606
613
MemoryContextSwitchTo (oldcxt );
607
- pfree (rule_evqual_str );
614
+ pfree (rule_str );
615
+ if ((Pointer ) rule_text != DatumGetPointer (rule_datum ))
616
+ pfree (rule_text );
608
617
609
618
if (numlocks >= maxlocks )
610
619
{
@@ -2207,6 +2216,13 @@ RelationCacheInitializePhase2(void)
2207
2216
* true. (NOTE: perhaps it would be possible to reload them by
2208
2217
* temporarily setting criticalRelcachesBuilt to false again. For now,
2209
2218
* 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.
2210
2226
*/
2211
2227
if (!criticalRelcachesBuilt )
2212
2228
{
@@ -2225,8 +2241,10 @@ RelationCacheInitializePhase2(void)
2225
2241
LOAD_CRIT_INDEX (AccessMethodStrategyIndexId );
2226
2242
LOAD_CRIT_INDEX (AccessMethodProcedureIndexId );
2227
2243
LOAD_CRIT_INDEX (OperatorOidIndexId );
2244
+ LOAD_CRIT_INDEX (RewriteRelRulenameIndexId );
2245
+ LOAD_CRIT_INDEX (TriggerRelidNameIndexId );
2228
2246
2229
- #define NUM_CRITICAL_INDEXES 6 /* fix if you change list above */
2247
+ #define NUM_CRITICAL_INDEXES 8 /* fix if you change list above */
2230
2248
2231
2249
criticalRelcachesBuilt = true;
2232
2250
}
0 commit comments