OSDN Git Service

Make all command-line options of postmaster and postgres the same. See
[pg-rex/syncrep.git] / src / backend / utils / cache / relcache.c
1 /*-------------------------------------------------------------------------
2  *
3  * relcache.c
4  *        POSTGRES relation descriptor cache code
5  *
6  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.234 2006/01/05 10:07:46 petere Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * INTERFACE ROUTINES
17  *              RelationCacheInitialize                 - initialize relcache
18  *              RelationCacheInitializePhase2   - finish initializing relcache
19  *              RelationIdGetRelation                   - get a reldesc by relation id
20  *              RelationIdCacheGetRelation              - get a cached reldesc by relid
21  *              RelationClose                                   - close an open relation
22  *
23  * NOTES
24  *              The following code contains many undocumented hacks.  Please be
25  *              careful....
26  */
27 #include "postgres.h"
28
29 #include <sys/file.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32
33 #include "access/genam.h"
34 #include "access/heapam.h"
35 #include "catalog/catalog.h"
36 #include "catalog/indexing.h"
37 #include "catalog/namespace.h"
38 #include "catalog/pg_amop.h"
39 #include "catalog/pg_amproc.h"
40 #include "catalog/pg_attrdef.h"
41 #include "catalog/pg_attribute.h"
42 #include "catalog/pg_authid.h"
43 #include "catalog/pg_constraint.h"
44 #include "catalog/pg_index.h"
45 #include "catalog/pg_namespace.h"
46 #include "catalog/pg_opclass.h"
47 #include "catalog/pg_proc.h"
48 #include "catalog/pg_rewrite.h"
49 #include "catalog/pg_type.h"
50 #include "commands/trigger.h"
51 #include "miscadmin.h"
52 #include "optimizer/clauses.h"
53 #include "optimizer/planmain.h"
54 #include "optimizer/prep.h"
55 #include "storage/fd.h"
56 #include "storage/smgr.h"
57 #include "utils/builtins.h"
58 #include "utils/catcache.h"
59 #include "utils/fmgroids.h"
60 #include "utils/inval.h"
61 #include "utils/lsyscache.h"
62 #include "utils/memutils.h"
63 #include "utils/relcache.h"
64 #include "utils/resowner.h"
65 #include "utils/syscache.h"
66 #include "utils/typcache.h"
67
68
69 /*
70  * name of relcache init file, used to speed up backend startup
71  */
72 #define RELCACHE_INIT_FILENAME  "pg_internal.init"
73
74 #define RELCACHE_INIT_FILEMAGIC         0x573262        /* version ID value */
75
76 /*
77  *              hardcoded tuple descriptors.  see include/catalog/pg_attribute.h
78  */
79 static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
80 static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
81 static FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
82 static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
83 static FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
84
85 /*
86  *              Hash tables that index the relation cache
87  *
88  *              We used to index the cache by both name and OID, but now there
89  *              is only an index by OID.
90  */
91 typedef struct relidcacheent
92 {
93         Oid                     reloid;
94         Relation        reldesc;
95 } RelIdCacheEnt;
96
97 static HTAB *RelationIdCache;
98
99 /*
100  * This flag is false until we have prepared the critical relcache entries
101  * that are needed to do indexscans on the tables read by relcache building.
102  */
103 bool            criticalRelcachesBuilt = false;
104
105 /*
106  * This flag is set if we discover that we need to write a new relcache
107  * cache file at the end of startup.
108  */
109 static bool needNewCacheFile = false;
110
111 /*
112  * This counter counts relcache inval events received since backend startup
113  * (but only for rels that are actually in cache).      Presently, we use it only
114  * to detect whether data about to be written by write_relcache_init_file()
115  * might already be obsolete.
116  */
117 static long relcacheInvalsReceived = 0L;
118
119 /*
120  * This list remembers the OIDs of the relations cached in the relcache
121  * init file.
122  */
123 static List *initFileRelationIds = NIL;
124
125 /*
126  * This flag lets us optimize away work in AtEO(Sub)Xact_RelationCache().
127  */
128 static bool need_eoxact_work = false;
129
130
131 /*
132  *              macros to manipulate the lookup hashtables
133  */
134 #define RelationCacheInsert(RELATION)   \
135 do { \
136         RelIdCacheEnt *idhentry; bool found; \
137         idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
138                                                                                    (void *) &(RELATION->rd_id), \
139                                                                                    HASH_ENTER, \
140                                                                                    &found); \
141         /* used to give notice if found -- now just keep quiet */ \
142         idhentry->reldesc = RELATION; \
143 } while(0)
144
145 #define RelationIdCacheLookup(ID, RELATION) \
146 do { \
147         RelIdCacheEnt *hentry; \
148         hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
149                                                                                  (void *) &(ID), HASH_FIND,NULL); \
150         if (hentry) \
151                 RELATION = hentry->reldesc; \
152         else \
153                 RELATION = NULL; \
154 } while(0)
155
156 #define RelationCacheDelete(RELATION) \
157 do { \
158         RelIdCacheEnt *idhentry; \
159         idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
160                                                                                    (void *) &(RELATION->rd_id), \
161                                                                                    HASH_REMOVE, NULL); \
162         if (idhentry == NULL) \
163                 elog(WARNING, "trying to delete a rd_id reldesc that does not exist"); \
164 } while(0)
165
166
167 /*
168  * Special cache for opclass-related information
169  *
170  * Note: only default-subtype operators and support procs get cached
171  */
172 typedef struct opclasscacheent
173 {
174         Oid                     opclassoid;             /* lookup key: OID of opclass */
175         bool            valid;                  /* set TRUE after successful fill-in */
176         StrategyNumber numStrats;       /* max # of strategies (from pg_am) */
177         StrategyNumber numSupport;      /* max # of support procs (from pg_am) */
178         Oid                *operatorOids;       /* strategy operators' OIDs */
179         RegProcedure *supportProcs; /* support procs */
180 } OpClassCacheEnt;
181
182 static HTAB *OpClassCache = NULL;
183
184
185 /* non-export function prototypes */
186
187 static void RelationClearRelation(Relation relation, bool rebuild);
188
189 static void RelationReloadClassinfo(Relation relation);
190 static void RelationFlushRelation(Relation relation);
191 static bool load_relcache_init_file(void);
192 static void write_relcache_init_file(void);
193
194 static void formrdesc(const char *relationName, Oid relationReltype,
195                   bool hasoids, int natts, FormData_pg_attribute *att);
196
197 static HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK);
198 static Relation AllocateRelationDesc(Relation relation, Form_pg_class relp);
199 static void RelationBuildTupleDesc(Relation relation);
200 static Relation RelationBuildDesc(Oid targetRelId, Relation oldrelation);
201 static void RelationInitPhysicalAddr(Relation relation);
202 static TupleDesc GetPgIndexDescriptor(void);
203 static void AttrDefaultFetch(Relation relation);
204 static void CheckConstraintFetch(Relation relation);
205 static List *insert_ordered_oid(List *list, Oid datum);
206 static void IndexSupportInitialize(oidvector *indclass,
207                                            Oid *indexOperator,
208                                            RegProcedure *indexSupport,
209                                            StrategyNumber maxStrategyNumber,
210                                            StrategyNumber maxSupportNumber,
211                                            AttrNumber maxAttributeNumber);
212 static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
213                                   StrategyNumber numStrats,
214                                   StrategyNumber numSupport);
215
216
217 /*
218  *              ScanPgRelation
219  *
220  *              this is used by RelationBuildDesc to find a pg_class
221  *              tuple matching targetRelId.
222  *
223  *              NB: the returned tuple has been copied into palloc'd storage
224  *              and must eventually be freed with heap_freetuple.
225  */
226 static HeapTuple
227 ScanPgRelation(Oid targetRelId, bool indexOK)
228 {
229         HeapTuple       pg_class_tuple;
230         Relation        pg_class_desc;
231         SysScanDesc pg_class_scan;
232         ScanKeyData key[1];
233
234         /*
235          * form a scan key
236          */
237         ScanKeyInit(&key[0],
238                                 ObjectIdAttributeNumber,
239                                 BTEqualStrategyNumber, F_OIDEQ,
240                                 ObjectIdGetDatum(targetRelId));
241
242         /*
243          * Open pg_class and fetch a tuple.  Force heap scan if we haven't yet
244          * built the critical relcache entries (this includes initdb and startup
245          * without a pg_internal.init file).  The caller can also force a heap
246          * scan by setting indexOK == false.
247          */
248         pg_class_desc = heap_open(RelationRelationId, AccessShareLock);
249         pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
250                                                                            indexOK && criticalRelcachesBuilt,
251                                                                            SnapshotNow,
252                                                                            1, key);
253
254         pg_class_tuple = systable_getnext(pg_class_scan);
255
256         /*
257          * Must copy tuple before releasing buffer.
258          */
259         if (HeapTupleIsValid(pg_class_tuple))
260                 pg_class_tuple = heap_copytuple(pg_class_tuple);
261
262         /* all done */
263         systable_endscan(pg_class_scan);
264         heap_close(pg_class_desc, AccessShareLock);
265
266         return pg_class_tuple;
267 }
268
269 /*
270  *              AllocateRelationDesc
271  *
272  *              This is used to allocate memory for a new relation descriptor
273  *              and initialize the rd_rel field.
274  *
275  *              If 'relation' is NULL, allocate a new RelationData object.
276  *              If not, reuse the given object (that path is taken only when
277  *              we have to rebuild a relcache entry during RelationClearRelation).
278  */
279 static Relation
280 AllocateRelationDesc(Relation relation, Form_pg_class relp)
281 {
282         MemoryContext oldcxt;
283         Form_pg_class relationForm;
284
285         /* Relcache entries must live in CacheMemoryContext */
286         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
287
288         /*
289          * allocate space for new relation descriptor, if needed
290          */
291         if (relation == NULL)
292                 relation = (Relation) palloc(sizeof(RelationData));
293
294         /*
295          * clear all fields of reldesc
296          */
297         MemSet(relation, 0, sizeof(RelationData));
298         relation->rd_targblock = InvalidBlockNumber;
299
300         /* make sure relation is marked as having no open file yet */
301         relation->rd_smgr = NULL;
302
303         /*
304          * Copy the relation tuple form
305          *
306          * We only allocate space for the fixed fields, ie, CLASS_TUPLE_SIZE.
307          * relacl is NOT stored in the relcache --- there'd be little point in it,
308          * since we don't copy the tuple's nullvalues bitmap and hence wouldn't
309          * know if the value is valid ... bottom line is that relacl *cannot* be
310          * retrieved from the relcache.  Get it from the syscache if you need it.
311          */
312         relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
313
314         memcpy(relationForm, relp, CLASS_TUPLE_SIZE);
315
316         /* initialize relation tuple form */
317         relation->rd_rel = relationForm;
318
319         /* and allocate attribute tuple form storage */
320         relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts,
321                                                                                            relationForm->relhasoids);
322
323         MemoryContextSwitchTo(oldcxt);
324
325         return relation;
326 }
327
328 /*
329  *              RelationBuildTupleDesc
330  *
331  *              Form the relation's tuple descriptor from information in
332  *              the pg_attribute, pg_attrdef & pg_constraint system catalogs.
333  */
334 static void
335 RelationBuildTupleDesc(Relation relation)
336 {
337         HeapTuple       pg_attribute_tuple;
338         Relation        pg_attribute_desc;
339         SysScanDesc pg_attribute_scan;
340         ScanKeyData skey[2];
341         int                     need;
342         TupleConstr *constr;
343         AttrDefault *attrdef = NULL;
344         int                     ndef = 0;
345
346         /* copy some fields from pg_class row to rd_att */
347         relation->rd_att->tdtypeid = relation->rd_rel->reltype;
348         relation->rd_att->tdtypmod = -1;        /* unnecessary, but... */
349         relation->rd_att->tdhasoid = relation->rd_rel->relhasoids;
350
351         constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
352                                                                                                 sizeof(TupleConstr));
353         constr->has_not_null = false;
354
355         /*
356          * Form a scan key that selects only user attributes (attnum > 0).
357          * (Eliminating system attribute rows at the index level is lots faster
358          * than fetching them.)
359          */
360         ScanKeyInit(&skey[0],
361                                 Anum_pg_attribute_attrelid,
362                                 BTEqualStrategyNumber, F_OIDEQ,
363                                 ObjectIdGetDatum(RelationGetRelid(relation)));
364         ScanKeyInit(&skey[1],
365                                 Anum_pg_attribute_attnum,
366                                 BTGreaterStrategyNumber, F_INT2GT,
367                                 Int16GetDatum(0));
368
369         /*
370          * Open pg_attribute and begin a scan.  Force heap scan if we haven't yet
371          * built the critical relcache entries (this includes initdb and startup
372          * without a pg_internal.init file).
373          */
374         pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock);
375         pg_attribute_scan = systable_beginscan(pg_attribute_desc,
376                                                                                    AttributeRelidNumIndexId,
377                                                                                    criticalRelcachesBuilt,
378                                                                                    SnapshotNow,
379                                                                                    2, skey);
380
381         /*
382          * add attribute data to relation->rd_att
383          */
384         need = relation->rd_rel->relnatts;
385
386         while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
387         {
388                 Form_pg_attribute attp;
389
390                 attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
391
392                 if (attp->attnum <= 0 ||
393                         attp->attnum > relation->rd_rel->relnatts)
394                         elog(ERROR, "invalid attribute number %d for %s",
395                                  attp->attnum, RelationGetRelationName(relation));
396
397                 memcpy(relation->rd_att->attrs[attp->attnum - 1],
398                            attp,
399                            ATTRIBUTE_TUPLE_SIZE);
400
401                 /* Update constraint/default info */
402                 if (attp->attnotnull)
403                         constr->has_not_null = true;
404
405                 if (attp->atthasdef)
406                 {
407                         if (attrdef == NULL)
408                                 attrdef = (AttrDefault *)
409                                         MemoryContextAllocZero(CacheMemoryContext,
410                                                                                    relation->rd_rel->relnatts *
411                                                                                    sizeof(AttrDefault));
412                         attrdef[ndef].adnum = attp->attnum;
413                         attrdef[ndef].adbin = NULL;
414                         ndef++;
415                 }
416                 need--;
417                 if (need == 0)
418                         break;
419         }
420
421         /*
422          * end the scan and close the attribute relation
423          */
424         systable_endscan(pg_attribute_scan);
425         heap_close(pg_attribute_desc, AccessShareLock);
426
427         if (need != 0)
428                 elog(ERROR, "catalog is missing %d attribute(s) for relid %u",
429                          need, RelationGetRelid(relation));
430
431         /*
432          * The attcacheoff values we read from pg_attribute should all be -1
433          * ("unknown").  Verify this if assert checking is on.  They will be
434          * computed when and if needed during tuple access.
435          */
436 #ifdef USE_ASSERT_CHECKING
437         {
438                 int                     i;
439
440                 for (i = 0; i < relation->rd_rel->relnatts; i++)
441                         Assert(relation->rd_att->attrs[i]->attcacheoff == -1);
442         }
443 #endif
444
445         /*
446          * However, we can easily set the attcacheoff value for the first
447          * attribute: it must be zero.  This eliminates the need for special cases
448          * for attnum=1 that used to exist in fastgetattr() and index_getattr().
449          */
450         if (relation->rd_rel->relnatts > 0)
451                 relation->rd_att->attrs[0]->attcacheoff = 0;
452
453         /*
454          * Set up constraint/default info
455          */
456         if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
457         {
458                 relation->rd_att->constr = constr;
459
460                 if (ndef > 0)                   /* DEFAULTs */
461                 {
462                         if (ndef < relation->rd_rel->relnatts)
463                                 constr->defval = (AttrDefault *)
464                                         repalloc(attrdef, ndef * sizeof(AttrDefault));
465                         else
466                                 constr->defval = attrdef;
467                         constr->num_defval = ndef;
468                         AttrDefaultFetch(relation);
469                 }
470                 else
471                         constr->num_defval = 0;
472
473                 if (relation->rd_rel->relchecks > 0)    /* CHECKs */
474                 {
475                         constr->num_check = relation->rd_rel->relchecks;
476                         constr->check = (ConstrCheck *)
477                                 MemoryContextAllocZero(CacheMemoryContext,
478                                                                         constr->num_check * sizeof(ConstrCheck));
479                         CheckConstraintFetch(relation);
480                 }
481                 else
482                         constr->num_check = 0;
483         }
484         else
485         {
486                 pfree(constr);
487                 relation->rd_att->constr = NULL;
488         }
489 }
490
491 /*
492  *              RelationBuildRuleLock
493  *
494  *              Form the relation's rewrite rules from information in
495  *              the pg_rewrite system catalog.
496  *
497  * Note: The rule parsetrees are potentially very complex node structures.
498  * To allow these trees to be freed when the relcache entry is flushed,
499  * we make a private memory context to hold the RuleLock information for
500  * each relcache entry that has associated rules.  The context is used
501  * just for rule info, not for any other subsidiary data of the relcache
502  * entry, because that keeps the update logic in RelationClearRelation()
503  * manageable.  The other subsidiary data structures are simple enough
504  * to be easy to free explicitly, anyway.
505  */
506 static void
507 RelationBuildRuleLock(Relation relation)
508 {
509         MemoryContext rulescxt;
510         MemoryContext oldcxt;
511         HeapTuple       rewrite_tuple;
512         Relation        rewrite_desc;
513         TupleDesc       rewrite_tupdesc;
514         SysScanDesc rewrite_scan;
515         ScanKeyData key;
516         RuleLock   *rulelock;
517         int                     numlocks;
518         RewriteRule **rules;
519         int                     maxlocks;
520
521         /*
522          * Make the private context.  Parameters are set on the assumption that
523          * it'll probably not contain much data.
524          */
525         rulescxt = AllocSetContextCreate(CacheMemoryContext,
526                                                                          RelationGetRelationName(relation),
527                                                                          ALLOCSET_SMALL_MINSIZE,
528                                                                          ALLOCSET_SMALL_INITSIZE,
529                                                                          ALLOCSET_SMALL_MAXSIZE);
530         relation->rd_rulescxt = rulescxt;
531
532         /*
533          * allocate an array to hold the rewrite rules (the array is extended if
534          * necessary)
535          */
536         maxlocks = 4;
537         rules = (RewriteRule **)
538                 MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
539         numlocks = 0;
540
541         /*
542          * form a scan key
543          */
544         ScanKeyInit(&key,
545                                 Anum_pg_rewrite_ev_class,
546                                 BTEqualStrategyNumber, F_OIDEQ,
547                                 ObjectIdGetDatum(RelationGetRelid(relation)));
548
549         /*
550          * open pg_rewrite and begin a scan
551          *
552          * Note: since we scan the rules using RewriteRelRulenameIndexId, we will
553          * be reading the rules in name order, except possibly during
554          * emergency-recovery operations (ie, IgnoreSystemIndexes). This in
555          * turn ensures that rules will be fired in name order.
556          */
557         rewrite_desc = heap_open(RewriteRelationId, AccessShareLock);
558         rewrite_tupdesc = RelationGetDescr(rewrite_desc);
559         rewrite_scan = systable_beginscan(rewrite_desc,
560                                                                           RewriteRelRulenameIndexId,
561                                                                           true, SnapshotNow,
562                                                                           1, &key);
563
564         while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan)))
565         {
566                 Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(rewrite_tuple);
567                 bool            isnull;
568                 Datum           ruleaction;
569                 Datum           rule_evqual;
570                 char       *ruleaction_str;
571                 char       *rule_evqual_str;
572                 RewriteRule *rule;
573
574                 rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
575                                                                                                   sizeof(RewriteRule));
576
577                 rule->ruleId = HeapTupleGetOid(rewrite_tuple);
578
579                 rule->event = rewrite_form->ev_type - '0';
580                 rule->attrno = rewrite_form->ev_attr;
581                 rule->isInstead = rewrite_form->is_instead;
582
583                 /* Must use heap_getattr to fetch ev_qual and ev_action */
584
585                 ruleaction = heap_getattr(rewrite_tuple,
586                                                                   Anum_pg_rewrite_ev_action,
587                                                                   rewrite_tupdesc,
588                                                                   &isnull);
589                 Assert(!isnull);
590                 ruleaction_str = DatumGetCString(DirectFunctionCall1(textout,
591                                                                                                                          ruleaction));
592                 oldcxt = MemoryContextSwitchTo(rulescxt);
593                 rule->actions = (List *) stringToNode(ruleaction_str);
594                 MemoryContextSwitchTo(oldcxt);
595                 pfree(ruleaction_str);
596
597                 rule_evqual = heap_getattr(rewrite_tuple,
598                                                                    Anum_pg_rewrite_ev_qual,
599                                                                    rewrite_tupdesc,
600                                                                    &isnull);
601                 Assert(!isnull);
602                 rule_evqual_str = DatumGetCString(DirectFunctionCall1(textout,
603                                                                                                                           rule_evqual));
604                 oldcxt = MemoryContextSwitchTo(rulescxt);
605                 rule->qual = (Node *) stringToNode(rule_evqual_str);
606                 MemoryContextSwitchTo(oldcxt);
607                 pfree(rule_evqual_str);
608
609                 if (numlocks >= maxlocks)
610                 {
611                         maxlocks *= 2;
612                         rules = (RewriteRule **)
613                                 repalloc(rules, sizeof(RewriteRule *) * maxlocks);
614                 }
615                 rules[numlocks++] = rule;
616         }
617
618         /*
619          * end the scan and close the attribute relation
620          */
621         systable_endscan(rewrite_scan);
622         heap_close(rewrite_desc, AccessShareLock);
623
624         /*
625          * form a RuleLock and insert into relation
626          */
627         rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
628         rulelock->numLocks = numlocks;
629         rulelock->rules = rules;
630
631         relation->rd_rules = rulelock;
632 }
633
634 /*
635  *              equalRuleLocks
636  *
637  *              Determine whether two RuleLocks are equivalent
638  *
639  *              Probably this should be in the rules code someplace...
640  */
641 static bool
642 equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
643 {
644         int                     i;
645
646         /*
647          * As of 7.3 we assume the rule ordering is repeatable, because
648          * RelationBuildRuleLock should read 'em in a consistent order.  So just
649          * compare corresponding slots.
650          */
651         if (rlock1 != NULL)
652         {
653                 if (rlock2 == NULL)
654                         return false;
655                 if (rlock1->numLocks != rlock2->numLocks)
656                         return false;
657                 for (i = 0; i < rlock1->numLocks; i++)
658                 {
659                         RewriteRule *rule1 = rlock1->rules[i];
660                         RewriteRule *rule2 = rlock2->rules[i];
661
662                         if (rule1->ruleId != rule2->ruleId)
663                                 return false;
664                         if (rule1->event != rule2->event)
665                                 return false;
666                         if (rule1->attrno != rule2->attrno)
667                                 return false;
668                         if (rule1->isInstead != rule2->isInstead)
669                                 return false;
670                         if (!equal(rule1->qual, rule2->qual))
671                                 return false;
672                         if (!equal(rule1->actions, rule2->actions))
673                                 return false;
674                 }
675         }
676         else if (rlock2 != NULL)
677                 return false;
678         return true;
679 }
680
681
682 /* ----------------------------------
683  *              RelationBuildDesc
684  *
685  *              Build a relation descriptor --- either a new one, or by
686  *              recycling the given old relation object.  The latter case
687  *              supports rebuilding a relcache entry without invalidating
688  *              pointers to it.
689  * --------------------------------
690  */
691 static Relation
692 RelationBuildDesc(Oid targetRelId, Relation oldrelation)
693 {
694         Relation        relation;
695         Oid                     relid;
696         HeapTuple       pg_class_tuple;
697         Form_pg_class relp;
698         MemoryContext oldcxt;
699
700         /*
701          * find the tuple in pg_class corresponding to the given relation id
702          */
703         pg_class_tuple = ScanPgRelation(targetRelId, true);
704
705         /*
706          * if no such tuple exists, return NULL
707          */
708         if (!HeapTupleIsValid(pg_class_tuple))
709                 return NULL;
710
711         /*
712          * get information from the pg_class_tuple
713          */
714         relid = HeapTupleGetOid(pg_class_tuple);
715         relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
716
717         /*
718          * allocate storage for the relation descriptor, and copy pg_class_tuple
719          * to relation->rd_rel.
720          */
721         relation = AllocateRelationDesc(oldrelation, relp);
722
723         /*
724          * now we can free the memory allocated for pg_class_tuple
725          */
726         heap_freetuple(pg_class_tuple);
727
728         /*
729          * initialize the relation's relation id (relation->rd_id)
730          */
731         RelationGetRelid(relation) = relid;
732
733         /*
734          * normal relations are not nailed into the cache; nor can a pre-existing
735          * relation be new.  It could be temp though.  (Actually, it could be new
736          * too, but it's okay to forget that fact if forced to flush the entry.)
737          */
738         relation->rd_refcnt = 0;
739         relation->rd_isnailed = false;
740         relation->rd_createSubid = InvalidSubTransactionId;
741         relation->rd_istemp = isTempNamespace(relation->rd_rel->relnamespace);
742
743         /*
744          * initialize the tuple descriptor (relation->rd_att).
745          */
746         RelationBuildTupleDesc(relation);
747
748         /*
749          * Fetch rules and triggers that affect this relation
750          */
751         if (relation->rd_rel->relhasrules)
752                 RelationBuildRuleLock(relation);
753         else
754         {
755                 relation->rd_rules = NULL;
756                 relation->rd_rulescxt = NULL;
757         }
758
759         if (relation->rd_rel->reltriggers > 0)
760                 RelationBuildTriggers(relation);
761         else
762                 relation->trigdesc = NULL;
763
764         /*
765          * if it's an index, initialize index-related information
766          */
767         if (OidIsValid(relation->rd_rel->relam))
768                 RelationInitIndexAccessInfo(relation);
769
770         /*
771          * initialize the relation lock manager information
772          */
773         RelationInitLockInfo(relation);         /* see lmgr.c */
774
775         /*
776          * initialize physical addressing information for the relation
777          */
778         RelationInitPhysicalAddr(relation);
779
780         /* make sure relation is marked as having no open file yet */
781         relation->rd_smgr = NULL;
782
783         /*
784          * Insert newly created relation into relcache hash tables.
785          */
786         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
787         RelationCacheInsert(relation);
788         MemoryContextSwitchTo(oldcxt);
789
790         /* It's fully valid */
791         relation->rd_isvalid = true;
792
793         return relation;
794 }
795
796 /*
797  * Initialize the physical addressing info (RelFileNode) for a relcache entry
798  */
799 static void
800 RelationInitPhysicalAddr(Relation relation)
801 {
802         if (relation->rd_rel->reltablespace)
803                 relation->rd_node.spcNode = relation->rd_rel->reltablespace;
804         else
805                 relation->rd_node.spcNode = MyDatabaseTableSpace;
806         if (relation->rd_rel->relisshared)
807                 relation->rd_node.dbNode = InvalidOid;
808         else
809                 relation->rd_node.dbNode = MyDatabaseId;
810         relation->rd_node.relNode = relation->rd_rel->relfilenode;
811 }
812
813 /*
814  * Initialize index-access-method support data for an index relation
815  */
816 void
817 RelationInitIndexAccessInfo(Relation relation)
818 {
819         HeapTuple       tuple;
820         Form_pg_am      aform;
821         Datum           indclassDatum;
822         bool            isnull;
823         MemoryContext indexcxt;
824         MemoryContext oldcontext;
825         Oid                *operator;
826         RegProcedure *support;
827         FmgrInfo   *supportinfo;
828         int                     natts;
829         uint16          amstrategies;
830         uint16          amsupport;
831
832         /*
833          * Make a copy of the pg_index entry for the index.  Since pg_index
834          * contains variable-length and possibly-null fields, we have to do this
835          * honestly rather than just treating it as a Form_pg_index struct.
836          */
837         tuple = SearchSysCache(INDEXRELID,
838                                                    ObjectIdGetDatum(RelationGetRelid(relation)),
839                                                    0, 0, 0);
840         if (!HeapTupleIsValid(tuple))
841                 elog(ERROR, "cache lookup failed for index %u",
842                          RelationGetRelid(relation));
843         oldcontext = MemoryContextSwitchTo(CacheMemoryContext);
844         relation->rd_indextuple = heap_copytuple(tuple);
845         relation->rd_index = (Form_pg_index) GETSTRUCT(relation->rd_indextuple);
846         MemoryContextSwitchTo(oldcontext);
847         ReleaseSysCache(tuple);
848
849         /*
850          * indclass cannot be referenced directly through the C struct, because it
851          * is after the variable-width indkey field.  Therefore we extract the
852          * datum the hard way and provide a direct link in the relcache.
853          */
854         indclassDatum = fastgetattr(relation->rd_indextuple,
855                                                                 Anum_pg_index_indclass,
856                                                                 GetPgIndexDescriptor(),
857                                                                 &isnull);
858         Assert(!isnull);
859         relation->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
860
861         /*
862          * Make a copy of the pg_am entry for the index's access method
863          */
864         tuple = SearchSysCache(AMOID,
865                                                    ObjectIdGetDatum(relation->rd_rel->relam),
866                                                    0, 0, 0);
867         if (!HeapTupleIsValid(tuple))
868                 elog(ERROR, "cache lookup failed for access method %u",
869                          relation->rd_rel->relam);
870         aform = (Form_pg_am) MemoryContextAlloc(CacheMemoryContext, sizeof *aform);
871         memcpy(aform, GETSTRUCT(tuple), sizeof *aform);
872         ReleaseSysCache(tuple);
873         relation->rd_am = aform;
874
875         natts = relation->rd_rel->relnatts;
876         if (natts != relation->rd_index->indnatts)
877                 elog(ERROR, "relnatts disagrees with indnatts for index %u",
878                          RelationGetRelid(relation));
879         amstrategies = aform->amstrategies;
880         amsupport = aform->amsupport;
881
882         /*
883          * Make the private context to hold index access info.  The reason we need
884          * a context, and not just a couple of pallocs, is so that we won't leak
885          * any subsidiary info attached to fmgr lookup records.
886          *
887          * Context parameters are set on the assumption that it'll probably not
888          * contain much data.
889          */
890         indexcxt = AllocSetContextCreate(CacheMemoryContext,
891                                                                          RelationGetRelationName(relation),
892                                                                          ALLOCSET_SMALL_MINSIZE,
893                                                                          ALLOCSET_SMALL_INITSIZE,
894                                                                          ALLOCSET_SMALL_MAXSIZE);
895         relation->rd_indexcxt = indexcxt;
896
897         /*
898          * Allocate arrays to hold data
899          */
900         relation->rd_aminfo = (RelationAmInfo *)
901                 MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo));
902
903         if (amstrategies > 0)
904                 operator = (Oid *)
905                         MemoryContextAllocZero(indexcxt,
906                                                                    natts * amstrategies * sizeof(Oid));
907         else
908                 operator = NULL;
909
910         if (amsupport > 0)
911         {
912                 int                     nsupport = natts * amsupport;
913
914                 support = (RegProcedure *)
915                         MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
916                 supportinfo = (FmgrInfo *)
917                         MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
918         }
919         else
920         {
921                 support = NULL;
922                 supportinfo = NULL;
923         }
924
925         relation->rd_operator = operator;
926         relation->rd_support = support;
927         relation->rd_supportinfo = supportinfo;
928
929         /*
930          * Fill the operator and support procedure OID arrays.  (aminfo and
931          * supportinfo are left as zeroes, and are filled on-the-fly when used)
932          */
933         IndexSupportInitialize(relation->rd_indclass,
934                                                    operator, support,
935                                                    amstrategies, amsupport, natts);
936
937         /*
938          * expressions and predicate cache will be filled later
939          */
940         relation->rd_indexprs = NIL;
941         relation->rd_indpred = NIL;
942 }
943
944 /*
945  * IndexSupportInitialize
946  *              Initializes an index's cached opclass information,
947  *              given the index's pg_index.indclass entry.
948  *
949  * Data is returned into *indexOperator and *indexSupport, which are arrays
950  * allocated by the caller.
951  *
952  * The caller also passes maxStrategyNumber, maxSupportNumber, and
953  * maxAttributeNumber, since these indicate the size of the arrays
954  * it has allocated --- but in practice these numbers must always match
955  * those obtainable from the system catalog entries for the index and
956  * access method.
957  */
958 static void
959 IndexSupportInitialize(oidvector *indclass,
960                                            Oid *indexOperator,
961                                            RegProcedure *indexSupport,
962                                            StrategyNumber maxStrategyNumber,
963                                            StrategyNumber maxSupportNumber,
964                                            AttrNumber maxAttributeNumber)
965 {
966         int                     attIndex;
967
968         for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
969         {
970                 OpClassCacheEnt *opcentry;
971
972                 if (!OidIsValid(indclass->values[attIndex]))
973                         elog(ERROR, "bogus pg_index tuple");
974
975                 /* look up the info for this opclass, using a cache */
976                 opcentry = LookupOpclassInfo(indclass->values[attIndex],
977                                                                          maxStrategyNumber,
978                                                                          maxSupportNumber);
979
980                 /* copy cached data into relcache entry */
981                 if (maxStrategyNumber > 0)
982                         memcpy(&indexOperator[attIndex * maxStrategyNumber],
983                                    opcentry->operatorOids,
984                                    maxStrategyNumber * sizeof(Oid));
985                 if (maxSupportNumber > 0)
986                         memcpy(&indexSupport[attIndex * maxSupportNumber],
987                                    opcentry->supportProcs,
988                                    maxSupportNumber * sizeof(RegProcedure));
989         }
990 }
991
992 /*
993  * LookupOpclassInfo
994  *
995  * This routine maintains a per-opclass cache of the information needed
996  * by IndexSupportInitialize().  This is more efficient than relying on
997  * the catalog cache, because we can load all the info about a particular
998  * opclass in a single indexscan of pg_amproc or pg_amop.
999  *
1000  * The information from pg_am about expected range of strategy and support
1001  * numbers is passed in, rather than being looked up, mainly because the
1002  * caller will have it already.
1003  *
1004  * XXX There isn't any provision for flushing the cache.  However, there
1005  * isn't any provision for flushing relcache entries when opclass info
1006  * changes, either :-(
1007  */
1008 static OpClassCacheEnt *
1009 LookupOpclassInfo(Oid operatorClassOid,
1010                                   StrategyNumber numStrats,
1011                                   StrategyNumber numSupport)
1012 {
1013         OpClassCacheEnt *opcentry;
1014         bool            found;
1015         Relation        rel;
1016         SysScanDesc scan;
1017         ScanKeyData skey[2];
1018         HeapTuple       htup;
1019         bool            indexOK;
1020
1021         if (OpClassCache == NULL)
1022         {
1023                 /* First time through: initialize the opclass cache */
1024                 HASHCTL         ctl;
1025
1026                 if (!CacheMemoryContext)
1027                         CreateCacheMemoryContext();
1028
1029                 MemSet(&ctl, 0, sizeof(ctl));
1030                 ctl.keysize = sizeof(Oid);
1031                 ctl.entrysize = sizeof(OpClassCacheEnt);
1032                 ctl.hash = oid_hash;
1033                 OpClassCache = hash_create("Operator class cache", 64,
1034                                                                    &ctl, HASH_ELEM | HASH_FUNCTION);
1035         }
1036
1037         opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
1038                                                                                            (void *) &operatorClassOid,
1039                                                                                            HASH_ENTER, &found);
1040
1041         if (found && opcentry->valid)
1042         {
1043                 /* Already made an entry for it */
1044                 Assert(numStrats == opcentry->numStrats);
1045                 Assert(numSupport == opcentry->numSupport);
1046                 return opcentry;
1047         }
1048
1049         /* Need to fill in new entry */
1050         opcentry->valid = false;        /* until known OK */
1051         opcentry->numStrats = numStrats;
1052         opcentry->numSupport = numSupport;
1053
1054         if (numStrats > 0)
1055                 opcentry->operatorOids = (Oid *)
1056                         MemoryContextAllocZero(CacheMemoryContext,
1057                                                                    numStrats * sizeof(Oid));
1058         else
1059                 opcentry->operatorOids = NULL;
1060
1061         if (numSupport > 0)
1062                 opcentry->supportProcs = (RegProcedure *)
1063                         MemoryContextAllocZero(CacheMemoryContext,
1064                                                                    numSupport * sizeof(RegProcedure));
1065         else
1066                 opcentry->supportProcs = NULL;
1067
1068         /*
1069          * To avoid infinite recursion during startup, force heap scans if we're
1070          * looking up info for the opclasses used by the indexes we would like to
1071          * reference here.
1072          */
1073         indexOK = criticalRelcachesBuilt ||
1074                 (operatorClassOid != OID_BTREE_OPS_OID &&
1075                  operatorClassOid != INT2_BTREE_OPS_OID);
1076
1077         /*
1078          * Scan pg_amop to obtain operators for the opclass.  We only fetch the
1079          * default ones (those with subtype zero).
1080          */
1081         if (numStrats > 0)
1082         {
1083                 ScanKeyInit(&skey[0],
1084                                         Anum_pg_amop_amopclaid,
1085                                         BTEqualStrategyNumber, F_OIDEQ,
1086                                         ObjectIdGetDatum(operatorClassOid));
1087                 ScanKeyInit(&skey[1],
1088                                         Anum_pg_amop_amopsubtype,
1089                                         BTEqualStrategyNumber, F_OIDEQ,
1090                                         ObjectIdGetDatum(InvalidOid));
1091                 rel = heap_open(AccessMethodOperatorRelationId, AccessShareLock);
1092                 scan = systable_beginscan(rel, AccessMethodStrategyIndexId, indexOK,
1093                                                                   SnapshotNow, 2, skey);
1094
1095                 while (HeapTupleIsValid(htup = systable_getnext(scan)))
1096                 {
1097                         Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
1098
1099                         if (amopform->amopstrategy <= 0 ||
1100                                 (StrategyNumber) amopform->amopstrategy > numStrats)
1101                                 elog(ERROR, "invalid amopstrategy number %d for opclass %u",
1102                                          amopform->amopstrategy, operatorClassOid);
1103                         opcentry->operatorOids[amopform->amopstrategy - 1] =
1104                                 amopform->amopopr;
1105                 }
1106
1107                 systable_endscan(scan);
1108                 heap_close(rel, AccessShareLock);
1109         }
1110
1111         /*
1112          * Scan pg_amproc to obtain support procs for the opclass.      We only fetch
1113          * the default ones (those with subtype zero).
1114          */
1115         if (numSupport > 0)
1116         {
1117                 ScanKeyInit(&skey[0],
1118                                         Anum_pg_amproc_amopclaid,
1119                                         BTEqualStrategyNumber, F_OIDEQ,
1120                                         ObjectIdGetDatum(operatorClassOid));
1121                 ScanKeyInit(&skey[1],
1122                                         Anum_pg_amproc_amprocsubtype,
1123                                         BTEqualStrategyNumber, F_OIDEQ,
1124                                         ObjectIdGetDatum(InvalidOid));
1125                 rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock);
1126                 scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK,
1127                                                                   SnapshotNow, 2, skey);
1128
1129                 while (HeapTupleIsValid(htup = systable_getnext(scan)))
1130                 {
1131                         Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
1132
1133                         if (amprocform->amprocnum <= 0 ||
1134                                 (StrategyNumber) amprocform->amprocnum > numSupport)
1135                                 elog(ERROR, "invalid amproc number %d for opclass %u",
1136                                          amprocform->amprocnum, operatorClassOid);
1137
1138                         opcentry->supportProcs[amprocform->amprocnum - 1] =
1139                                 amprocform->amproc;
1140                 }
1141
1142                 systable_endscan(scan);
1143                 heap_close(rel, AccessShareLock);
1144         }
1145
1146         opcentry->valid = true;
1147         return opcentry;
1148 }
1149
1150
1151 /*
1152  *              formrdesc
1153  *
1154  *              This is a special cut-down version of RelationBuildDesc()
1155  *              used by RelationCacheInitialize() in initializing the relcache.
1156  *              The relation descriptor is built just from the supplied parameters,
1157  *              without actually looking at any system table entries.  We cheat
1158  *              quite a lot since we only need to work for a few basic system
1159  *              catalogs.
1160  *
1161  * formrdesc is currently used for: pg_class, pg_attribute, pg_proc,
1162  * and pg_type (see RelationCacheInitialize).
1163  *
1164  * Note that these catalogs can't have constraints (except attnotnull),
1165  * default values, rules, or triggers, since we don't cope with any of that.
1166  *
1167  * NOTE: we assume we are already switched into CacheMemoryContext.
1168  */
1169 static void
1170 formrdesc(const char *relationName, Oid relationReltype,
1171                   bool hasoids, int natts, FormData_pg_attribute *att)
1172 {
1173         Relation        relation;
1174         int                     i;
1175         bool            has_not_null;
1176
1177         /*
1178          * allocate new relation desc, clear all fields of reldesc
1179          */
1180         relation = (Relation) palloc0(sizeof(RelationData));
1181         relation->rd_targblock = InvalidBlockNumber;
1182
1183         /* make sure relation is marked as having no open file yet */
1184         relation->rd_smgr = NULL;
1185
1186         /*
1187          * initialize reference count: 1 because it is nailed in cache
1188          */
1189         relation->rd_refcnt = 1;
1190
1191         /*
1192          * all entries built with this routine are nailed-in-cache; none are for
1193          * new or temp relations.
1194          */
1195         relation->rd_isnailed = true;
1196         relation->rd_createSubid = InvalidSubTransactionId;
1197         relation->rd_istemp = false;
1198
1199         /*
1200          * initialize relation tuple form
1201          *
1202          * The data we insert here is pretty incomplete/bogus, but it'll serve to
1203          * get us launched.  RelationCacheInitializePhase2() will read the real
1204          * data from pg_class and replace what we've done here.
1205          */
1206         relation->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
1207
1208         namestrcpy(&relation->rd_rel->relname, relationName);
1209         relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
1210         relation->rd_rel->reltype = relationReltype;
1211
1212         /*
1213          * It's important to distinguish between shared and non-shared relations,
1214          * even at bootstrap time, to make sure we know where they are stored.  At
1215          * present, all relations that formrdesc is used for are not shared.
1216          */
1217         relation->rd_rel->relisshared = false;
1218
1219         relation->rd_rel->relpages = 1;
1220         relation->rd_rel->reltuples = 1;
1221         relation->rd_rel->relkind = RELKIND_RELATION;
1222         relation->rd_rel->relhasoids = hasoids;
1223         relation->rd_rel->relnatts = (int16) natts;
1224
1225         /*
1226          * initialize attribute tuple form
1227          *
1228          * Unlike the case with the relation tuple, this data had better be right
1229          * because it will never be replaced.  The input values must be correctly
1230          * defined by macros in src/include/catalog/ headers.
1231          */
1232         relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
1233         relation->rd_att->tdtypeid = relationReltype;
1234         relation->rd_att->tdtypmod = -1;        /* unnecessary, but... */
1235
1236         /*
1237          * initialize tuple desc info
1238          */
1239         has_not_null = false;
1240         for (i = 0; i < natts; i++)
1241         {
1242                 memcpy(relation->rd_att->attrs[i],
1243                            &att[i],
1244                            ATTRIBUTE_TUPLE_SIZE);
1245                 has_not_null |= att[i].attnotnull;
1246                 /* make sure attcacheoff is valid */
1247                 relation->rd_att->attrs[i]->attcacheoff = -1;
1248         }
1249
1250         /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
1251         relation->rd_att->attrs[0]->attcacheoff = 0;
1252
1253         /* mark not-null status */
1254         if (has_not_null)
1255         {
1256                 TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
1257
1258                 constr->has_not_null = true;
1259                 relation->rd_att->constr = constr;
1260         }
1261
1262         /*
1263          * initialize relation id from info in att array (my, this is ugly)
1264          */
1265         RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
1266         relation->rd_rel->relfilenode = RelationGetRelid(relation);
1267
1268         /*
1269          * initialize the relation lock manager information
1270          */
1271         RelationInitLockInfo(relation);         /* see lmgr.c */
1272
1273         /*
1274          * initialize physical addressing information for the relation
1275          */
1276         RelationInitPhysicalAddr(relation);
1277
1278         /*
1279          * initialize the rel-has-index flag, using hardwired knowledge
1280          */
1281         if (IsBootstrapProcessingMode())
1282         {
1283                 /* In bootstrap mode, we have no indexes */
1284                 relation->rd_rel->relhasindex = false;
1285         }
1286         else
1287         {
1288                 /* Otherwise, all the rels formrdesc is used for have indexes */
1289                 relation->rd_rel->relhasindex = true;
1290         }
1291
1292         /*
1293          * add new reldesc to relcache
1294          */
1295         RelationCacheInsert(relation);
1296
1297         /* It's fully valid */
1298         relation->rd_isvalid = true;
1299 }
1300
1301
1302 /* ----------------------------------------------------------------
1303  *                               Relation Descriptor Lookup Interface
1304  * ----------------------------------------------------------------
1305  */
1306
1307 /*
1308  *              RelationIdCacheGetRelation
1309  *
1310  *              Lookup an existing reldesc by OID.
1311  *
1312  *              Only try to get the reldesc by looking in the cache,
1313  *              do not go to the disk if it's not present.
1314  *
1315  *              NB: relation ref count is incremented if successful.
1316  *              Caller should eventually decrement count.  (Usually,
1317  *              that happens by calling RelationClose().)
1318  */
1319 Relation
1320 RelationIdCacheGetRelation(Oid relationId)
1321 {
1322         Relation        rd;
1323
1324         RelationIdCacheLookup(relationId, rd);
1325
1326         if (RelationIsValid(rd))
1327         {
1328                 RelationIncrementReferenceCount(rd);
1329                 /* revalidate nailed index if necessary */
1330                 if (!rd->rd_isvalid)
1331                         RelationReloadClassinfo(rd);
1332         }
1333
1334         return rd;
1335 }
1336
1337 /*
1338  *              RelationIdGetRelation
1339  *
1340  *              Lookup a reldesc by OID; make one if not already in cache.
1341  *
1342  *              NB: relation ref count is incremented, or set to 1 if new entry.
1343  *              Caller should eventually decrement count.  (Usually,
1344  *              that happens by calling RelationClose().)
1345  */
1346 Relation
1347 RelationIdGetRelation(Oid relationId)
1348 {
1349         Relation        rd;
1350
1351         /*
1352          * first try and get a reldesc from the cache
1353          */
1354         rd = RelationIdCacheGetRelation(relationId);
1355         if (RelationIsValid(rd))
1356                 return rd;
1357
1358         /*
1359          * no reldesc in the cache, so have RelationBuildDesc() build one and add
1360          * it.
1361          */
1362         rd = RelationBuildDesc(relationId, NULL);
1363         if (RelationIsValid(rd))
1364                 RelationIncrementReferenceCount(rd);
1365         return rd;
1366 }
1367
1368 /* ----------------------------------------------------------------
1369  *                              cache invalidation support routines
1370  * ----------------------------------------------------------------
1371  */
1372
1373 /*
1374  * RelationIncrementReferenceCount
1375  *              Increments relation reference count.
1376  *
1377  * Note: bootstrap mode has its own weird ideas about relation refcount
1378  * behavior; we ought to fix it someday, but for now, just disable
1379  * reference count ownership tracking in bootstrap mode.
1380  */
1381 void
1382 RelationIncrementReferenceCount(Relation rel)
1383 {
1384         ResourceOwnerEnlargeRelationRefs(CurrentResourceOwner);
1385         rel->rd_refcnt += 1;
1386         if (!IsBootstrapProcessingMode())
1387                 ResourceOwnerRememberRelationRef(CurrentResourceOwner, rel);
1388 }
1389
1390 /*
1391  * RelationDecrementReferenceCount
1392  *              Decrements relation reference count.
1393  */
1394 void
1395 RelationDecrementReferenceCount(Relation rel)
1396 {
1397         Assert(rel->rd_refcnt > 0);
1398         rel->rd_refcnt -= 1;
1399         if (!IsBootstrapProcessingMode())
1400                 ResourceOwnerForgetRelationRef(CurrentResourceOwner, rel);
1401 }
1402
1403 /*
1404  * RelationClose - close an open relation
1405  *
1406  *      Actually, we just decrement the refcount.
1407  *
1408  *      NOTE: if compiled with -DRELCACHE_FORCE_RELEASE then relcache entries
1409  *      will be freed as soon as their refcount goes to zero.  In combination
1410  *      with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
1411  *      to catch references to already-released relcache entries.  It slows
1412  *      things down quite a bit, however.
1413  */
1414 void
1415 RelationClose(Relation relation)
1416 {
1417         /* Note: no locking manipulations needed */
1418         RelationDecrementReferenceCount(relation);
1419
1420 #ifdef RELCACHE_FORCE_RELEASE
1421         if (RelationHasReferenceCountZero(relation) &&
1422                 relation->rd_createSubid == InvalidSubTransactionId)
1423                 RelationClearRelation(relation, false);
1424 #endif
1425 }
1426
1427 /*
1428  * RelationReloadClassinfo - reload the pg_class row (only)
1429  *
1430  *      This function is used only for nailed indexes.  Since a REINDEX can
1431  *      change the relfilenode value for a nailed index, we have to reread
1432  *      the pg_class row anytime we get an SI invalidation on a nailed index
1433  *      (without throwing away the whole relcache entry, since we'd be unable
1434  *      to rebuild it).
1435  *
1436  *      We can't necessarily reread the pg_class row right away; we might be
1437  *      in a failed transaction when we receive the SI notification.  If so,
1438  *      RelationClearRelation just marks the entry as invalid by setting
1439  *      rd_isvalid to false.  This routine is called to fix the entry when it
1440  *      is next needed.
1441  */
1442 static void
1443 RelationReloadClassinfo(Relation relation)
1444 {
1445         bool            indexOK;
1446         HeapTuple       pg_class_tuple;
1447         Form_pg_class relp;
1448
1449         /* Should be called only for invalidated nailed indexes */
1450         Assert(relation->rd_isnailed && !relation->rd_isvalid &&
1451                    relation->rd_rel->relkind == RELKIND_INDEX);
1452
1453         /*
1454          * Read the pg_class row
1455          *
1456          * Don't try to use an indexscan of pg_class_oid_index to reload the info
1457          * for pg_class_oid_index ...
1458          */
1459         indexOK = (RelationGetRelid(relation) != ClassOidIndexId);
1460         pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), indexOK);
1461         if (!HeapTupleIsValid(pg_class_tuple))
1462                 elog(ERROR, "could not find tuple for system relation %u",
1463                          RelationGetRelid(relation));
1464         relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
1465         memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
1466         /* Now we can recalculate physical address */
1467         RelationInitPhysicalAddr(relation);
1468         heap_freetuple(pg_class_tuple);
1469         relation->rd_targblock = InvalidBlockNumber;
1470         /* Okay, now it's valid again */
1471         relation->rd_isvalid = true;
1472 }
1473
1474 /*
1475  * RelationClearRelation
1476  *
1477  *       Physically blow away a relation cache entry, or reset it and rebuild
1478  *       it from scratch (that is, from catalog entries).  The latter path is
1479  *       usually used when we are notified of a change to an open relation
1480  *       (one with refcount > 0).  However, this routine just does whichever
1481  *       it's told to do; callers must determine which they want.
1482  */
1483 static void
1484 RelationClearRelation(Relation relation, bool rebuild)
1485 {
1486         Oid                     old_reltype = relation->rd_rel->reltype;
1487         MemoryContext oldcxt;
1488
1489         /*
1490          * Make sure smgr and lower levels close the relation's files, if they
1491          * weren't closed already.  If the relation is not getting deleted, the
1492          * next smgr access should reopen the files automatically.      This ensures
1493          * that the low-level file access state is updated after, say, a vacuum
1494          * truncation.
1495          */
1496         RelationCloseSmgr(relation);
1497
1498         /*
1499          * Never, never ever blow away a nailed-in system relation, because we'd
1500          * be unable to recover.  However, we must reset rd_targblock, in case we
1501          * got called because of a relation cache flush that was triggered by
1502          * VACUUM.
1503          *
1504          * If it's a nailed index, then we need to re-read the pg_class row to see
1505          * if its relfilenode changed.  We can't necessarily do that here, because
1506          * we might be in a failed transaction.  We assume it's okay to do it if
1507          * there are open references to the relcache entry (cf notes for
1508          * AtEOXact_RelationCache).  Otherwise just mark the entry as possibly
1509          * invalid, and it'll be fixed when next opened.
1510          */
1511         if (relation->rd_isnailed)
1512         {
1513                 relation->rd_targblock = InvalidBlockNumber;
1514                 if (relation->rd_rel->relkind == RELKIND_INDEX)
1515                 {
1516                         relation->rd_isvalid = false;           /* needs to be revalidated */
1517                         if (relation->rd_refcnt > 1)
1518                                 RelationReloadClassinfo(relation);
1519                 }
1520                 return;
1521         }
1522
1523         /*
1524          * Remove relation from hash tables
1525          *
1526          * Note: we might be reinserting it momentarily, but we must not have it
1527          * visible in the hash tables until it's valid again, so don't try to
1528          * optimize this away...
1529          */
1530         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
1531         RelationCacheDelete(relation);
1532         MemoryContextSwitchTo(oldcxt);
1533
1534         /* Clear out catcache's entries for this relation */
1535         CatalogCacheFlushRelation(RelationGetRelid(relation));
1536
1537         /*
1538          * Free all the subsidiary data structures of the relcache entry. We
1539          * cannot free rd_att if we are trying to rebuild the entry, however,
1540          * because pointers to it may be cached in various places. The rule
1541          * manager might also have pointers into the rewrite rules. So to begin
1542          * with, we can only get rid of these fields:
1543          */
1544         FreeTriggerDesc(relation->trigdesc);
1545         if (relation->rd_indextuple)
1546                 pfree(relation->rd_indextuple);
1547         if (relation->rd_am)
1548                 pfree(relation->rd_am);
1549         if (relation->rd_rel)
1550                 pfree(relation->rd_rel);
1551         list_free(relation->rd_indexlist);
1552         if (relation->rd_indexcxt)
1553                 MemoryContextDelete(relation->rd_indexcxt);
1554
1555         /*
1556          * If we're really done with the relcache entry, blow it away. But if
1557          * someone is still using it, reconstruct the whole deal without moving
1558          * the physical RelationData record (so that the someone's pointer is
1559          * still valid).
1560          */
1561         if (!rebuild)
1562         {
1563                 /* ok to zap remaining substructure */
1564                 flush_rowtype_cache(old_reltype);
1565                 FreeTupleDesc(relation->rd_att);
1566                 if (relation->rd_rulescxt)
1567                         MemoryContextDelete(relation->rd_rulescxt);
1568                 pfree(relation);
1569         }
1570         else
1571         {
1572                 /*
1573                  * When rebuilding an open relcache entry, must preserve ref count and
1574                  * rd_createSubid state.  Also attempt to preserve the tupledesc and
1575                  * rewrite-rule substructures in place.
1576                  *
1577                  * Note that this process does not touch CurrentResourceOwner; which
1578                  * is good because whatever ref counts the entry may have do not
1579                  * necessarily belong to that resource owner.
1580                  */
1581                 Oid                     save_relid = RelationGetRelid(relation);
1582                 int                     old_refcnt = relation->rd_refcnt;
1583                 SubTransactionId old_createSubid = relation->rd_createSubid;
1584                 TupleDesc       old_att = relation->rd_att;
1585                 RuleLock   *old_rules = relation->rd_rules;
1586                 MemoryContext old_rulescxt = relation->rd_rulescxt;
1587
1588                 if (RelationBuildDesc(save_relid, relation) != relation)
1589                 {
1590                         /* Should only get here if relation was deleted */
1591                         flush_rowtype_cache(old_reltype);
1592                         FreeTupleDesc(old_att);
1593                         if (old_rulescxt)
1594                                 MemoryContextDelete(old_rulescxt);
1595                         pfree(relation);
1596                         elog(ERROR, "relation %u deleted while still in use", save_relid);
1597                 }
1598                 relation->rd_refcnt = old_refcnt;
1599                 relation->rd_createSubid = old_createSubid;
1600                 if (equalTupleDescs(old_att, relation->rd_att))
1601                 {
1602                         /* needn't flush typcache here */
1603                         FreeTupleDesc(relation->rd_att);
1604                         relation->rd_att = old_att;
1605                 }
1606                 else
1607                 {
1608                         flush_rowtype_cache(old_reltype);
1609                         FreeTupleDesc(old_att);
1610                 }
1611                 if (equalRuleLocks(old_rules, relation->rd_rules))
1612                 {
1613                         if (relation->rd_rulescxt)
1614                                 MemoryContextDelete(relation->rd_rulescxt);
1615                         relation->rd_rules = old_rules;
1616                         relation->rd_rulescxt = old_rulescxt;
1617                 }
1618                 else
1619                 {
1620                         if (old_rulescxt)
1621                                 MemoryContextDelete(old_rulescxt);
1622                 }
1623         }
1624 }
1625
1626 /*
1627  * RelationFlushRelation
1628  *
1629  *       Rebuild the relation if it is open (refcount > 0), else blow it away.
1630  */
1631 static void
1632 RelationFlushRelation(Relation relation)
1633 {
1634         bool            rebuild;
1635
1636         if (relation->rd_createSubid != InvalidSubTransactionId)
1637         {
1638                 /*
1639                  * New relcache entries are always rebuilt, not flushed; else we'd
1640                  * forget the "new" status of the relation, which is a useful
1641                  * optimization to have.
1642                  */
1643                 rebuild = true;
1644         }
1645         else
1646         {
1647                 /*
1648                  * Pre-existing rels can be dropped from the relcache if not open.
1649                  */
1650                 rebuild = !RelationHasReferenceCountZero(relation);
1651         }
1652
1653         RelationClearRelation(relation, rebuild);
1654 }
1655
1656 /*
1657  * RelationForgetRelation - unconditionally remove a relcache entry
1658  *
1659  *                 External interface for destroying a relcache entry when we
1660  *                 drop the relation.
1661  */
1662 void
1663 RelationForgetRelation(Oid rid)
1664 {
1665         Relation        relation;
1666
1667         RelationIdCacheLookup(rid, relation);
1668
1669         if (!PointerIsValid(relation))
1670                 return;                                 /* not in cache, nothing to do */
1671
1672         if (!RelationHasReferenceCountZero(relation))
1673                 elog(ERROR, "relation %u is still open", rid);
1674
1675         /* Unconditionally destroy the relcache entry */
1676         RelationClearRelation(relation, false);
1677 }
1678
1679 /*
1680  *              RelationCacheInvalidateEntry
1681  *
1682  *              This routine is invoked for SI cache flush messages.
1683  *
1684  * Any relcache entry matching the relid must be flushed.  (Note: caller has
1685  * already determined that the relid belongs to our database or is a shared
1686  * relation.)
1687  *
1688  * We used to skip local relations, on the grounds that they could
1689  * not be targets of cross-backend SI update messages; but it seems
1690  * safer to process them, so that our *own* SI update messages will
1691  * have the same effects during CommandCounterIncrement for both
1692  * local and nonlocal relations.
1693  */
1694 void
1695 RelationCacheInvalidateEntry(Oid relationId)
1696 {
1697         Relation        relation;
1698
1699         RelationIdCacheLookup(relationId, relation);
1700
1701         if (PointerIsValid(relation))
1702         {
1703                 relcacheInvalsReceived++;
1704                 RelationFlushRelation(relation);
1705         }
1706 }
1707
1708 /*
1709  * RelationCacheInvalidate
1710  *       Blow away cached relation descriptors that have zero reference counts,
1711  *       and rebuild those with positive reference counts.      Also reset the smgr
1712  *       relation cache.
1713  *
1714  *       This is currently used only to recover from SI message buffer overflow,
1715  *       so we do not touch new-in-transaction relations; they cannot be targets
1716  *       of cross-backend SI updates (and our own updates now go through a
1717  *       separate linked list that isn't limited by the SI message buffer size).
1718  *
1719  *       We do this in two phases: the first pass deletes deletable items, and
1720  *       the second one rebuilds the rebuildable items.  This is essential for
1721  *       safety, because hash_seq_search only copes with concurrent deletion of
1722  *       the element it is currently visiting.  If a second SI overflow were to
1723  *       occur while we are walking the table, resulting in recursive entry to
1724  *       this routine, we could crash because the inner invocation blows away
1725  *       the entry next to be visited by the outer scan.  But this way is OK,
1726  *       because (a) during the first pass we won't process any more SI messages,
1727  *       so hash_seq_search will complete safely; (b) during the second pass we
1728  *       only hold onto pointers to nondeletable entries.
1729  *
1730  *       The two-phase approach also makes it easy to ensure that we process
1731  *       nailed-in-cache indexes before other nondeletable items, and that we
1732  *       process pg_class_oid_index first of all.  In scenarios where a nailed
1733  *       index has been given a new relfilenode, we have to detect that update
1734  *       before the nailed index is used in reloading any other relcache entry.
1735  */
1736 void
1737 RelationCacheInvalidate(void)
1738 {
1739         HASH_SEQ_STATUS status;
1740         RelIdCacheEnt *idhentry;
1741         Relation        relation;
1742         List       *rebuildFirstList = NIL;
1743         List       *rebuildList = NIL;
1744         ListCell   *l;
1745
1746         /* Phase 1 */
1747         hash_seq_init(&status, RelationIdCache);
1748
1749         while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1750         {
1751                 relation = idhentry->reldesc;
1752
1753                 /* Must close all smgr references to avoid leaving dangling ptrs */
1754                 RelationCloseSmgr(relation);
1755
1756                 /* Ignore new relations, since they are never SI targets */
1757                 if (relation->rd_createSubid != InvalidSubTransactionId)
1758                         continue;
1759
1760                 relcacheInvalsReceived++;
1761
1762                 if (RelationHasReferenceCountZero(relation))
1763                 {
1764                         /* Delete this entry immediately */
1765                         Assert(!relation->rd_isnailed);
1766                         RelationClearRelation(relation, false);
1767                 }
1768                 else
1769                 {
1770                         /*
1771                          * Add this entry to list of stuff to rebuild in second pass.
1772                          * pg_class_oid_index goes on the front of rebuildFirstList, other
1773                          * nailed indexes on the back, and everything else into
1774                          * rebuildList (in no particular order).
1775                          */
1776                         if (relation->rd_isnailed &&
1777                                 relation->rd_rel->relkind == RELKIND_INDEX)
1778                         {
1779                                 if (RelationGetRelid(relation) == ClassOidIndexId)
1780                                         rebuildFirstList = lcons(relation, rebuildFirstList);
1781                                 else
1782                                         rebuildFirstList = lappend(rebuildFirstList, relation);
1783                         }
1784                         else
1785                                 rebuildList = lcons(relation, rebuildList);
1786                 }
1787         }
1788
1789         rebuildList = list_concat(rebuildFirstList, rebuildList);
1790
1791         /*
1792          * Now zap any remaining smgr cache entries.  This must happen before we
1793          * start to rebuild entries, since that may involve catalog fetches which
1794          * will re-open catalog files.
1795          */
1796         smgrcloseall();
1797
1798         /* Phase 2: rebuild the items found to need rebuild in phase 1 */
1799         foreach(l, rebuildList)
1800         {
1801                 relation = (Relation) lfirst(l);
1802                 RelationClearRelation(relation, true);
1803         }
1804         list_free(rebuildList);
1805 }
1806
1807 /*
1808  * AtEOXact_RelationCache
1809  *
1810  *      Clean up the relcache at main-transaction commit or abort.
1811  *
1812  * Note: this must be called *before* processing invalidation messages.
1813  * In the case of abort, we don't want to try to rebuild any invalidated
1814  * cache entries (since we can't safely do database accesses).  Therefore
1815  * we must reset refcnts before handling pending invalidations.
1816  *
1817  * As of PostgreSQL 8.1, relcache refcnts should get released by the
1818  * ResourceOwner mechanism.  This routine just does a debugging
1819  * cross-check that no pins remain.  However, we also need to do special
1820  * cleanup when the current transaction created any relations or made use
1821  * of forced index lists.
1822  */
1823 void
1824 AtEOXact_RelationCache(bool isCommit)
1825 {
1826         HASH_SEQ_STATUS status;
1827         RelIdCacheEnt *idhentry;
1828
1829         /*
1830          * To speed up transaction exit, we want to avoid scanning the relcache
1831          * unless there is actually something for this routine to do.  Other than
1832          * the debug-only Assert checks, most transactions don't create any work
1833          * for us to do here, so we keep a static flag that gets set if there is
1834          * anything to do.      (Currently, this means either a relation is created in
1835          * the current xact, or an index list is forced.)  For simplicity, the
1836          * flag remains set till end of top-level transaction, even though we
1837          * could clear it at subtransaction end in some cases.
1838          */
1839         if (!need_eoxact_work
1840 #ifdef USE_ASSERT_CHECKING
1841                 && !assert_enabled
1842 #endif
1843                 )
1844                 return;
1845
1846         hash_seq_init(&status, RelationIdCache);
1847
1848         while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1849         {
1850                 Relation        relation = idhentry->reldesc;
1851
1852                 /*
1853                  * The relcache entry's ref count should be back to its normal
1854                  * not-in-a-transaction state: 0 unless it's nailed in cache.
1855                  *
1856                  * In bootstrap mode, this is NOT true, so don't check it --- the
1857                  * bootstrap code expects relations to stay open across start/commit
1858                  * transaction calls.  (That seems bogus, but it's not worth fixing.)
1859                  */
1860 #ifdef USE_ASSERT_CHECKING
1861                 if (!IsBootstrapProcessingMode())
1862                 {
1863                         int                     expected_refcnt;
1864
1865                         expected_refcnt = relation->rd_isnailed ? 1 : 0;
1866                         Assert(relation->rd_refcnt == expected_refcnt);
1867                 }
1868 #endif
1869
1870                 /*
1871                  * Is it a relation created in the current transaction?
1872                  *
1873                  * During commit, reset the flag to zero, since we are now out of the
1874                  * creating transaction.  During abort, simply delete the relcache
1875                  * entry --- it isn't interesting any longer.  (NOTE: if we have
1876                  * forgotten the new-ness of a new relation due to a forced cache
1877                  * flush, the entry will get deleted anyway by shared-cache-inval
1878                  * processing of the aborted pg_class insertion.)
1879                  */
1880                 if (relation->rd_createSubid != InvalidSubTransactionId)
1881                 {
1882                         if (isCommit)
1883                                 relation->rd_createSubid = InvalidSubTransactionId;
1884                         else
1885                         {
1886                                 RelationClearRelation(relation, false);
1887                                 continue;
1888                         }
1889                 }
1890
1891                 /*
1892                  * Flush any temporary index list.
1893                  */
1894                 if (relation->rd_indexvalid == 2)
1895                 {
1896                         list_free(relation->rd_indexlist);
1897                         relation->rd_indexlist = NIL;
1898                         relation->rd_oidindex = InvalidOid;
1899                         relation->rd_indexvalid = 0;
1900                 }
1901         }
1902
1903         /* Once done with the transaction, we can reset need_eoxact_work */
1904         need_eoxact_work = false;
1905 }
1906
1907 /*
1908  * AtEOSubXact_RelationCache
1909  *
1910  *      Clean up the relcache at sub-transaction commit or abort.
1911  *
1912  * Note: this must be called *before* processing invalidation messages.
1913  */
1914 void
1915 AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
1916                                                   SubTransactionId parentSubid)
1917 {
1918         HASH_SEQ_STATUS status;
1919         RelIdCacheEnt *idhentry;
1920
1921         /*
1922          * Skip the relcache scan if nothing to do --- see notes for
1923          * AtEOXact_RelationCache.
1924          */
1925         if (!need_eoxact_work)
1926                 return;
1927
1928         hash_seq_init(&status, RelationIdCache);
1929
1930         while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1931         {
1932                 Relation        relation = idhentry->reldesc;
1933
1934                 /*
1935                  * Is it a relation created in the current subtransaction?
1936                  *
1937                  * During subcommit, mark it as belonging to the parent, instead.
1938                  * During subabort, simply delete the relcache entry.
1939                  */
1940                 if (relation->rd_createSubid == mySubid)
1941                 {
1942                         if (isCommit)
1943                                 relation->rd_createSubid = parentSubid;
1944                         else
1945                         {
1946                                 Assert(RelationHasReferenceCountZero(relation));
1947                                 RelationClearRelation(relation, false);
1948                                 continue;
1949                         }
1950                 }
1951
1952                 /*
1953                  * Flush any temporary index list.
1954                  */
1955                 if (relation->rd_indexvalid == 2)
1956                 {
1957                         list_free(relation->rd_indexlist);
1958                         relation->rd_indexlist = NIL;
1959                         relation->rd_oidindex = InvalidOid;
1960                         relation->rd_indexvalid = 0;
1961                 }
1962         }
1963 }
1964
1965 /*
1966  *              RelationBuildLocalRelation
1967  *                      Build a relcache entry for an about-to-be-created relation,
1968  *                      and enter it into the relcache.
1969  */
1970 Relation
1971 RelationBuildLocalRelation(const char *relname,
1972                                                    Oid relnamespace,
1973                                                    TupleDesc tupDesc,
1974                                                    Oid relid,
1975                                                    Oid reltablespace,
1976                                                    bool shared_relation)
1977 {
1978         Relation        rel;
1979         MemoryContext oldcxt;
1980         int                     natts = tupDesc->natts;
1981         int                     i;
1982         bool            has_not_null;
1983         bool            nailit;
1984
1985         AssertArg(natts >= 0);
1986
1987         /*
1988          * check for creation of a rel that must be nailed in cache.
1989          *
1990          * XXX this list had better match RelationCacheInitialize's list.
1991          */
1992         switch (relid)
1993         {
1994                 case RelationRelationId:
1995                 case AttributeRelationId:
1996                 case ProcedureRelationId:
1997                 case TypeRelationId:
1998                         nailit = true;
1999                         break;
2000                 default:
2001                         nailit = false;
2002                         break;
2003         }
2004
2005         /*
2006          * switch to the cache context to create the relcache entry.
2007          */
2008         if (!CacheMemoryContext)
2009                 CreateCacheMemoryContext();
2010
2011         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2012
2013         /*
2014          * allocate a new relation descriptor and fill in basic state fields.
2015          */
2016         rel = (Relation) palloc0(sizeof(RelationData));
2017
2018         rel->rd_targblock = InvalidBlockNumber;
2019
2020         /* make sure relation is marked as having no open file yet */
2021         rel->rd_smgr = NULL;
2022
2023         /* mark it nailed if appropriate */
2024         rel->rd_isnailed = nailit;
2025
2026         rel->rd_refcnt = nailit ? 1 : 0;
2027
2028         /* it's being created in this transaction */
2029         rel->rd_createSubid = GetCurrentSubTransactionId();
2030
2031         /* must flag that we have rels created in this transaction */
2032         need_eoxact_work = true;
2033
2034         /* is it a temporary relation? */
2035         rel->rd_istemp = isTempNamespace(relnamespace);
2036
2037         /*
2038          * create a new tuple descriptor from the one passed in.  We do this
2039          * partly to copy it into the cache context, and partly because the new
2040          * relation can't have any defaults or constraints yet; they have to be
2041          * added in later steps, because they require additions to multiple system
2042          * catalogs.  We can copy attnotnull constraints here, however.
2043          */
2044         rel->rd_att = CreateTupleDescCopy(tupDesc);
2045         has_not_null = false;
2046         for (i = 0; i < natts; i++)
2047         {
2048                 rel->rd_att->attrs[i]->attnotnull = tupDesc->attrs[i]->attnotnull;
2049                 has_not_null |= tupDesc->attrs[i]->attnotnull;
2050         }
2051
2052         if (has_not_null)
2053         {
2054                 TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
2055
2056                 constr->has_not_null = true;
2057                 rel->rd_att->constr = constr;
2058         }
2059
2060         /*
2061          * initialize relation tuple form (caller may add/override data later)
2062          */
2063         rel->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
2064
2065         namestrcpy(&rel->rd_rel->relname, relname);
2066         rel->rd_rel->relnamespace = relnamespace;
2067
2068         rel->rd_rel->relkind = RELKIND_UNCATALOGED;
2069         rel->rd_rel->relhasoids = rel->rd_att->tdhasoid;
2070         rel->rd_rel->relnatts = natts;
2071         rel->rd_rel->reltype = InvalidOid;
2072         /* needed when bootstrapping: */
2073         rel->rd_rel->relowner = BOOTSTRAP_SUPERUSERID;
2074
2075         /*
2076          * Insert relation physical and logical identifiers (OIDs) into the right
2077          * places.      Note that the physical ID (relfilenode) is initially the same
2078          * as the logical ID (OID).
2079          */
2080         rel->rd_rel->relisshared = shared_relation;
2081
2082         RelationGetRelid(rel) = relid;
2083
2084         for (i = 0; i < natts; i++)
2085                 rel->rd_att->attrs[i]->attrelid = relid;
2086
2087         rel->rd_rel->relfilenode = relid;
2088         rel->rd_rel->reltablespace = reltablespace;
2089
2090         RelationInitLockInfo(rel);      /* see lmgr.c */
2091
2092         RelationInitPhysicalAddr(rel);
2093
2094         /*
2095          * Okay to insert into the relcache hash tables.
2096          */
2097         RelationCacheInsert(rel);
2098
2099         /*
2100          * done building relcache entry.
2101          */
2102         MemoryContextSwitchTo(oldcxt);
2103
2104         /* It's fully valid */
2105         rel->rd_isvalid = true;
2106
2107         /*
2108          * Caller expects us to pin the returned entry.
2109          */
2110         RelationIncrementReferenceCount(rel);
2111
2112         return rel;
2113 }
2114
2115 /*
2116  *              RelationCacheInitialize
2117  *
2118  *              This initializes the relation descriptor cache.  At the time
2119  *              that this is invoked, we can't do database access yet (mainly
2120  *              because the transaction subsystem is not up), so we can't get
2121  *              "real" info.  However it's okay to read the pg_internal.init
2122  *              cache file, if one is available.  Otherwise we make phony
2123  *              entries for the minimum set of nailed-in-cache relations.
2124  */
2125
2126 #define INITRELCACHESIZE                400
2127
2128 void
2129 RelationCacheInitialize(void)
2130 {
2131         MemoryContext oldcxt;
2132         HASHCTL         ctl;
2133
2134         /*
2135          * switch to cache memory context
2136          */
2137         if (!CacheMemoryContext)
2138                 CreateCacheMemoryContext();
2139
2140         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2141
2142         /*
2143          * create hashtables that index the relcache
2144          */
2145         MemSet(&ctl, 0, sizeof(ctl));
2146         ctl.keysize = sizeof(Oid);
2147         ctl.entrysize = sizeof(RelIdCacheEnt);
2148         ctl.hash = oid_hash;
2149         RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE,
2150                                                                   &ctl, HASH_ELEM | HASH_FUNCTION);
2151
2152         /*
2153          * Try to load the relcache cache file.  If successful, we're done for
2154          * now.  Otherwise, initialize the cache with pre-made descriptors for the
2155          * critical "nailed-in" system catalogs.
2156          */
2157         if (IsBootstrapProcessingMode() ||
2158                 !load_relcache_init_file())
2159         {
2160                 formrdesc("pg_class", PG_CLASS_RELTYPE_OID,
2161                                   true, Natts_pg_class, Desc_pg_class);
2162                 formrdesc("pg_attribute", PG_ATTRIBUTE_RELTYPE_OID,
2163                                   false, Natts_pg_attribute, Desc_pg_attribute);
2164                 formrdesc("pg_proc", PG_PROC_RELTYPE_OID,
2165                                   true, Natts_pg_proc, Desc_pg_proc);
2166                 formrdesc("pg_type", PG_TYPE_RELTYPE_OID,
2167                                   true, Natts_pg_type, Desc_pg_type);
2168
2169 #define NUM_CRITICAL_RELS       4       /* fix if you change list above */
2170         }
2171
2172         MemoryContextSwitchTo(oldcxt);
2173 }
2174
2175 /*
2176  *              RelationCacheInitializePhase2
2177  *
2178  *              This is called as soon as the catcache and transaction system
2179  *              are functional.  At this point we can actually read data from
2180  *              the system catalogs.  Update the relcache entries made during
2181  *              RelationCacheInitialize, and make sure we have entries for the
2182  *              critical system indexes.
2183  */
2184 void
2185 RelationCacheInitializePhase2(void)
2186 {
2187         HASH_SEQ_STATUS status;
2188         RelIdCacheEnt *idhentry;
2189
2190         if (IsBootstrapProcessingMode())
2191                 return;
2192
2193         /*
2194          * If we didn't get the critical system indexes loaded into relcache, do
2195          * so now.      These are critical because the catcache depends on them for
2196          * catcache fetches that are done during relcache load.  Thus, we have an
2197          * infinite-recursion problem.  We can break the recursion by doing
2198          * heapscans instead of indexscans at certain key spots. To avoid hobbling
2199          * performance, we only want to do that until we have the critical indexes
2200          * loaded into relcache.  Thus, the flag criticalRelcachesBuilt is used to
2201          * decide whether to do heapscan or indexscan at the key spots, and we set
2202          * it true after we've loaded the critical indexes.
2203          *
2204          * The critical indexes are marked as "nailed in cache", partly to make it
2205          * easy for load_relcache_init_file to count them, but mainly because we
2206          * cannot flush and rebuild them once we've set criticalRelcachesBuilt to
2207          * true.  (NOTE: perhaps it would be possible to reload them by
2208          * temporarily setting criticalRelcachesBuilt to false again.  For now,
2209          * though, we just nail 'em in.)
2210          */
2211         if (!criticalRelcachesBuilt)
2212         {
2213                 Relation        ird;
2214
2215 #define LOAD_CRIT_INDEX(indexoid) \
2216                 do { \
2217                         ird = RelationBuildDesc((indexoid), NULL); \
2218                         ird->rd_isnailed = true; \
2219                         ird->rd_refcnt = 1; \
2220                 } while (0)
2221
2222                 LOAD_CRIT_INDEX(ClassOidIndexId);
2223                 LOAD_CRIT_INDEX(AttributeRelidNumIndexId);
2224                 LOAD_CRIT_INDEX(IndexRelidIndexId);
2225                 LOAD_CRIT_INDEX(AccessMethodStrategyIndexId);
2226                 LOAD_CRIT_INDEX(AccessMethodProcedureIndexId);
2227                 LOAD_CRIT_INDEX(OperatorOidIndexId);
2228
2229 #define NUM_CRITICAL_INDEXES    6               /* fix if you change list above */
2230
2231                 criticalRelcachesBuilt = true;
2232         }
2233
2234         /*
2235          * Now, scan all the relcache entries and update anything that might be
2236          * wrong in the results from formrdesc or the relcache cache file. If we
2237          * faked up relcache entries using formrdesc, then read the real pg_class
2238          * rows and replace the fake entries with them. Also, if any of the
2239          * relcache entries have rules or triggers, load that info the hard way
2240          * since it isn't recorded in the cache file.
2241          */
2242         hash_seq_init(&status, RelationIdCache);
2243
2244         while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
2245         {
2246                 Relation        relation = idhentry->reldesc;
2247
2248                 /*
2249                  * If it's a faked-up entry, read the real pg_class tuple.
2250                  */
2251                 if (needNewCacheFile && relation->rd_isnailed)
2252                 {
2253                         HeapTuple       htup;
2254                         Form_pg_class relp;
2255
2256                         htup = SearchSysCache(RELOID,
2257                                                                 ObjectIdGetDatum(RelationGetRelid(relation)),
2258                                                                   0, 0, 0);
2259                         if (!HeapTupleIsValid(htup))
2260                                 elog(FATAL, "cache lookup failed for relation %u",
2261                                          RelationGetRelid(relation));
2262                         relp = (Form_pg_class) GETSTRUCT(htup);
2263
2264                         /*
2265                          * Copy tuple to relation->rd_rel. (See notes in
2266                          * AllocateRelationDesc())
2267                          */
2268                         Assert(relation->rd_rel != NULL);
2269                         memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
2270
2271                         /*
2272                          * Also update the derived fields in rd_att.
2273                          */
2274                         relation->rd_att->tdtypeid = relp->reltype;
2275                         relation->rd_att->tdtypmod = -1;        /* unnecessary, but... */
2276                         relation->rd_att->tdhasoid = relp->relhasoids;
2277
2278                         ReleaseSysCache(htup);
2279                 }
2280
2281                 /*
2282                  * Fix data that isn't saved in relcache cache file.
2283                  */
2284                 if (relation->rd_rel->relhasrules && relation->rd_rules == NULL)
2285                         RelationBuildRuleLock(relation);
2286                 if (relation->rd_rel->reltriggers > 0 && relation->trigdesc == NULL)
2287                         RelationBuildTriggers(relation);
2288         }
2289 }
2290
2291 /*
2292  *              RelationCacheInitializePhase3
2293  *
2294  *              Final step of relcache initialization: write out a new relcache
2295  *              cache file if one is needed.
2296  */
2297 void
2298 RelationCacheInitializePhase3(void)
2299 {
2300         if (IsBootstrapProcessingMode())
2301                 return;
2302
2303         if (needNewCacheFile)
2304         {
2305                 /*
2306                  * Force all the catcaches to finish initializing and thereby open the
2307                  * catalogs and indexes they use.  This will preload the relcache with
2308                  * entries for all the most important system catalogs and indexes, so
2309                  * that the init file will be most useful for future backends.
2310                  */
2311                 InitCatalogCachePhase2();
2312
2313                 /* now write the file */
2314                 write_relcache_init_file();
2315         }
2316 }
2317
2318 /*
2319  * GetPgIndexDescriptor -- get a predefined tuple descriptor for pg_index
2320  *
2321  * We need this kluge because we have to be able to access non-fixed-width
2322  * fields of pg_index before we have the standard catalog caches available.
2323  * We use predefined data that's set up in just the same way as the
2324  * bootstrapped reldescs used by formrdesc().  The resulting tupdesc is
2325  * not 100% kosher: it does not have the correct rowtype OID in tdtypeid,
2326  * nor does it have a TupleConstr field.  But it's good enough for the
2327  * purpose of extracting fields.
2328  */
2329 static TupleDesc
2330 GetPgIndexDescriptor(void)
2331 {
2332         static TupleDesc pgindexdesc = NULL;
2333         MemoryContext oldcxt;
2334         int                     i;
2335
2336         /* Already done? */
2337         if (pgindexdesc)
2338                 return pgindexdesc;
2339
2340         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2341
2342         pgindexdesc = CreateTemplateTupleDesc(Natts_pg_index, false);
2343         pgindexdesc->tdtypeid = RECORDOID;      /* not right, but we don't care */
2344         pgindexdesc->tdtypmod = -1;
2345
2346         for (i = 0; i < Natts_pg_index; i++)
2347         {
2348                 memcpy(pgindexdesc->attrs[i],
2349                            &Desc_pg_index[i],
2350                            ATTRIBUTE_TUPLE_SIZE);
2351                 /* make sure attcacheoff is valid */
2352                 pgindexdesc->attrs[i]->attcacheoff = -1;
2353         }
2354
2355         /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
2356         pgindexdesc->attrs[0]->attcacheoff = 0;
2357
2358         /* Note: we don't bother to set up a TupleConstr entry */
2359
2360         MemoryContextSwitchTo(oldcxt);
2361
2362         return pgindexdesc;
2363 }
2364
2365 static void
2366 AttrDefaultFetch(Relation relation)
2367 {
2368         AttrDefault *attrdef = relation->rd_att->constr->defval;
2369         int                     ndef = relation->rd_att->constr->num_defval;
2370         Relation        adrel;
2371         SysScanDesc adscan;
2372         ScanKeyData skey;
2373         HeapTuple       htup;
2374         Datum           val;
2375         bool            isnull;
2376         int                     found;
2377         int                     i;
2378
2379         ScanKeyInit(&skey,
2380                                 Anum_pg_attrdef_adrelid,
2381                                 BTEqualStrategyNumber, F_OIDEQ,
2382                                 ObjectIdGetDatum(RelationGetRelid(relation)));
2383
2384         adrel = heap_open(AttrDefaultRelationId, AccessShareLock);
2385         adscan = systable_beginscan(adrel, AttrDefaultIndexId, true,
2386                                                                 SnapshotNow, 1, &skey);
2387         found = 0;
2388
2389         while (HeapTupleIsValid(htup = systable_getnext(adscan)))
2390         {
2391                 Form_pg_attrdef adform = (Form_pg_attrdef) GETSTRUCT(htup);
2392
2393                 for (i = 0; i < ndef; i++)
2394                 {
2395                         if (adform->adnum != attrdef[i].adnum)
2396                                 continue;
2397                         if (attrdef[i].adbin != NULL)
2398                                 elog(WARNING, "multiple attrdef records found for attr %s of rel %s",
2399                                 NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname),
2400                                          RelationGetRelationName(relation));
2401                         else
2402                                 found++;
2403
2404                         val = fastgetattr(htup,
2405                                                           Anum_pg_attrdef_adbin,
2406                                                           adrel->rd_att, &isnull);
2407                         if (isnull)
2408                                 elog(WARNING, "null adbin for attr %s of rel %s",
2409                                 NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname),
2410                                          RelationGetRelationName(relation));
2411                         else
2412                                 attrdef[i].adbin = MemoryContextStrdup(CacheMemoryContext,
2413                                                                  DatumGetCString(DirectFunctionCall1(textout,
2414                                                                                                                                          val)));
2415                         break;
2416                 }
2417
2418                 if (i >= ndef)
2419                         elog(WARNING, "unexpected attrdef record found for attr %d of rel %s",
2420                                  adform->adnum, RelationGetRelationName(relation));
2421         }
2422
2423         systable_endscan(adscan);
2424         heap_close(adrel, AccessShareLock);
2425
2426         if (found != ndef)
2427                 elog(WARNING, "%d attrdef record(s) missing for rel %s",
2428                          ndef - found, RelationGetRelationName(relation));
2429 }
2430
2431 static void
2432 CheckConstraintFetch(Relation relation)
2433 {
2434         ConstrCheck *check = relation->rd_att->constr->check;
2435         int                     ncheck = relation->rd_att->constr->num_check;
2436         Relation        conrel;
2437         SysScanDesc conscan;
2438         ScanKeyData skey[1];
2439         HeapTuple       htup;
2440         Datum           val;
2441         bool            isnull;
2442         int                     found = 0;
2443
2444         ScanKeyInit(&skey[0],
2445                                 Anum_pg_constraint_conrelid,
2446                                 BTEqualStrategyNumber, F_OIDEQ,
2447                                 ObjectIdGetDatum(RelationGetRelid(relation)));
2448
2449         conrel = heap_open(ConstraintRelationId, AccessShareLock);
2450         conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true,
2451                                                                  SnapshotNow, 1, skey);
2452
2453         while (HeapTupleIsValid(htup = systable_getnext(conscan)))
2454         {
2455                 Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup);
2456
2457                 /* We want check constraints only */
2458                 if (conform->contype != CONSTRAINT_CHECK)
2459                         continue;
2460
2461                 if (found >= ncheck)
2462                         elog(ERROR, "unexpected constraint record found for rel %s",
2463                                  RelationGetRelationName(relation));
2464
2465                 check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
2466                                                                                                   NameStr(conform->conname));
2467
2468                 /* Grab and test conbin is actually set */
2469                 val = fastgetattr(htup,
2470                                                   Anum_pg_constraint_conbin,
2471                                                   conrel->rd_att, &isnull);
2472                 if (isnull)
2473                         elog(ERROR, "null conbin for rel %s",
2474                                  RelationGetRelationName(relation));
2475
2476                 check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
2477                                                                  DatumGetCString(DirectFunctionCall1(textout,
2478                                                                                                                                          val)));
2479                 found++;
2480         }
2481
2482         systable_endscan(conscan);
2483         heap_close(conrel, AccessShareLock);
2484
2485         if (found != ncheck)
2486                 elog(ERROR, "%d constraint record(s) missing for rel %s",
2487                          ncheck - found, RelationGetRelationName(relation));
2488 }
2489
2490 /*
2491  * RelationGetIndexList -- get a list of OIDs of indexes on this relation
2492  *
2493  * The index list is created only if someone requests it.  We scan pg_index
2494  * to find relevant indexes, and add the list to the relcache entry so that
2495  * we won't have to compute it again.  Note that shared cache inval of a
2496  * relcache entry will delete the old list and set rd_indexvalid to 0,
2497  * so that we must recompute the index list on next request.  This handles
2498  * creation or deletion of an index.
2499  *
2500  * The returned list is guaranteed to be sorted in order by OID.  This is
2501  * needed by the executor, since for index types that we obtain exclusive
2502  * locks on when updating the index, all backends must lock the indexes in
2503  * the same order or we will get deadlocks (see ExecOpenIndices()).  Any
2504  * consistent ordering would do, but ordering by OID is easy.
2505  *
2506  * Since shared cache inval causes the relcache's copy of the list to go away,
2507  * we return a copy of the list palloc'd in the caller's context.  The caller
2508  * may list_free() the returned list after scanning it. This is necessary
2509  * since the caller will typically be doing syscache lookups on the relevant
2510  * indexes, and syscache lookup could cause SI messages to be processed!
2511  *
2512  * We also update rd_oidindex, which this module treats as effectively part
2513  * of the index list.  rd_oidindex is valid when rd_indexvalid isn't zero;
2514  * it is the pg_class OID of a unique index on OID when the relation has one,
2515  * and InvalidOid if there is no such index.
2516  */
2517 List *
2518 RelationGetIndexList(Relation relation)
2519 {
2520         Relation        indrel;
2521         SysScanDesc indscan;
2522         ScanKeyData skey;
2523         HeapTuple       htup;
2524         List       *result;
2525         Oid                     oidIndex;
2526         MemoryContext oldcxt;
2527
2528         /* Quick exit if we already computed the list. */
2529         if (relation->rd_indexvalid != 0)
2530                 return list_copy(relation->rd_indexlist);
2531
2532         /*
2533          * We build the list we intend to return (in the caller's context) while
2534          * doing the scan.      After successfully completing the scan, we copy that
2535          * list into the relcache entry.  This avoids cache-context memory leakage
2536          * if we get some sort of error partway through.
2537          */
2538         result = NIL;
2539         oidIndex = InvalidOid;
2540
2541         /* Prepare to scan pg_index for entries having indrelid = this rel. */
2542         ScanKeyInit(&skey,
2543                                 Anum_pg_index_indrelid,
2544                                 BTEqualStrategyNumber, F_OIDEQ,
2545                                 ObjectIdGetDatum(RelationGetRelid(relation)));
2546
2547         indrel = heap_open(IndexRelationId, AccessShareLock);
2548         indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true,
2549                                                                  SnapshotNow, 1, &skey);
2550
2551         while (HeapTupleIsValid(htup = systable_getnext(indscan)))
2552         {
2553                 Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
2554
2555                 /* Add index's OID to result list in the proper order */
2556                 result = insert_ordered_oid(result, index->indexrelid);
2557
2558                 /* Check to see if it is a unique, non-partial btree index on OID */
2559                 if (index->indnatts == 1 &&
2560                         index->indisunique &&
2561                         index->indkey.values[0] == ObjectIdAttributeNumber &&
2562                         index->indclass.values[0] == OID_BTREE_OPS_OID &&
2563                         heap_attisnull(htup, Anum_pg_index_indpred))
2564                         oidIndex = index->indexrelid;
2565         }
2566
2567         systable_endscan(indscan);
2568         heap_close(indrel, AccessShareLock);
2569
2570         /* Now save a copy of the completed list in the relcache entry. */
2571         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2572         relation->rd_indexlist = list_copy(result);
2573         relation->rd_oidindex = oidIndex;
2574         relation->rd_indexvalid = 1;
2575         MemoryContextSwitchTo(oldcxt);
2576
2577         return result;
2578 }
2579
2580 /*
2581  * insert_ordered_oid
2582  *              Insert a new Oid into a sorted list of Oids, preserving ordering
2583  *
2584  * Building the ordered list this way is O(N^2), but with a pretty small
2585  * constant, so for the number of entries we expect it will probably be
2586  * faster than trying to apply qsort().  Most tables don't have very many
2587  * indexes...
2588  */
2589 static List *
2590 insert_ordered_oid(List *list, Oid datum)
2591 {
2592         ListCell   *prev;
2593
2594         /* Does the datum belong at the front? */
2595         if (list == NIL || datum < linitial_oid(list))
2596                 return lcons_oid(datum, list);
2597         /* No, so find the entry it belongs after */
2598         prev = list_head(list);
2599         for (;;)
2600         {
2601                 ListCell   *curr = lnext(prev);
2602
2603                 if (curr == NULL || datum < lfirst_oid(curr))
2604                         break;                          /* it belongs after 'prev', before 'curr' */
2605
2606                 prev = curr;
2607         }
2608         /* Insert datum into list after 'prev' */
2609         lappend_cell_oid(list, prev, datum);
2610         return list;
2611 }
2612
2613 /*
2614  * RelationSetIndexList -- externally force the index list contents
2615  *
2616  * This is used to temporarily override what we think the set of valid
2617  * indexes is (including the presence or absence of an OID index).
2618  * The forcing will be valid only until transaction commit or abort.
2619  *
2620  * This should only be applied to nailed relations, because in a non-nailed
2621  * relation the hacked index list could be lost at any time due to SI
2622  * messages.  In practice it is only used on pg_class (see REINDEX).
2623  *
2624  * It is up to the caller to make sure the given list is correctly ordered.
2625  */
2626 void
2627 RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
2628 {
2629         MemoryContext oldcxt;
2630
2631         Assert(relation->rd_isnailed);
2632         /* Copy the list into the cache context (could fail for lack of mem) */
2633         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2634         indexIds = list_copy(indexIds);
2635         MemoryContextSwitchTo(oldcxt);
2636         /* Okay to replace old list */
2637         list_free(relation->rd_indexlist);
2638         relation->rd_indexlist = indexIds;
2639         relation->rd_oidindex = oidIndex;
2640         relation->rd_indexvalid = 2;    /* mark list as forced */
2641         /* must flag that we have a forced index list */
2642         need_eoxact_work = true;
2643 }
2644
2645 /*
2646  * RelationGetOidIndex -- get the pg_class OID of the relation's OID index
2647  *
2648  * Returns InvalidOid if there is no such index.
2649  */
2650 Oid
2651 RelationGetOidIndex(Relation relation)
2652 {
2653         List       *ilist;
2654
2655         /*
2656          * If relation doesn't have OIDs at all, caller is probably confused. (We
2657          * could just silently return InvalidOid, but it seems better to throw an
2658          * assertion.)
2659          */
2660         Assert(relation->rd_rel->relhasoids);
2661
2662         if (relation->rd_indexvalid == 0)
2663         {
2664                 /* RelationGetIndexList does the heavy lifting. */
2665                 ilist = RelationGetIndexList(relation);
2666                 list_free(ilist);
2667                 Assert(relation->rd_indexvalid != 0);
2668         }
2669
2670         return relation->rd_oidindex;
2671 }
2672
2673 /*
2674  * RelationGetIndexExpressions -- get the index expressions for an index
2675  *
2676  * We cache the result of transforming pg_index.indexprs into a node tree.
2677  * If the rel is not an index or has no expressional columns, we return NIL.
2678  * Otherwise, the returned tree is copied into the caller's memory context.
2679  * (We don't want to return a pointer to the relcache copy, since it could
2680  * disappear due to relcache invalidation.)
2681  */
2682 List *
2683 RelationGetIndexExpressions(Relation relation)
2684 {
2685         List       *result;
2686         Datum           exprsDatum;
2687         bool            isnull;
2688         char       *exprsString;
2689         MemoryContext oldcxt;
2690
2691         /* Quick exit if we already computed the result. */
2692         if (relation->rd_indexprs)
2693                 return (List *) copyObject(relation->rd_indexprs);
2694
2695         /* Quick exit if there is nothing to do. */
2696         if (relation->rd_indextuple == NULL ||
2697                 heap_attisnull(relation->rd_indextuple, Anum_pg_index_indexprs))
2698                 return NIL;
2699
2700         /*
2701          * We build the tree we intend to return in the caller's context. After
2702          * successfully completing the work, we copy it into the relcache entry.
2703          * This avoids problems if we get some sort of error partway through.
2704          */
2705         exprsDatum = heap_getattr(relation->rd_indextuple,
2706                                                           Anum_pg_index_indexprs,
2707                                                           GetPgIndexDescriptor(),
2708                                                           &isnull);
2709         Assert(!isnull);
2710         exprsString = DatumGetCString(DirectFunctionCall1(textout, exprsDatum));
2711         result = (List *) stringToNode(exprsString);
2712         pfree(exprsString);
2713
2714         /*
2715          * Run the expressions through eval_const_expressions. This is not just an
2716          * optimization, but is necessary, because the planner will be comparing
2717          * them to similarly-processed qual clauses, and may fail to detect valid
2718          * matches without this.  We don't bother with canonicalize_qual, however.
2719          */
2720         result = (List *) eval_const_expressions((Node *) result);
2721
2722         /*
2723          * Also mark any coercion format fields as "don't care", so that the
2724          * planner can match to both explicit and implicit coercions.
2725          */
2726         set_coercionform_dontcare((Node *) result);
2727
2728         /* May as well fix opfuncids too */
2729         fix_opfuncids((Node *) result);
2730
2731         /* Now save a copy of the completed tree in the relcache entry. */
2732         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2733         relation->rd_indexprs = (List *) copyObject(result);
2734         MemoryContextSwitchTo(oldcxt);
2735
2736         return result;
2737 }
2738
2739 /*
2740  * RelationGetIndexPredicate -- get the index predicate for an index
2741  *
2742  * We cache the result of transforming pg_index.indpred into an implicit-AND
2743  * node tree (suitable for ExecQual).
2744  * If the rel is not an index or has no predicate, we return NIL.
2745  * Otherwise, the returned tree is copied into the caller's memory context.
2746  * (We don't want to return a pointer to the relcache copy, since it could
2747  * disappear due to relcache invalidation.)
2748  */
2749 List *
2750 RelationGetIndexPredicate(Relation relation)
2751 {
2752         List       *result;
2753         Datum           predDatum;
2754         bool            isnull;
2755         char       *predString;
2756         MemoryContext oldcxt;
2757
2758         /* Quick exit if we already computed the result. */
2759         if (relation->rd_indpred)
2760                 return (List *) copyObject(relation->rd_indpred);
2761
2762         /* Quick exit if there is nothing to do. */
2763         if (relation->rd_indextuple == NULL ||
2764                 heap_attisnull(relation->rd_indextuple, Anum_pg_index_indpred))
2765                 return NIL;
2766
2767         /*
2768          * We build the tree we intend to return in the caller's context. After
2769          * successfully completing the work, we copy it into the relcache entry.
2770          * This avoids problems if we get some sort of error partway through.
2771          */
2772         predDatum = heap_getattr(relation->rd_indextuple,
2773                                                          Anum_pg_index_indpred,
2774                                                          GetPgIndexDescriptor(),
2775                                                          &isnull);
2776         Assert(!isnull);
2777         predString = DatumGetCString(DirectFunctionCall1(textout, predDatum));
2778         result = (List *) stringToNode(predString);
2779         pfree(predString);
2780
2781         /*
2782          * Run the expression through const-simplification and canonicalization.
2783          * This is not just an optimization, but is necessary, because the planner
2784          * will be comparing it to similarly-processed qual clauses, and may fail
2785          * to detect valid matches without this.  This must match the processing
2786          * done to qual clauses in preprocess_expression()!  (We can skip the
2787          * stuff involving subqueries, however, since we don't allow any in index
2788          * predicates.)
2789          */
2790         result = (List *) eval_const_expressions((Node *) result);
2791
2792         result = (List *) canonicalize_qual((Expr *) result);
2793
2794         /*
2795          * Also mark any coercion format fields as "don't care", so that the
2796          * planner can match to both explicit and implicit coercions.
2797          */
2798         set_coercionform_dontcare((Node *) result);
2799
2800         /* Also convert to implicit-AND format */
2801         result = make_ands_implicit((Expr *) result);
2802
2803         /* May as well fix opfuncids too */
2804         fix_opfuncids((Node *) result);
2805
2806         /* Now save a copy of the completed tree in the relcache entry. */
2807         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2808         relation->rd_indpred = (List *) copyObject(result);
2809         MemoryContextSwitchTo(oldcxt);
2810
2811         return result;
2812 }
2813
2814
2815 /*
2816  *      load_relcache_init_file, write_relcache_init_file
2817  *
2818  *              In late 1992, we started regularly having databases with more than
2819  *              a thousand classes in them.  With this number of classes, it became
2820  *              critical to do indexed lookups on the system catalogs.
2821  *
2822  *              Bootstrapping these lookups is very hard.  We want to be able to
2823  *              use an index on pg_attribute, for example, but in order to do so,
2824  *              we must have read pg_attribute for the attributes in the index,
2825  *              which implies that we need to use the index.
2826  *
2827  *              In order to get around the problem, we do the following:
2828  *
2829  *                 +  When the database system is initialized (at initdb time), we
2830  *                        don't use indexes.  We do sequential scans.
2831  *
2832  *                 +  When the backend is started up in normal mode, we load an image
2833  *                        of the appropriate relation descriptors, in internal format,
2834  *                        from an initialization file in the data/base/... directory.
2835  *
2836  *                 +  If the initialization file isn't there, then we create the
2837  *                        relation descriptors using sequential scans and write 'em to
2838  *                        the initialization file for use by subsequent backends.
2839  *
2840  *              We could dispense with the initialization file and just build the
2841  *              critical reldescs the hard way on every backend startup, but that
2842  *              slows down backend startup noticeably.
2843  *
2844  *              We can in fact go further, and save more relcache entries than
2845  *              just the ones that are absolutely critical; this allows us to speed
2846  *              up backend startup by not having to build such entries the hard way.
2847  *              Presently, all the catalog and index entries that are referred to
2848  *              by catcaches are stored in the initialization file.
2849  *
2850  *              The same mechanism that detects when catcache and relcache entries
2851  *              need to be invalidated (due to catalog updates) also arranges to
2852  *              unlink the initialization file when its contents may be out of date.
2853  *              The file will then be rebuilt during the next backend startup.
2854  */
2855
2856 /*
2857  * load_relcache_init_file -- attempt to load cache from the init file
2858  *
2859  * If successful, return TRUE and set criticalRelcachesBuilt to true.
2860  * If not successful, return FALSE and set needNewCacheFile to true.
2861  *
2862  * NOTE: we assume we are already switched into CacheMemoryContext.
2863  */
2864 static bool
2865 load_relcache_init_file(void)
2866 {
2867         FILE       *fp;
2868         char            initfilename[MAXPGPATH];
2869         Relation   *rels;
2870         int                     relno,
2871                                 num_rels,
2872                                 max_rels,
2873                                 nailed_rels,
2874                                 nailed_indexes,
2875                                 magic;
2876         int                     i;
2877
2878         snprintf(initfilename, sizeof(initfilename), "%s/%s",
2879                          DatabasePath, RELCACHE_INIT_FILENAME);
2880
2881         fp = AllocateFile(initfilename, PG_BINARY_R);
2882         if (fp == NULL)
2883         {
2884                 needNewCacheFile = true;
2885                 return false;
2886         }
2887
2888         /*
2889          * Read the index relcache entries from the file.  Note we will not enter
2890          * any of them into the cache if the read fails partway through; this
2891          * helps to guard against broken init files.
2892          */
2893         max_rels = 100;
2894         rels = (Relation *) palloc(max_rels * sizeof(Relation));
2895         num_rels = 0;
2896         nailed_rels = nailed_indexes = 0;
2897         initFileRelationIds = NIL;
2898
2899         /* check for correct magic number (compatible version) */
2900         if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
2901                 goto read_failed;
2902         if (magic != RELCACHE_INIT_FILEMAGIC)
2903                 goto read_failed;
2904
2905         for (relno = 0;; relno++)
2906         {
2907                 Size            len;
2908                 size_t          nread;
2909                 Relation        rel;
2910                 Form_pg_class relform;
2911                 bool            has_not_null;
2912                 Datum           indclassDatum;
2913                 bool            isnull;
2914
2915                 /* first read the relation descriptor length */
2916                 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2917                 {
2918                         if (nread == 0)
2919                                 break;                  /* end of file */
2920                         goto read_failed;
2921                 }
2922
2923                 /* safety check for incompatible relcache layout */
2924                 if (len != sizeof(RelationData))
2925                         goto read_failed;
2926
2927                 /* allocate another relcache header */
2928                 if (num_rels >= max_rels)
2929                 {
2930                         max_rels *= 2;
2931                         rels = (Relation *) repalloc(rels, max_rels * sizeof(Relation));
2932                 }
2933
2934                 rel = rels[num_rels++] = (Relation) palloc(len);
2935
2936                 /* then, read the Relation structure */
2937                 if ((nread = fread(rel, 1, len, fp)) != len)
2938                         goto read_failed;
2939
2940                 /* next read the relation tuple form */
2941                 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2942                         goto read_failed;
2943
2944                 relform = (Form_pg_class) palloc(len);
2945                 if ((nread = fread(relform, 1, len, fp)) != len)
2946                         goto read_failed;
2947
2948                 rel->rd_rel = relform;
2949
2950                 /* initialize attribute tuple forms */
2951                 rel->rd_att = CreateTemplateTupleDesc(relform->relnatts,
2952                                                                                           relform->relhasoids);
2953                 rel->rd_att->tdtypeid = relform->reltype;
2954                 rel->rd_att->tdtypmod = -1;             /* unnecessary, but... */
2955
2956                 /* next read all the attribute tuple form data entries */
2957                 has_not_null = false;
2958                 for (i = 0; i < relform->relnatts; i++)
2959                 {
2960                         if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2961                                 goto read_failed;
2962                         if (len != ATTRIBUTE_TUPLE_SIZE)
2963                                 goto read_failed;
2964                         if ((nread = fread(rel->rd_att->attrs[i], 1, len, fp)) != len)
2965                                 goto read_failed;
2966
2967                         has_not_null |= rel->rd_att->attrs[i]->attnotnull;
2968                 }
2969
2970                 /* mark not-null status */
2971                 if (has_not_null)
2972                 {
2973                         TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
2974
2975                         constr->has_not_null = true;
2976                         rel->rd_att->constr = constr;
2977                 }
2978
2979                 /* If it's an index, there's more to do */
2980                 if (rel->rd_rel->relkind == RELKIND_INDEX)
2981                 {
2982                         Form_pg_am      am;
2983                         MemoryContext indexcxt;
2984                         Oid                *operator;
2985                         RegProcedure *support;
2986                         int                     nsupport;
2987
2988                         /* Count nailed indexes to ensure we have 'em all */
2989                         if (rel->rd_isnailed)
2990                                 nailed_indexes++;
2991
2992                         /* next, read the pg_index tuple */
2993                         if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2994                                 goto read_failed;
2995
2996                         rel->rd_indextuple = (HeapTuple) palloc(len);
2997                         if ((nread = fread(rel->rd_indextuple, 1, len, fp)) != len)
2998                                 goto read_failed;
2999
3000                         /* Fix up internal pointers in the tuple -- see heap_copytuple */
3001                         rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE);
3002                         rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple);
3003
3004                         /* fix up indclass pointer too */
3005                         indclassDatum = fastgetattr(rel->rd_indextuple,
3006                                                                                 Anum_pg_index_indclass,
3007                                                                                 GetPgIndexDescriptor(),
3008                                                                                 &isnull);
3009                         Assert(!isnull);
3010                         rel->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
3011
3012                         /* next, read the access method tuple form */
3013                         if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3014                                 goto read_failed;
3015
3016                         am = (Form_pg_am) palloc(len);
3017                         if ((nread = fread(am, 1, len, fp)) != len)
3018                                 goto read_failed;
3019                         rel->rd_am = am;
3020
3021                         /*
3022                          * prepare index info context --- parameters should match
3023                          * RelationInitIndexAccessInfo
3024                          */
3025                         indexcxt = AllocSetContextCreate(CacheMemoryContext,
3026                                                                                          RelationGetRelationName(rel),
3027                                                                                          ALLOCSET_SMALL_MINSIZE,
3028                                                                                          ALLOCSET_SMALL_INITSIZE,
3029                                                                                          ALLOCSET_SMALL_MAXSIZE);
3030                         rel->rd_indexcxt = indexcxt;
3031
3032                         /* next, read the vector of operator OIDs */
3033                         if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3034                                 goto read_failed;
3035
3036                         operator = (Oid *) MemoryContextAlloc(indexcxt, len);
3037                         if ((nread = fread(operator, 1, len, fp)) != len)
3038                                 goto read_failed;
3039
3040                         rel->rd_operator = operator;
3041
3042                         /* finally, read the vector of support procedures */
3043                         if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3044                                 goto read_failed;
3045                         support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
3046                         if ((nread = fread(support, 1, len, fp)) != len)
3047                                 goto read_failed;
3048
3049                         rel->rd_support = support;
3050
3051                         /* set up zeroed fmgr-info vectors */
3052                         rel->rd_aminfo = (RelationAmInfo *)
3053                                 MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo));
3054                         nsupport = relform->relnatts * am->amsupport;
3055                         rel->rd_supportinfo = (FmgrInfo *)
3056                                 MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
3057                 }
3058                 else
3059                 {
3060                         /* Count nailed rels to ensure we have 'em all */
3061                         if (rel->rd_isnailed)
3062                                 nailed_rels++;
3063
3064                         Assert(rel->rd_index == NULL);
3065                         Assert(rel->rd_indextuple == NULL);
3066                         Assert(rel->rd_indclass == NULL);
3067                         Assert(rel->rd_am == NULL);
3068                         Assert(rel->rd_indexcxt == NULL);
3069                         Assert(rel->rd_aminfo == NULL);
3070                         Assert(rel->rd_operator == NULL);
3071                         Assert(rel->rd_support == NULL);
3072                         Assert(rel->rd_supportinfo == NULL);
3073                 }
3074
3075                 /*
3076                  * Rules and triggers are not saved (mainly because the internal
3077                  * format is complex and subject to change).  They must be rebuilt if
3078                  * needed by RelationCacheInitializePhase2.  This is not expected to
3079                  * be a big performance hit since few system catalogs have such. Ditto
3080                  * for index expressions and predicates.
3081                  */
3082                 rel->rd_rules = NULL;
3083                 rel->rd_rulescxt = NULL;
3084                 rel->trigdesc = NULL;
3085                 rel->rd_indexprs = NIL;
3086                 rel->rd_indpred = NIL;
3087
3088                 /*
3089                  * Reset transient-state fields in the relcache entry
3090                  */
3091                 rel->rd_smgr = NULL;
3092                 rel->rd_targblock = InvalidBlockNumber;
3093                 if (rel->rd_isnailed)
3094                         rel->rd_refcnt = 1;
3095                 else
3096                         rel->rd_refcnt = 0;
3097                 rel->rd_indexvalid = 0;
3098                 rel->rd_indexlist = NIL;
3099                 rel->rd_oidindex = InvalidOid;
3100                 rel->rd_createSubid = InvalidSubTransactionId;
3101                 MemSet(&rel->pgstat_info, 0, sizeof(rel->pgstat_info));
3102
3103                 /*
3104                  * Recompute lock and physical addressing info.  This is needed in
3105                  * case the pg_internal.init file was copied from some other database
3106                  * by CREATE DATABASE.
3107                  */
3108                 RelationInitLockInfo(rel);
3109                 RelationInitPhysicalAddr(rel);
3110         }
3111
3112         /*
3113          * We reached the end of the init file without apparent problem. Did we
3114          * get the right number of nailed items?  (This is a useful crosscheck in
3115          * case the set of critical rels or indexes changes.)
3116          */
3117         if (nailed_rels != NUM_CRITICAL_RELS ||
3118                 nailed_indexes != NUM_CRITICAL_INDEXES)
3119                 goto read_failed;
3120
3121         /*
3122          * OK, all appears well.
3123          *
3124          * Now insert all the new relcache entries into the cache.
3125          */
3126         for (relno = 0; relno < num_rels; relno++)
3127         {
3128                 RelationCacheInsert(rels[relno]);
3129                 /* also make a list of their OIDs, for RelationIdIsInInitFile */
3130                 initFileRelationIds = lcons_oid(RelationGetRelid(rels[relno]),
3131                                                                                 initFileRelationIds);
3132         }
3133
3134         pfree(rels);
3135         FreeFile(fp);
3136
3137         criticalRelcachesBuilt = true;
3138         return true;
3139
3140         /*
3141          * init file is broken, so do it the hard way.  We don't bother trying to
3142          * free the clutter we just allocated; it's not in the relcache so it
3143          * won't hurt.
3144          */
3145 read_failed:
3146         pfree(rels);
3147         FreeFile(fp);
3148
3149         needNewCacheFile = true;
3150         return false;
3151 }
3152
3153 /*
3154  * Write out a new initialization file with the current contents
3155  * of the relcache.
3156  */
3157 static void
3158 write_relcache_init_file(void)
3159 {
3160         FILE       *fp;
3161         char            tempfilename[MAXPGPATH];
3162         char            finalfilename[MAXPGPATH];
3163         int                     magic;
3164         HASH_SEQ_STATUS status;
3165         RelIdCacheEnt *idhentry;
3166         MemoryContext oldcxt;
3167         int                     i;
3168
3169         /*
3170          * We must write a temporary file and rename it into place. Otherwise,
3171          * another backend starting at about the same time might crash trying to
3172          * read the partially-complete file.
3173          */
3174         snprintf(tempfilename, sizeof(tempfilename), "%s/%s.%d",
3175                          DatabasePath, RELCACHE_INIT_FILENAME, MyProcPid);
3176         snprintf(finalfilename, sizeof(finalfilename), "%s/%s",
3177                          DatabasePath, RELCACHE_INIT_FILENAME);
3178
3179         unlink(tempfilename);           /* in case it exists w/wrong permissions */
3180
3181         fp = AllocateFile(tempfilename, PG_BINARY_W);
3182         if (fp == NULL)
3183         {
3184                 /*
3185                  * We used to consider this a fatal error, but we might as well
3186                  * continue with backend startup ...
3187                  */
3188                 ereport(WARNING,
3189                                 (errcode_for_file_access(),
3190                                  errmsg("could not create relation-cache initialization file \"%s\": %m",
3191                                                 tempfilename),
3192                           errdetail("Continuing anyway, but there's something wrong.")));
3193                 return;
3194         }
3195
3196         /*
3197          * Write a magic number to serve as a file version identifier.  We can
3198          * change the magic number whenever the relcache layout changes.
3199          */
3200         magic = RELCACHE_INIT_FILEMAGIC;
3201         if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
3202                 elog(FATAL, "could not write init file");
3203
3204         /*
3205          * Write all the reldescs (in no particular order).
3206          */
3207         hash_seq_init(&status, RelationIdCache);
3208
3209         initFileRelationIds = NIL;
3210
3211         while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3212         {
3213                 Relation        rel = idhentry->reldesc;
3214                 Form_pg_class relform = rel->rd_rel;
3215                 Size            len;
3216
3217                 /*
3218                  * first write the relcache entry proper
3219                  */
3220                 len = sizeof(RelationData);
3221
3222                 /* first, write the relation descriptor length */
3223                 if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3224                         elog(FATAL, "could not write init file");
3225
3226                 /* next, write out the Relation structure */
3227                 if (fwrite(rel, 1, len, fp) != len)
3228                         elog(FATAL, "could not write init file");
3229
3230                 /* next write the relation tuple form */
3231                 len = sizeof(FormData_pg_class);
3232                 if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3233                         elog(FATAL, "could not write init file");
3234
3235                 if (fwrite(relform, 1, len, fp) != len)
3236                         elog(FATAL, "could not write init file");
3237
3238                 /* next, do all the attribute tuple form data entries */
3239                 for (i = 0; i < relform->relnatts; i++)
3240                 {
3241                         len = ATTRIBUTE_TUPLE_SIZE;
3242                         if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3243                                 elog(FATAL, "could not write init file");
3244                         if (fwrite(rel->rd_att->attrs[i], 1, len, fp) != len)
3245                                 elog(FATAL, "could not write init file");
3246                 }
3247
3248                 /* If it's an index, there's more to do */
3249                 if (rel->rd_rel->relkind == RELKIND_INDEX)
3250                 {
3251                         Form_pg_am      am = rel->rd_am;
3252
3253                         /* write the pg_index tuple */
3254                         /* we assume this was created by heap_copytuple! */
3255                         len = HEAPTUPLESIZE + rel->rd_indextuple->t_len;
3256                         if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3257                                 elog(FATAL, "could not write init file");
3258
3259                         if (fwrite(rel->rd_indextuple, 1, len, fp) != len)
3260                                 elog(FATAL, "could not write init file");
3261
3262                         /* next, write the access method tuple form */
3263                         len = sizeof(FormData_pg_am);
3264                         if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3265                                 elog(FATAL, "could not write init file");
3266
3267                         if (fwrite(am, 1, len, fp) != len)
3268                                 elog(FATAL, "could not write init file");
3269
3270                         /* next, write the vector of operator OIDs */
3271                         len = relform->relnatts * (am->amstrategies * sizeof(Oid));
3272                         if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3273                                 elog(FATAL, "could not write init file");
3274
3275                         if (fwrite(rel->rd_operator, 1, len, fp) != len)
3276                                 elog(FATAL, "could not write init file");
3277
3278                         /* finally, write the vector of support procedures */
3279                         len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
3280                         if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3281                                 elog(FATAL, "could not write init file");
3282
3283                         if (fwrite(rel->rd_support, 1, len, fp) != len)
3284                                 elog(FATAL, "could not write init file");
3285                 }
3286
3287                 /* also make a list of their OIDs, for RelationIdIsInInitFile */
3288                 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
3289                 initFileRelationIds = lcons_oid(RelationGetRelid(rel),
3290                                                                                 initFileRelationIds);
3291                 MemoryContextSwitchTo(oldcxt);
3292         }
3293
3294         if (FreeFile(fp))
3295                 elog(FATAL, "could not write init file");
3296
3297         /*
3298          * Now we have to check whether the data we've so painstakingly
3299          * accumulated is already obsolete due to someone else's just-committed
3300          * catalog changes.  If so, we just delete the temp file and leave it to
3301          * the next backend to try again.  (Our own relcache entries will be
3302          * updated by SI message processing, but we can't be sure whether what we
3303          * wrote out was up-to-date.)
3304          *
3305          * This mustn't run concurrently with RelationCacheInitFileInvalidate, so
3306          * grab a serialization lock for the duration.
3307          */
3308         LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3309
3310         /* Make sure we have seen all incoming SI messages */
3311         AcceptInvalidationMessages();
3312
3313         /*
3314          * If we have received any SI relcache invals since backend start, assume
3315          * we may have written out-of-date data.
3316          */
3317         if (relcacheInvalsReceived == 0L)
3318         {
3319                 /*
3320                  * OK, rename the temp file to its final name, deleting any
3321                  * previously-existing init file.
3322                  *
3323                  * Note: a failure here is possible under Cygwin, if some other
3324                  * backend is holding open an unlinked-but-not-yet-gone init file. So
3325                  * treat this as a noncritical failure; just remove the useless temp
3326                  * file on failure.
3327                  */
3328                 if (rename(tempfilename, finalfilename) < 0)
3329                         unlink(tempfilename);
3330         }
3331         else
3332         {
3333                 /* Delete the already-obsolete temp file */
3334                 unlink(tempfilename);
3335         }
3336
3337         LWLockRelease(RelCacheInitLock);
3338 }
3339
3340 /*
3341  * Detect whether a given relation (identified by OID) is one of the ones
3342  * we store in the init file.
3343  *
3344  * Note that we effectively assume that all backends running in a database
3345  * would choose to store the same set of relations in the init file;
3346  * otherwise there are cases where we'd fail to detect the need for an init
3347  * file invalidation.  This does not seem likely to be a problem in practice.
3348  */
3349 bool
3350 RelationIdIsInInitFile(Oid relationId)
3351 {
3352         return list_member_oid(initFileRelationIds, relationId);
3353 }
3354
3355 /*
3356  * Invalidate (remove) the init file during commit of a transaction that
3357  * changed one or more of the relation cache entries that are kept in the
3358  * init file.
3359  *
3360  * We actually need to remove the init file twice: once just before sending
3361  * the SI messages that include relcache inval for such relations, and once
3362  * just after sending them.  The unlink before ensures that a backend that's
3363  * currently starting cannot read the now-obsolete init file and then miss
3364  * the SI messages that will force it to update its relcache entries.  (This
3365  * works because the backend startup sequence gets into the PGPROC array before
3366  * trying to load the init file.)  The unlink after is to synchronize with a
3367  * backend that may currently be trying to write an init file based on data
3368  * that we've just rendered invalid.  Such a backend will see the SI messages,
3369  * but we can't leave the init file sitting around to fool later backends.
3370  *
3371  * Ignore any failure to unlink the file, since it might not be there if
3372  * no backend has been started since the last removal.
3373  */
3374 void
3375 RelationCacheInitFileInvalidate(bool beforeSend)
3376 {
3377         char            initfilename[MAXPGPATH];
3378
3379         snprintf(initfilename, sizeof(initfilename), "%s/%s",
3380                          DatabasePath, RELCACHE_INIT_FILENAME);
3381
3382         if (beforeSend)
3383         {
3384                 /* no interlock needed here */
3385                 unlink(initfilename);
3386         }
3387         else
3388         {
3389                 /*
3390                  * We need to interlock this against write_relcache_init_file, to
3391                  * guard against possibility that someone renames a new-but-
3392                  * already-obsolete init file into place just after we unlink. With
3393                  * the interlock, it's certain that write_relcache_init_file will
3394                  * notice our SI inval message before renaming into place, or else
3395                  * that we will execute second and successfully unlink the file.
3396                  */
3397                 LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3398                 unlink(initfilename);
3399                 LWLockRelease(RelCacheInitLock);
3400         }
3401 }