1 /*-------------------------------------------------------------------------
4 * POSTGRES relation descriptor cache code
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.234 2006/01/05 10:07:46 petere Exp $
13 *-------------------------------------------------------------------------
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
24 * The following code contains many undocumented hacks. Please be
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"
70 * name of relcache init file, used to speed up backend startup
72 #define RELCACHE_INIT_FILENAME "pg_internal.init"
74 #define RELCACHE_INIT_FILEMAGIC 0x573262 /* version ID value */
77 * hardcoded tuple descriptors. see include/catalog/pg_attribute.h
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};
86 * Hash tables that index the relation cache
88 * We used to index the cache by both name and OID, but now there
89 * is only an index by OID.
91 typedef struct relidcacheent
97 static HTAB *RelationIdCache;
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.
103 bool criticalRelcachesBuilt = false;
106 * This flag is set if we discover that we need to write a new relcache
107 * cache file at the end of startup.
109 static bool needNewCacheFile = false;
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.
117 static long relcacheInvalsReceived = 0L;
120 * This list remembers the OIDs of the relations cached in the relcache
123 static List *initFileRelationIds = NIL;
126 * This flag lets us optimize away work in AtEO(Sub)Xact_RelationCache().
128 static bool need_eoxact_work = false;
132 * macros to manipulate the lookup hashtables
134 #define RelationCacheInsert(RELATION) \
136 RelIdCacheEnt *idhentry; bool found; \
137 idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
138 (void *) &(RELATION->rd_id), \
141 /* used to give notice if found -- now just keep quiet */ \
142 idhentry->reldesc = RELATION; \
145 #define RelationIdCacheLookup(ID, RELATION) \
147 RelIdCacheEnt *hentry; \
148 hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
149 (void *) &(ID), HASH_FIND,NULL); \
151 RELATION = hentry->reldesc; \
156 #define RelationCacheDelete(RELATION) \
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"); \
168 * Special cache for opclass-related information
170 * Note: only default-subtype operators and support procs get cached
172 typedef struct opclasscacheent
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 */
182 static HTAB *OpClassCache = NULL;
185 /* non-export function prototypes */
187 static void RelationClearRelation(Relation relation, bool rebuild);
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);
194 static void formrdesc(const char *relationName, Oid relationReltype,
195 bool hasoids, int natts, FormData_pg_attribute *att);
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,
208 RegProcedure *indexSupport,
209 StrategyNumber maxStrategyNumber,
210 StrategyNumber maxSupportNumber,
211 AttrNumber maxAttributeNumber);
212 static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
213 StrategyNumber numStrats,
214 StrategyNumber numSupport);
220 * this is used by RelationBuildDesc to find a pg_class
221 * tuple matching targetRelId.
223 * NB: the returned tuple has been copied into palloc'd storage
224 * and must eventually be freed with heap_freetuple.
227 ScanPgRelation(Oid targetRelId, bool indexOK)
229 HeapTuple pg_class_tuple;
230 Relation pg_class_desc;
231 SysScanDesc pg_class_scan;
238 ObjectIdAttributeNumber,
239 BTEqualStrategyNumber, F_OIDEQ,
240 ObjectIdGetDatum(targetRelId));
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.
248 pg_class_desc = heap_open(RelationRelationId, AccessShareLock);
249 pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
250 indexOK && criticalRelcachesBuilt,
254 pg_class_tuple = systable_getnext(pg_class_scan);
257 * Must copy tuple before releasing buffer.
259 if (HeapTupleIsValid(pg_class_tuple))
260 pg_class_tuple = heap_copytuple(pg_class_tuple);
263 systable_endscan(pg_class_scan);
264 heap_close(pg_class_desc, AccessShareLock);
266 return pg_class_tuple;
270 * AllocateRelationDesc
272 * This is used to allocate memory for a new relation descriptor
273 * and initialize the rd_rel field.
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).
280 AllocateRelationDesc(Relation relation, Form_pg_class relp)
282 MemoryContext oldcxt;
283 Form_pg_class relationForm;
285 /* Relcache entries must live in CacheMemoryContext */
286 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
289 * allocate space for new relation descriptor, if needed
291 if (relation == NULL)
292 relation = (Relation) palloc(sizeof(RelationData));
295 * clear all fields of reldesc
297 MemSet(relation, 0, sizeof(RelationData));
298 relation->rd_targblock = InvalidBlockNumber;
300 /* make sure relation is marked as having no open file yet */
301 relation->rd_smgr = NULL;
304 * Copy the relation tuple form
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.
312 relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
314 memcpy(relationForm, relp, CLASS_TUPLE_SIZE);
316 /* initialize relation tuple form */
317 relation->rd_rel = relationForm;
319 /* and allocate attribute tuple form storage */
320 relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts,
321 relationForm->relhasoids);
323 MemoryContextSwitchTo(oldcxt);
329 * RelationBuildTupleDesc
331 * Form the relation's tuple descriptor from information in
332 * the pg_attribute, pg_attrdef & pg_constraint system catalogs.
335 RelationBuildTupleDesc(Relation relation)
337 HeapTuple pg_attribute_tuple;
338 Relation pg_attribute_desc;
339 SysScanDesc pg_attribute_scan;
343 AttrDefault *attrdef = NULL;
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;
351 constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
352 sizeof(TupleConstr));
353 constr->has_not_null = false;
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.)
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,
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).
374 pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock);
375 pg_attribute_scan = systable_beginscan(pg_attribute_desc,
376 AttributeRelidNumIndexId,
377 criticalRelcachesBuilt,
382 * add attribute data to relation->rd_att
384 need = relation->rd_rel->relnatts;
386 while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
388 Form_pg_attribute attp;
390 attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
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));
397 memcpy(relation->rd_att->attrs[attp->attnum - 1],
399 ATTRIBUTE_TUPLE_SIZE);
401 /* Update constraint/default info */
402 if (attp->attnotnull)
403 constr->has_not_null = true;
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;
422 * end the scan and close the attribute relation
424 systable_endscan(pg_attribute_scan);
425 heap_close(pg_attribute_desc, AccessShareLock);
428 elog(ERROR, "catalog is missing %d attribute(s) for relid %u",
429 need, RelationGetRelid(relation));
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.
436 #ifdef USE_ASSERT_CHECKING
440 for (i = 0; i < relation->rd_rel->relnatts; i++)
441 Assert(relation->rd_att->attrs[i]->attcacheoff == -1);
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().
450 if (relation->rd_rel->relnatts > 0)
451 relation->rd_att->attrs[0]->attcacheoff = 0;
454 * Set up constraint/default info
456 if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
458 relation->rd_att->constr = constr;
460 if (ndef > 0) /* DEFAULTs */
462 if (ndef < relation->rd_rel->relnatts)
463 constr->defval = (AttrDefault *)
464 repalloc(attrdef, ndef * sizeof(AttrDefault));
466 constr->defval = attrdef;
467 constr->num_defval = ndef;
468 AttrDefaultFetch(relation);
471 constr->num_defval = 0;
473 if (relation->rd_rel->relchecks > 0) /* CHECKs */
475 constr->num_check = relation->rd_rel->relchecks;
476 constr->check = (ConstrCheck *)
477 MemoryContextAllocZero(CacheMemoryContext,
478 constr->num_check * sizeof(ConstrCheck));
479 CheckConstraintFetch(relation);
482 constr->num_check = 0;
487 relation->rd_att->constr = NULL;
492 * RelationBuildRuleLock
494 * Form the relation's rewrite rules from information in
495 * the pg_rewrite system catalog.
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.
507 RelationBuildRuleLock(Relation relation)
509 MemoryContext rulescxt;
510 MemoryContext oldcxt;
511 HeapTuple rewrite_tuple;
512 Relation rewrite_desc;
513 TupleDesc rewrite_tupdesc;
514 SysScanDesc rewrite_scan;
522 * Make the private context. Parameters are set on the assumption that
523 * it'll probably not contain much data.
525 rulescxt = AllocSetContextCreate(CacheMemoryContext,
526 RelationGetRelationName(relation),
527 ALLOCSET_SMALL_MINSIZE,
528 ALLOCSET_SMALL_INITSIZE,
529 ALLOCSET_SMALL_MAXSIZE);
530 relation->rd_rulescxt = rulescxt;
533 * allocate an array to hold the rewrite rules (the array is extended if
537 rules = (RewriteRule **)
538 MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
545 Anum_pg_rewrite_ev_class,
546 BTEqualStrategyNumber, F_OIDEQ,
547 ObjectIdGetDatum(RelationGetRelid(relation)));
550 * open pg_rewrite and begin a scan
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.
557 rewrite_desc = heap_open(RewriteRelationId, AccessShareLock);
558 rewrite_tupdesc = RelationGetDescr(rewrite_desc);
559 rewrite_scan = systable_beginscan(rewrite_desc,
560 RewriteRelRulenameIndexId,
564 while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan)))
566 Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(rewrite_tuple);
570 char *ruleaction_str;
571 char *rule_evqual_str;
574 rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
575 sizeof(RewriteRule));
577 rule->ruleId = HeapTupleGetOid(rewrite_tuple);
579 rule->event = rewrite_form->ev_type - '0';
580 rule->attrno = rewrite_form->ev_attr;
581 rule->isInstead = rewrite_form->is_instead;
583 /* Must use heap_getattr to fetch ev_qual and ev_action */
585 ruleaction = heap_getattr(rewrite_tuple,
586 Anum_pg_rewrite_ev_action,
590 ruleaction_str = DatumGetCString(DirectFunctionCall1(textout,
592 oldcxt = MemoryContextSwitchTo(rulescxt);
593 rule->actions = (List *) stringToNode(ruleaction_str);
594 MemoryContextSwitchTo(oldcxt);
595 pfree(ruleaction_str);
597 rule_evqual = heap_getattr(rewrite_tuple,
598 Anum_pg_rewrite_ev_qual,
602 rule_evqual_str = DatumGetCString(DirectFunctionCall1(textout,
604 oldcxt = MemoryContextSwitchTo(rulescxt);
605 rule->qual = (Node *) stringToNode(rule_evqual_str);
606 MemoryContextSwitchTo(oldcxt);
607 pfree(rule_evqual_str);
609 if (numlocks >= maxlocks)
612 rules = (RewriteRule **)
613 repalloc(rules, sizeof(RewriteRule *) * maxlocks);
615 rules[numlocks++] = rule;
619 * end the scan and close the attribute relation
621 systable_endscan(rewrite_scan);
622 heap_close(rewrite_desc, AccessShareLock);
625 * form a RuleLock and insert into relation
627 rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
628 rulelock->numLocks = numlocks;
629 rulelock->rules = rules;
631 relation->rd_rules = rulelock;
637 * Determine whether two RuleLocks are equivalent
639 * Probably this should be in the rules code someplace...
642 equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
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.
655 if (rlock1->numLocks != rlock2->numLocks)
657 for (i = 0; i < rlock1->numLocks; i++)
659 RewriteRule *rule1 = rlock1->rules[i];
660 RewriteRule *rule2 = rlock2->rules[i];
662 if (rule1->ruleId != rule2->ruleId)
664 if (rule1->event != rule2->event)
666 if (rule1->attrno != rule2->attrno)
668 if (rule1->isInstead != rule2->isInstead)
670 if (!equal(rule1->qual, rule2->qual))
672 if (!equal(rule1->actions, rule2->actions))
676 else if (rlock2 != NULL)
682 /* ----------------------------------
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
689 * --------------------------------
692 RelationBuildDesc(Oid targetRelId, Relation oldrelation)
696 HeapTuple pg_class_tuple;
698 MemoryContext oldcxt;
701 * find the tuple in pg_class corresponding to the given relation id
703 pg_class_tuple = ScanPgRelation(targetRelId, true);
706 * if no such tuple exists, return NULL
708 if (!HeapTupleIsValid(pg_class_tuple))
712 * get information from the pg_class_tuple
714 relid = HeapTupleGetOid(pg_class_tuple);
715 relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
718 * allocate storage for the relation descriptor, and copy pg_class_tuple
719 * to relation->rd_rel.
721 relation = AllocateRelationDesc(oldrelation, relp);
724 * now we can free the memory allocated for pg_class_tuple
726 heap_freetuple(pg_class_tuple);
729 * initialize the relation's relation id (relation->rd_id)
731 RelationGetRelid(relation) = relid;
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.)
738 relation->rd_refcnt = 0;
739 relation->rd_isnailed = false;
740 relation->rd_createSubid = InvalidSubTransactionId;
741 relation->rd_istemp = isTempNamespace(relation->rd_rel->relnamespace);
744 * initialize the tuple descriptor (relation->rd_att).
746 RelationBuildTupleDesc(relation);
749 * Fetch rules and triggers that affect this relation
751 if (relation->rd_rel->relhasrules)
752 RelationBuildRuleLock(relation);
755 relation->rd_rules = NULL;
756 relation->rd_rulescxt = NULL;
759 if (relation->rd_rel->reltriggers > 0)
760 RelationBuildTriggers(relation);
762 relation->trigdesc = NULL;
765 * if it's an index, initialize index-related information
767 if (OidIsValid(relation->rd_rel->relam))
768 RelationInitIndexAccessInfo(relation);
771 * initialize the relation lock manager information
773 RelationInitLockInfo(relation); /* see lmgr.c */
776 * initialize physical addressing information for the relation
778 RelationInitPhysicalAddr(relation);
780 /* make sure relation is marked as having no open file yet */
781 relation->rd_smgr = NULL;
784 * Insert newly created relation into relcache hash tables.
786 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
787 RelationCacheInsert(relation);
788 MemoryContextSwitchTo(oldcxt);
790 /* It's fully valid */
791 relation->rd_isvalid = true;
797 * Initialize the physical addressing info (RelFileNode) for a relcache entry
800 RelationInitPhysicalAddr(Relation relation)
802 if (relation->rd_rel->reltablespace)
803 relation->rd_node.spcNode = relation->rd_rel->reltablespace;
805 relation->rd_node.spcNode = MyDatabaseTableSpace;
806 if (relation->rd_rel->relisshared)
807 relation->rd_node.dbNode = InvalidOid;
809 relation->rd_node.dbNode = MyDatabaseId;
810 relation->rd_node.relNode = relation->rd_rel->relfilenode;
814 * Initialize index-access-method support data for an index relation
817 RelationInitIndexAccessInfo(Relation relation)
823 MemoryContext indexcxt;
824 MemoryContext oldcontext;
826 RegProcedure *support;
827 FmgrInfo *supportinfo;
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.
837 tuple = SearchSysCache(INDEXRELID,
838 ObjectIdGetDatum(RelationGetRelid(relation)),
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);
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.
854 indclassDatum = fastgetattr(relation->rd_indextuple,
855 Anum_pg_index_indclass,
856 GetPgIndexDescriptor(),
859 relation->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
862 * Make a copy of the pg_am entry for the index's access method
864 tuple = SearchSysCache(AMOID,
865 ObjectIdGetDatum(relation->rd_rel->relam),
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;
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;
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.
887 * Context parameters are set on the assumption that it'll probably not
890 indexcxt = AllocSetContextCreate(CacheMemoryContext,
891 RelationGetRelationName(relation),
892 ALLOCSET_SMALL_MINSIZE,
893 ALLOCSET_SMALL_INITSIZE,
894 ALLOCSET_SMALL_MAXSIZE);
895 relation->rd_indexcxt = indexcxt;
898 * Allocate arrays to hold data
900 relation->rd_aminfo = (RelationAmInfo *)
901 MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo));
903 if (amstrategies > 0)
905 MemoryContextAllocZero(indexcxt,
906 natts * amstrategies * sizeof(Oid));
912 int nsupport = natts * amsupport;
914 support = (RegProcedure *)
915 MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
916 supportinfo = (FmgrInfo *)
917 MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
925 relation->rd_operator = operator;
926 relation->rd_support = support;
927 relation->rd_supportinfo = supportinfo;
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)
933 IndexSupportInitialize(relation->rd_indclass,
935 amstrategies, amsupport, natts);
938 * expressions and predicate cache will be filled later
940 relation->rd_indexprs = NIL;
941 relation->rd_indpred = NIL;
945 * IndexSupportInitialize
946 * Initializes an index's cached opclass information,
947 * given the index's pg_index.indclass entry.
949 * Data is returned into *indexOperator and *indexSupport, which are arrays
950 * allocated by the caller.
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
959 IndexSupportInitialize(oidvector *indclass,
961 RegProcedure *indexSupport,
962 StrategyNumber maxStrategyNumber,
963 StrategyNumber maxSupportNumber,
964 AttrNumber maxAttributeNumber)
968 for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
970 OpClassCacheEnt *opcentry;
972 if (!OidIsValid(indclass->values[attIndex]))
973 elog(ERROR, "bogus pg_index tuple");
975 /* look up the info for this opclass, using a cache */
976 opcentry = LookupOpclassInfo(indclass->values[attIndex],
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));
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.
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.
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 :-(
1008 static OpClassCacheEnt *
1009 LookupOpclassInfo(Oid operatorClassOid,
1010 StrategyNumber numStrats,
1011 StrategyNumber numSupport)
1013 OpClassCacheEnt *opcentry;
1017 ScanKeyData skey[2];
1021 if (OpClassCache == NULL)
1023 /* First time through: initialize the opclass cache */
1026 if (!CacheMemoryContext)
1027 CreateCacheMemoryContext();
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);
1037 opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
1038 (void *) &operatorClassOid,
1039 HASH_ENTER, &found);
1041 if (found && opcentry->valid)
1043 /* Already made an entry for it */
1044 Assert(numStrats == opcentry->numStrats);
1045 Assert(numSupport == opcentry->numSupport);
1049 /* Need to fill in new entry */
1050 opcentry->valid = false; /* until known OK */
1051 opcentry->numStrats = numStrats;
1052 opcentry->numSupport = numSupport;
1055 opcentry->operatorOids = (Oid *)
1056 MemoryContextAllocZero(CacheMemoryContext,
1057 numStrats * sizeof(Oid));
1059 opcentry->operatorOids = NULL;
1062 opcentry->supportProcs = (RegProcedure *)
1063 MemoryContextAllocZero(CacheMemoryContext,
1064 numSupport * sizeof(RegProcedure));
1066 opcentry->supportProcs = NULL;
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
1073 indexOK = criticalRelcachesBuilt ||
1074 (operatorClassOid != OID_BTREE_OPS_OID &&
1075 operatorClassOid != INT2_BTREE_OPS_OID);
1078 * Scan pg_amop to obtain operators for the opclass. We only fetch the
1079 * default ones (those with subtype zero).
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);
1095 while (HeapTupleIsValid(htup = systable_getnext(scan)))
1097 Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
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] =
1107 systable_endscan(scan);
1108 heap_close(rel, AccessShareLock);
1112 * Scan pg_amproc to obtain support procs for the opclass. We only fetch
1113 * the default ones (those with subtype zero).
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);
1129 while (HeapTupleIsValid(htup = systable_getnext(scan)))
1131 Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
1133 if (amprocform->amprocnum <= 0 ||
1134 (StrategyNumber) amprocform->amprocnum > numSupport)
1135 elog(ERROR, "invalid amproc number %d for opclass %u",
1136 amprocform->amprocnum, operatorClassOid);
1138 opcentry->supportProcs[amprocform->amprocnum - 1] =
1142 systable_endscan(scan);
1143 heap_close(rel, AccessShareLock);
1146 opcentry->valid = true;
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
1161 * formrdesc is currently used for: pg_class, pg_attribute, pg_proc,
1162 * and pg_type (see RelationCacheInitialize).
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.
1167 * NOTE: we assume we are already switched into CacheMemoryContext.
1170 formrdesc(const char *relationName, Oid relationReltype,
1171 bool hasoids, int natts, FormData_pg_attribute *att)
1178 * allocate new relation desc, clear all fields of reldesc
1180 relation = (Relation) palloc0(sizeof(RelationData));
1181 relation->rd_targblock = InvalidBlockNumber;
1183 /* make sure relation is marked as having no open file yet */
1184 relation->rd_smgr = NULL;
1187 * initialize reference count: 1 because it is nailed in cache
1189 relation->rd_refcnt = 1;
1192 * all entries built with this routine are nailed-in-cache; none are for
1193 * new or temp relations.
1195 relation->rd_isnailed = true;
1196 relation->rd_createSubid = InvalidSubTransactionId;
1197 relation->rd_istemp = false;
1200 * initialize relation tuple form
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.
1206 relation->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
1208 namestrcpy(&relation->rd_rel->relname, relationName);
1209 relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
1210 relation->rd_rel->reltype = relationReltype;
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.
1217 relation->rd_rel->relisshared = false;
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;
1226 * initialize attribute tuple form
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.
1232 relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
1233 relation->rd_att->tdtypeid = relationReltype;
1234 relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
1237 * initialize tuple desc info
1239 has_not_null = false;
1240 for (i = 0; i < natts; i++)
1242 memcpy(relation->rd_att->attrs[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;
1250 /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
1251 relation->rd_att->attrs[0]->attcacheoff = 0;
1253 /* mark not-null status */
1256 TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
1258 constr->has_not_null = true;
1259 relation->rd_att->constr = constr;
1263 * initialize relation id from info in att array (my, this is ugly)
1265 RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
1266 relation->rd_rel->relfilenode = RelationGetRelid(relation);
1269 * initialize the relation lock manager information
1271 RelationInitLockInfo(relation); /* see lmgr.c */
1274 * initialize physical addressing information for the relation
1276 RelationInitPhysicalAddr(relation);
1279 * initialize the rel-has-index flag, using hardwired knowledge
1281 if (IsBootstrapProcessingMode())
1283 /* In bootstrap mode, we have no indexes */
1284 relation->rd_rel->relhasindex = false;
1288 /* Otherwise, all the rels formrdesc is used for have indexes */
1289 relation->rd_rel->relhasindex = true;
1293 * add new reldesc to relcache
1295 RelationCacheInsert(relation);
1297 /* It's fully valid */
1298 relation->rd_isvalid = true;
1302 /* ----------------------------------------------------------------
1303 * Relation Descriptor Lookup Interface
1304 * ----------------------------------------------------------------
1308 * RelationIdCacheGetRelation
1310 * Lookup an existing reldesc by OID.
1312 * Only try to get the reldesc by looking in the cache,
1313 * do not go to the disk if it's not present.
1315 * NB: relation ref count is incremented if successful.
1316 * Caller should eventually decrement count. (Usually,
1317 * that happens by calling RelationClose().)
1320 RelationIdCacheGetRelation(Oid relationId)
1324 RelationIdCacheLookup(relationId, rd);
1326 if (RelationIsValid(rd))
1328 RelationIncrementReferenceCount(rd);
1329 /* revalidate nailed index if necessary */
1330 if (!rd->rd_isvalid)
1331 RelationReloadClassinfo(rd);
1338 * RelationIdGetRelation
1340 * Lookup a reldesc by OID; make one if not already in cache.
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().)
1347 RelationIdGetRelation(Oid relationId)
1352 * first try and get a reldesc from the cache
1354 rd = RelationIdCacheGetRelation(relationId);
1355 if (RelationIsValid(rd))
1359 * no reldesc in the cache, so have RelationBuildDesc() build one and add
1362 rd = RelationBuildDesc(relationId, NULL);
1363 if (RelationIsValid(rd))
1364 RelationIncrementReferenceCount(rd);
1368 /* ----------------------------------------------------------------
1369 * cache invalidation support routines
1370 * ----------------------------------------------------------------
1374 * RelationIncrementReferenceCount
1375 * Increments relation reference count.
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.
1382 RelationIncrementReferenceCount(Relation rel)
1384 ResourceOwnerEnlargeRelationRefs(CurrentResourceOwner);
1385 rel->rd_refcnt += 1;
1386 if (!IsBootstrapProcessingMode())
1387 ResourceOwnerRememberRelationRef(CurrentResourceOwner, rel);
1391 * RelationDecrementReferenceCount
1392 * Decrements relation reference count.
1395 RelationDecrementReferenceCount(Relation rel)
1397 Assert(rel->rd_refcnt > 0);
1398 rel->rd_refcnt -= 1;
1399 if (!IsBootstrapProcessingMode())
1400 ResourceOwnerForgetRelationRef(CurrentResourceOwner, rel);
1404 * RelationClose - close an open relation
1406 * Actually, we just decrement the refcount.
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.
1415 RelationClose(Relation relation)
1417 /* Note: no locking manipulations needed */
1418 RelationDecrementReferenceCount(relation);
1420 #ifdef RELCACHE_FORCE_RELEASE
1421 if (RelationHasReferenceCountZero(relation) &&
1422 relation->rd_createSubid == InvalidSubTransactionId)
1423 RelationClearRelation(relation, false);
1428 * RelationReloadClassinfo - reload the pg_class row (only)
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
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
1443 RelationReloadClassinfo(Relation relation)
1446 HeapTuple pg_class_tuple;
1449 /* Should be called only for invalidated nailed indexes */
1450 Assert(relation->rd_isnailed && !relation->rd_isvalid &&
1451 relation->rd_rel->relkind == RELKIND_INDEX);
1454 * Read the pg_class row
1456 * Don't try to use an indexscan of pg_class_oid_index to reload the info
1457 * for pg_class_oid_index ...
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;
1475 * RelationClearRelation
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.
1484 RelationClearRelation(Relation relation, bool rebuild)
1486 Oid old_reltype = relation->rd_rel->reltype;
1487 MemoryContext oldcxt;
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
1496 RelationCloseSmgr(relation);
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
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.
1511 if (relation->rd_isnailed)
1513 relation->rd_targblock = InvalidBlockNumber;
1514 if (relation->rd_rel->relkind == RELKIND_INDEX)
1516 relation->rd_isvalid = false; /* needs to be revalidated */
1517 if (relation->rd_refcnt > 1)
1518 RelationReloadClassinfo(relation);
1524 * Remove relation from hash tables
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...
1530 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
1531 RelationCacheDelete(relation);
1532 MemoryContextSwitchTo(oldcxt);
1534 /* Clear out catcache's entries for this relation */
1535 CatalogCacheFlushRelation(RelationGetRelid(relation));
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:
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);
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
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);
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.
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.
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;
1588 if (RelationBuildDesc(save_relid, relation) != relation)
1590 /* Should only get here if relation was deleted */
1591 flush_rowtype_cache(old_reltype);
1592 FreeTupleDesc(old_att);
1594 MemoryContextDelete(old_rulescxt);
1596 elog(ERROR, "relation %u deleted while still in use", save_relid);
1598 relation->rd_refcnt = old_refcnt;
1599 relation->rd_createSubid = old_createSubid;
1600 if (equalTupleDescs(old_att, relation->rd_att))
1602 /* needn't flush typcache here */
1603 FreeTupleDesc(relation->rd_att);
1604 relation->rd_att = old_att;
1608 flush_rowtype_cache(old_reltype);
1609 FreeTupleDesc(old_att);
1611 if (equalRuleLocks(old_rules, relation->rd_rules))
1613 if (relation->rd_rulescxt)
1614 MemoryContextDelete(relation->rd_rulescxt);
1615 relation->rd_rules = old_rules;
1616 relation->rd_rulescxt = old_rulescxt;
1621 MemoryContextDelete(old_rulescxt);
1627 * RelationFlushRelation
1629 * Rebuild the relation if it is open (refcount > 0), else blow it away.
1632 RelationFlushRelation(Relation relation)
1636 if (relation->rd_createSubid != InvalidSubTransactionId)
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.
1648 * Pre-existing rels can be dropped from the relcache if not open.
1650 rebuild = !RelationHasReferenceCountZero(relation);
1653 RelationClearRelation(relation, rebuild);
1657 * RelationForgetRelation - unconditionally remove a relcache entry
1659 * External interface for destroying a relcache entry when we
1660 * drop the relation.
1663 RelationForgetRelation(Oid rid)
1667 RelationIdCacheLookup(rid, relation);
1669 if (!PointerIsValid(relation))
1670 return; /* not in cache, nothing to do */
1672 if (!RelationHasReferenceCountZero(relation))
1673 elog(ERROR, "relation %u is still open", rid);
1675 /* Unconditionally destroy the relcache entry */
1676 RelationClearRelation(relation, false);
1680 * RelationCacheInvalidateEntry
1682 * This routine is invoked for SI cache flush messages.
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
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.
1695 RelationCacheInvalidateEntry(Oid relationId)
1699 RelationIdCacheLookup(relationId, relation);
1701 if (PointerIsValid(relation))
1703 relcacheInvalsReceived++;
1704 RelationFlushRelation(relation);
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
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).
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.
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.
1737 RelationCacheInvalidate(void)
1739 HASH_SEQ_STATUS status;
1740 RelIdCacheEnt *idhentry;
1742 List *rebuildFirstList = NIL;
1743 List *rebuildList = NIL;
1747 hash_seq_init(&status, RelationIdCache);
1749 while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1751 relation = idhentry->reldesc;
1753 /* Must close all smgr references to avoid leaving dangling ptrs */
1754 RelationCloseSmgr(relation);
1756 /* Ignore new relations, since they are never SI targets */
1757 if (relation->rd_createSubid != InvalidSubTransactionId)
1760 relcacheInvalsReceived++;
1762 if (RelationHasReferenceCountZero(relation))
1764 /* Delete this entry immediately */
1765 Assert(!relation->rd_isnailed);
1766 RelationClearRelation(relation, false);
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).
1776 if (relation->rd_isnailed &&
1777 relation->rd_rel->relkind == RELKIND_INDEX)
1779 if (RelationGetRelid(relation) == ClassOidIndexId)
1780 rebuildFirstList = lcons(relation, rebuildFirstList);
1782 rebuildFirstList = lappend(rebuildFirstList, relation);
1785 rebuildList = lcons(relation, rebuildList);
1789 rebuildList = list_concat(rebuildFirstList, rebuildList);
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.
1798 /* Phase 2: rebuild the items found to need rebuild in phase 1 */
1799 foreach(l, rebuildList)
1801 relation = (Relation) lfirst(l);
1802 RelationClearRelation(relation, true);
1804 list_free(rebuildList);
1808 * AtEOXact_RelationCache
1810 * Clean up the relcache at main-transaction commit or abort.
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.
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.
1824 AtEOXact_RelationCache(bool isCommit)
1826 HASH_SEQ_STATUS status;
1827 RelIdCacheEnt *idhentry;
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.
1839 if (!need_eoxact_work
1840 #ifdef USE_ASSERT_CHECKING
1846 hash_seq_init(&status, RelationIdCache);
1848 while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1850 Relation relation = idhentry->reldesc;
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.
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.)
1860 #ifdef USE_ASSERT_CHECKING
1861 if (!IsBootstrapProcessingMode())
1863 int expected_refcnt;
1865 expected_refcnt = relation->rd_isnailed ? 1 : 0;
1866 Assert(relation->rd_refcnt == expected_refcnt);
1871 * Is it a relation created in the current transaction?
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.)
1880 if (relation->rd_createSubid != InvalidSubTransactionId)
1883 relation->rd_createSubid = InvalidSubTransactionId;
1886 RelationClearRelation(relation, false);
1892 * Flush any temporary index list.
1894 if (relation->rd_indexvalid == 2)
1896 list_free(relation->rd_indexlist);
1897 relation->rd_indexlist = NIL;
1898 relation->rd_oidindex = InvalidOid;
1899 relation->rd_indexvalid = 0;
1903 /* Once done with the transaction, we can reset need_eoxact_work */
1904 need_eoxact_work = false;
1908 * AtEOSubXact_RelationCache
1910 * Clean up the relcache at sub-transaction commit or abort.
1912 * Note: this must be called *before* processing invalidation messages.
1915 AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
1916 SubTransactionId parentSubid)
1918 HASH_SEQ_STATUS status;
1919 RelIdCacheEnt *idhentry;
1922 * Skip the relcache scan if nothing to do --- see notes for
1923 * AtEOXact_RelationCache.
1925 if (!need_eoxact_work)
1928 hash_seq_init(&status, RelationIdCache);
1930 while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1932 Relation relation = idhentry->reldesc;
1935 * Is it a relation created in the current subtransaction?
1937 * During subcommit, mark it as belonging to the parent, instead.
1938 * During subabort, simply delete the relcache entry.
1940 if (relation->rd_createSubid == mySubid)
1943 relation->rd_createSubid = parentSubid;
1946 Assert(RelationHasReferenceCountZero(relation));
1947 RelationClearRelation(relation, false);
1953 * Flush any temporary index list.
1955 if (relation->rd_indexvalid == 2)
1957 list_free(relation->rd_indexlist);
1958 relation->rd_indexlist = NIL;
1959 relation->rd_oidindex = InvalidOid;
1960 relation->rd_indexvalid = 0;
1966 * RelationBuildLocalRelation
1967 * Build a relcache entry for an about-to-be-created relation,
1968 * and enter it into the relcache.
1971 RelationBuildLocalRelation(const char *relname,
1976 bool shared_relation)
1979 MemoryContext oldcxt;
1980 int natts = tupDesc->natts;
1985 AssertArg(natts >= 0);
1988 * check for creation of a rel that must be nailed in cache.
1990 * XXX this list had better match RelationCacheInitialize's list.
1994 case RelationRelationId:
1995 case AttributeRelationId:
1996 case ProcedureRelationId:
1997 case TypeRelationId:
2006 * switch to the cache context to create the relcache entry.
2008 if (!CacheMemoryContext)
2009 CreateCacheMemoryContext();
2011 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2014 * allocate a new relation descriptor and fill in basic state fields.
2016 rel = (Relation) palloc0(sizeof(RelationData));
2018 rel->rd_targblock = InvalidBlockNumber;
2020 /* make sure relation is marked as having no open file yet */
2021 rel->rd_smgr = NULL;
2023 /* mark it nailed if appropriate */
2024 rel->rd_isnailed = nailit;
2026 rel->rd_refcnt = nailit ? 1 : 0;
2028 /* it's being created in this transaction */
2029 rel->rd_createSubid = GetCurrentSubTransactionId();
2031 /* must flag that we have rels created in this transaction */
2032 need_eoxact_work = true;
2034 /* is it a temporary relation? */
2035 rel->rd_istemp = isTempNamespace(relnamespace);
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.
2044 rel->rd_att = CreateTupleDescCopy(tupDesc);
2045 has_not_null = false;
2046 for (i = 0; i < natts; i++)
2048 rel->rd_att->attrs[i]->attnotnull = tupDesc->attrs[i]->attnotnull;
2049 has_not_null |= tupDesc->attrs[i]->attnotnull;
2054 TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
2056 constr->has_not_null = true;
2057 rel->rd_att->constr = constr;
2061 * initialize relation tuple form (caller may add/override data later)
2063 rel->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
2065 namestrcpy(&rel->rd_rel->relname, relname);
2066 rel->rd_rel->relnamespace = relnamespace;
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;
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).
2080 rel->rd_rel->relisshared = shared_relation;
2082 RelationGetRelid(rel) = relid;
2084 for (i = 0; i < natts; i++)
2085 rel->rd_att->attrs[i]->attrelid = relid;
2087 rel->rd_rel->relfilenode = relid;
2088 rel->rd_rel->reltablespace = reltablespace;
2090 RelationInitLockInfo(rel); /* see lmgr.c */
2092 RelationInitPhysicalAddr(rel);
2095 * Okay to insert into the relcache hash tables.
2097 RelationCacheInsert(rel);
2100 * done building relcache entry.
2102 MemoryContextSwitchTo(oldcxt);
2104 /* It's fully valid */
2105 rel->rd_isvalid = true;
2108 * Caller expects us to pin the returned entry.
2110 RelationIncrementReferenceCount(rel);
2116 * RelationCacheInitialize
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.
2126 #define INITRELCACHESIZE 400
2129 RelationCacheInitialize(void)
2131 MemoryContext oldcxt;
2135 * switch to cache memory context
2137 if (!CacheMemoryContext)
2138 CreateCacheMemoryContext();
2140 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2143 * create hashtables that index the relcache
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);
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.
2157 if (IsBootstrapProcessingMode() ||
2158 !load_relcache_init_file())
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);
2169 #define NUM_CRITICAL_RELS 4 /* fix if you change list above */
2172 MemoryContextSwitchTo(oldcxt);
2176 * RelationCacheInitializePhase2
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.
2185 RelationCacheInitializePhase2(void)
2187 HASH_SEQ_STATUS status;
2188 RelIdCacheEnt *idhentry;
2190 if (IsBootstrapProcessingMode())
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.
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.)
2211 if (!criticalRelcachesBuilt)
2215 #define LOAD_CRIT_INDEX(indexoid) \
2217 ird = RelationBuildDesc((indexoid), NULL); \
2218 ird->rd_isnailed = true; \
2219 ird->rd_refcnt = 1; \
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);
2229 #define NUM_CRITICAL_INDEXES 6 /* fix if you change list above */
2231 criticalRelcachesBuilt = true;
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.
2242 hash_seq_init(&status, RelationIdCache);
2244 while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
2246 Relation relation = idhentry->reldesc;
2249 * If it's a faked-up entry, read the real pg_class tuple.
2251 if (needNewCacheFile && relation->rd_isnailed)
2256 htup = SearchSysCache(RELOID,
2257 ObjectIdGetDatum(RelationGetRelid(relation)),
2259 if (!HeapTupleIsValid(htup))
2260 elog(FATAL, "cache lookup failed for relation %u",
2261 RelationGetRelid(relation));
2262 relp = (Form_pg_class) GETSTRUCT(htup);
2265 * Copy tuple to relation->rd_rel. (See notes in
2266 * AllocateRelationDesc())
2268 Assert(relation->rd_rel != NULL);
2269 memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
2272 * Also update the derived fields in rd_att.
2274 relation->rd_att->tdtypeid = relp->reltype;
2275 relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
2276 relation->rd_att->tdhasoid = relp->relhasoids;
2278 ReleaseSysCache(htup);
2282 * Fix data that isn't saved in relcache cache file.
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);
2292 * RelationCacheInitializePhase3
2294 * Final step of relcache initialization: write out a new relcache
2295 * cache file if one is needed.
2298 RelationCacheInitializePhase3(void)
2300 if (IsBootstrapProcessingMode())
2303 if (needNewCacheFile)
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.
2311 InitCatalogCachePhase2();
2313 /* now write the file */
2314 write_relcache_init_file();
2319 * GetPgIndexDescriptor -- get a predefined tuple descriptor for pg_index
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.
2330 GetPgIndexDescriptor(void)
2332 static TupleDesc pgindexdesc = NULL;
2333 MemoryContext oldcxt;
2340 oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2342 pgindexdesc = CreateTemplateTupleDesc(Natts_pg_index, false);
2343 pgindexdesc->tdtypeid = RECORDOID; /* not right, but we don't care */
2344 pgindexdesc->tdtypmod = -1;
2346 for (i = 0; i < Natts_pg_index; i++)
2348 memcpy(pgindexdesc->attrs[i],
2350 ATTRIBUTE_TUPLE_SIZE);
2351 /* make sure attcacheoff is valid */
2352 pgindexdesc->attrs[i]->attcacheoff = -1;
2355 /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
2356 pgindexdesc->attrs[0]->attcacheoff = 0;
2358 /* Note: we don't bother to set up a TupleConstr entry */
2360 MemoryContextSwitchTo(oldcxt);
2366 AttrDefaultFetch(Relation relation)
2368 AttrDefault *attrdef = relation->rd_att->constr->defval;
2369 int ndef = relation->rd_att->constr->num_defval;
2380 Anum_pg_attrdef_adrelid,
2381 BTEqualStrategyNumber, F_OIDEQ,
2382 ObjectIdGetDatum(RelationGetRelid(relation)));
2384 adrel = heap_open(AttrDefaultRelationId, AccessShareLock);
2385 adscan = systable_beginscan(adrel, AttrDefaultIndexId, true,
2386 SnapshotNow, 1, &skey);
2389 while (HeapTupleIsValid(htup = systable_getnext(adscan)))
2391 Form_pg_attrdef adform = (Form_pg_attrdef) GETSTRUCT(htup);
2393 for (i = 0; i < ndef; i++)
2395 if (adform->adnum != attrdef[i].adnum)
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));
2404 val = fastgetattr(htup,
2405 Anum_pg_attrdef_adbin,
2406 adrel->rd_att, &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));
2412 attrdef[i].adbin = MemoryContextStrdup(CacheMemoryContext,
2413 DatumGetCString(DirectFunctionCall1(textout,
2419 elog(WARNING, "unexpected attrdef record found for attr %d of rel %s",
2420 adform->adnum, RelationGetRelationName(relation));
2423 systable_endscan(adscan);
2424 heap_close(adrel, AccessShareLock);
2427 elog(WARNING, "%d attrdef record(s) missing for rel %s",
2428 ndef - found, RelationGetRelationName(relation));
2432 CheckConstraintFetch(Relation relation)
2434 ConstrCheck *check = relation->rd_att->constr->check;
2435 int ncheck = relation->rd_att->constr->num_check;
2437 SysScanDesc conscan;
2438 ScanKeyData skey[1];
2444 ScanKeyInit(&skey[0],
2445 Anum_pg_constraint_conrelid,
2446 BTEqualStrategyNumber, F_OIDEQ,
2447 ObjectIdGetDatum(RelationGetRelid(relation)));
2449 conrel = heap_open(ConstraintRelationId, AccessShareLock);
2450 conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true,
2451 SnapshotNow, 1, skey);
2453 while (HeapTupleIsValid(htup = systable_getnext(conscan)))
2455 Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup);
2457 /* We want check constraints only */
2458 if (conform->contype != CONSTRAINT_CHECK)
2461 if (found >= ncheck)
2462 elog(ERROR, "unexpected constraint record found for rel %s",
2463 RelationGetRelationName(relation));
2465 check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
2466 NameStr(conform->conname));
2468 /* Grab and test conbin is actually set */
2469 val = fastgetattr(htup,
2470 Anum_pg_constraint_conbin,
2471 conrel->rd_att, &isnull);
2473 elog(ERROR, "null conbin for rel %s",
2474 RelationGetRelationName(relation));
2476 check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
2477 DatumGetCString(DirectFunctionCall1(textout,
2482 systable_endscan(conscan);
2483 heap_close(conrel, AccessShareLock);
2485 if (found != ncheck)
2486 elog(ERROR, "%d constraint record(s) missing for rel %s",
2487 ncheck - found, RelationGetRelationName(relation));
2491 * RelationGetIndexList -- get a list of OIDs of indexes on this relation
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.
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.
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!
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.
2518 RelationGetIndexList(Relation relation)
2521 SysScanDesc indscan;
2526 MemoryContext oldcxt;
2528 /* Quick exit if we already computed the list. */
2529 if (relation->rd_indexvalid != 0)
2530 return list_copy(relation->rd_indexlist);
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.
2539 oidIndex = InvalidOid;
2541 /* Prepare to scan pg_index for entries having indrelid = this rel. */
2543 Anum_pg_index_indrelid,
2544 BTEqualStrategyNumber, F_OIDEQ,
2545 ObjectIdGetDatum(RelationGetRelid(relation)));
2547 indrel = heap_open(IndexRelationId, AccessShareLock);
2548 indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true,
2549 SnapshotNow, 1, &skey);
2551 while (HeapTupleIsValid(htup = systable_getnext(indscan)))
2553 Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
2555 /* Add index's OID to result list in the proper order */
2556 result = insert_ordered_oid(result, index->indexrelid);
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;
2567 systable_endscan(indscan);
2568 heap_close(indrel, AccessShareLock);
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);
2581 * insert_ordered_oid
2582 * Insert a new Oid into a sorted list of Oids, preserving ordering
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
2590 insert_ordered_oid(List *list, Oid datum)
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);
2601 ListCell *curr = lnext(prev);
2603 if (curr == NULL || datum < lfirst_oid(curr))
2604 break; /* it belongs after 'prev', before 'curr' */
2608 /* Insert datum into list after 'prev' */
2609 lappend_cell_oid(list, prev, datum);
2614 * RelationSetIndexList -- externally force the index list contents
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.
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).
2624 * It is up to the caller to make sure the given list is correctly ordered.
2627 RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
2629 MemoryContext oldcxt;
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;
2646 * RelationGetOidIndex -- get the pg_class OID of the relation's OID index
2648 * Returns InvalidOid if there is no such index.
2651 RelationGetOidIndex(Relation relation)
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
2660 Assert(relation->rd_rel->relhasoids);
2662 if (relation->rd_indexvalid == 0)
2664 /* RelationGetIndexList does the heavy lifting. */
2665 ilist = RelationGetIndexList(relation);
2667 Assert(relation->rd_indexvalid != 0);
2670 return relation->rd_oidindex;
2674 * RelationGetIndexExpressions -- get the index expressions for an index
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.)
2683 RelationGetIndexExpressions(Relation relation)
2689 MemoryContext oldcxt;
2691 /* Quick exit if we already computed the result. */
2692 if (relation->rd_indexprs)
2693 return (List *) copyObject(relation->rd_indexprs);
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))
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.
2705 exprsDatum = heap_getattr(relation->rd_indextuple,
2706 Anum_pg_index_indexprs,
2707 GetPgIndexDescriptor(),
2710 exprsString = DatumGetCString(DirectFunctionCall1(textout, exprsDatum));
2711 result = (List *) stringToNode(exprsString);
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.
2720 result = (List *) eval_const_expressions((Node *) result);
2723 * Also mark any coercion format fields as "don't care", so that the
2724 * planner can match to both explicit and implicit coercions.
2726 set_coercionform_dontcare((Node *) result);
2728 /* May as well fix opfuncids too */
2729 fix_opfuncids((Node *) result);
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);
2740 * RelationGetIndexPredicate -- get the index predicate for an index
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.)
2750 RelationGetIndexPredicate(Relation relation)
2756 MemoryContext oldcxt;
2758 /* Quick exit if we already computed the result. */
2759 if (relation->rd_indpred)
2760 return (List *) copyObject(relation->rd_indpred);
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))
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.
2772 predDatum = heap_getattr(relation->rd_indextuple,
2773 Anum_pg_index_indpred,
2774 GetPgIndexDescriptor(),
2777 predString = DatumGetCString(DirectFunctionCall1(textout, predDatum));
2778 result = (List *) stringToNode(predString);
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
2790 result = (List *) eval_const_expressions((Node *) result);
2792 result = (List *) canonicalize_qual((Expr *) result);
2795 * Also mark any coercion format fields as "don't care", so that the
2796 * planner can match to both explicit and implicit coercions.
2798 set_coercionform_dontcare((Node *) result);
2800 /* Also convert to implicit-AND format */
2801 result = make_ands_implicit((Expr *) result);
2803 /* May as well fix opfuncids too */
2804 fix_opfuncids((Node *) result);
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);
2816 * load_relcache_init_file, write_relcache_init_file
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.
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.
2827 * In order to get around the problem, we do the following:
2829 * + When the database system is initialized (at initdb time), we
2830 * don't use indexes. We do sequential scans.
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.
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.
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.
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.
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.
2857 * load_relcache_init_file -- attempt to load cache from the init file
2859 * If successful, return TRUE and set criticalRelcachesBuilt to true.
2860 * If not successful, return FALSE and set needNewCacheFile to true.
2862 * NOTE: we assume we are already switched into CacheMemoryContext.
2865 load_relcache_init_file(void)
2868 char initfilename[MAXPGPATH];
2878 snprintf(initfilename, sizeof(initfilename), "%s/%s",
2879 DatabasePath, RELCACHE_INIT_FILENAME);
2881 fp = AllocateFile(initfilename, PG_BINARY_R);
2884 needNewCacheFile = true;
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.
2894 rels = (Relation *) palloc(max_rels * sizeof(Relation));
2896 nailed_rels = nailed_indexes = 0;
2897 initFileRelationIds = NIL;
2899 /* check for correct magic number (compatible version) */
2900 if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
2902 if (magic != RELCACHE_INIT_FILEMAGIC)
2905 for (relno = 0;; relno++)
2910 Form_pg_class relform;
2912 Datum indclassDatum;
2915 /* first read the relation descriptor length */
2916 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2919 break; /* end of file */
2923 /* safety check for incompatible relcache layout */
2924 if (len != sizeof(RelationData))
2927 /* allocate another relcache header */
2928 if (num_rels >= max_rels)
2931 rels = (Relation *) repalloc(rels, max_rels * sizeof(Relation));
2934 rel = rels[num_rels++] = (Relation) palloc(len);
2936 /* then, read the Relation structure */
2937 if ((nread = fread(rel, 1, len, fp)) != len)
2940 /* next read the relation tuple form */
2941 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2944 relform = (Form_pg_class) palloc(len);
2945 if ((nread = fread(relform, 1, len, fp)) != len)
2948 rel->rd_rel = relform;
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... */
2956 /* next read all the attribute tuple form data entries */
2957 has_not_null = false;
2958 for (i = 0; i < relform->relnatts; i++)
2960 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2962 if (len != ATTRIBUTE_TUPLE_SIZE)
2964 if ((nread = fread(rel->rd_att->attrs[i], 1, len, fp)) != len)
2967 has_not_null |= rel->rd_att->attrs[i]->attnotnull;
2970 /* mark not-null status */
2973 TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
2975 constr->has_not_null = true;
2976 rel->rd_att->constr = constr;
2979 /* If it's an index, there's more to do */
2980 if (rel->rd_rel->relkind == RELKIND_INDEX)
2983 MemoryContext indexcxt;
2985 RegProcedure *support;
2988 /* Count nailed indexes to ensure we have 'em all */
2989 if (rel->rd_isnailed)
2992 /* next, read the pg_index tuple */
2993 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
2996 rel->rd_indextuple = (HeapTuple) palloc(len);
2997 if ((nread = fread(rel->rd_indextuple, 1, len, fp)) != len)
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);
3004 /* fix up indclass pointer too */
3005 indclassDatum = fastgetattr(rel->rd_indextuple,
3006 Anum_pg_index_indclass,
3007 GetPgIndexDescriptor(),
3010 rel->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum);
3012 /* next, read the access method tuple form */
3013 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3016 am = (Form_pg_am) palloc(len);
3017 if ((nread = fread(am, 1, len, fp)) != len)
3022 * prepare index info context --- parameters should match
3023 * RelationInitIndexAccessInfo
3025 indexcxt = AllocSetContextCreate(CacheMemoryContext,
3026 RelationGetRelationName(rel),
3027 ALLOCSET_SMALL_MINSIZE,
3028 ALLOCSET_SMALL_INITSIZE,
3029 ALLOCSET_SMALL_MAXSIZE);
3030 rel->rd_indexcxt = indexcxt;
3032 /* next, read the vector of operator OIDs */
3033 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3036 operator = (Oid *) MemoryContextAlloc(indexcxt, len);
3037 if ((nread = fread(operator, 1, len, fp)) != len)
3040 rel->rd_operator = operator;
3042 /* finally, read the vector of support procedures */
3043 if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3045 support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
3046 if ((nread = fread(support, 1, len, fp)) != len)
3049 rel->rd_support = support;
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));
3060 /* Count nailed rels to ensure we have 'em all */
3061 if (rel->rd_isnailed)
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);
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.
3082 rel->rd_rules = NULL;
3083 rel->rd_rulescxt = NULL;
3084 rel->trigdesc = NULL;
3085 rel->rd_indexprs = NIL;
3086 rel->rd_indpred = NIL;
3089 * Reset transient-state fields in the relcache entry
3091 rel->rd_smgr = NULL;
3092 rel->rd_targblock = InvalidBlockNumber;
3093 if (rel->rd_isnailed)
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));
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.
3108 RelationInitLockInfo(rel);
3109 RelationInitPhysicalAddr(rel);
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.)
3117 if (nailed_rels != NUM_CRITICAL_RELS ||
3118 nailed_indexes != NUM_CRITICAL_INDEXES)
3122 * OK, all appears well.
3124 * Now insert all the new relcache entries into the cache.
3126 for (relno = 0; relno < num_rels; relno++)
3128 RelationCacheInsert(rels[relno]);
3129 /* also make a list of their OIDs, for RelationIdIsInInitFile */
3130 initFileRelationIds = lcons_oid(RelationGetRelid(rels[relno]),
3131 initFileRelationIds);
3137 criticalRelcachesBuilt = true;
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
3149 needNewCacheFile = true;
3154 * Write out a new initialization file with the current contents
3158 write_relcache_init_file(void)
3161 char tempfilename[MAXPGPATH];
3162 char finalfilename[MAXPGPATH];
3164 HASH_SEQ_STATUS status;
3165 RelIdCacheEnt *idhentry;
3166 MemoryContext oldcxt;
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.
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);
3179 unlink(tempfilename); /* in case it exists w/wrong permissions */
3181 fp = AllocateFile(tempfilename, PG_BINARY_W);
3185 * We used to consider this a fatal error, but we might as well
3186 * continue with backend startup ...
3189 (errcode_for_file_access(),
3190 errmsg("could not create relation-cache initialization file \"%s\": %m",
3192 errdetail("Continuing anyway, but there's something wrong.")));
3197 * Write a magic number to serve as a file version identifier. We can
3198 * change the magic number whenever the relcache layout changes.
3200 magic = RELCACHE_INIT_FILEMAGIC;
3201 if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
3202 elog(FATAL, "could not write init file");
3205 * Write all the reldescs (in no particular order).
3207 hash_seq_init(&status, RelationIdCache);
3209 initFileRelationIds = NIL;
3211 while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3213 Relation rel = idhentry->reldesc;
3214 Form_pg_class relform = rel->rd_rel;
3218 * first write the relcache entry proper
3220 len = sizeof(RelationData);
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");
3226 /* next, write out the Relation structure */
3227 if (fwrite(rel, 1, len, fp) != len)
3228 elog(FATAL, "could not write init file");
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");
3235 if (fwrite(relform, 1, len, fp) != len)
3236 elog(FATAL, "could not write init file");
3238 /* next, do all the attribute tuple form data entries */
3239 for (i = 0; i < relform->relnatts; i++)
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");
3248 /* If it's an index, there's more to do */
3249 if (rel->rd_rel->relkind == RELKIND_INDEX)
3251 Form_pg_am am = rel->rd_am;
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");
3259 if (fwrite(rel->rd_indextuple, 1, len, fp) != len)
3260 elog(FATAL, "could not write init file");
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");
3267 if (fwrite(am, 1, len, fp) != len)
3268 elog(FATAL, "could not write init file");
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");
3275 if (fwrite(rel->rd_operator, 1, len, fp) != len)
3276 elog(FATAL, "could not write init file");
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");
3283 if (fwrite(rel->rd_support, 1, len, fp) != len)
3284 elog(FATAL, "could not write init file");
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);
3295 elog(FATAL, "could not write init file");
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.)
3305 * This mustn't run concurrently with RelationCacheInitFileInvalidate, so
3306 * grab a serialization lock for the duration.
3308 LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3310 /* Make sure we have seen all incoming SI messages */
3311 AcceptInvalidationMessages();
3314 * If we have received any SI relcache invals since backend start, assume
3315 * we may have written out-of-date data.
3317 if (relcacheInvalsReceived == 0L)
3320 * OK, rename the temp file to its final name, deleting any
3321 * previously-existing init file.
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
3328 if (rename(tempfilename, finalfilename) < 0)
3329 unlink(tempfilename);
3333 /* Delete the already-obsolete temp file */
3334 unlink(tempfilename);
3337 LWLockRelease(RelCacheInitLock);
3341 * Detect whether a given relation (identified by OID) is one of the ones
3342 * we store in the init file.
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.
3350 RelationIdIsInInitFile(Oid relationId)
3352 return list_member_oid(initFileRelationIds, relationId);
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
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.
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.
3375 RelationCacheInitFileInvalidate(bool beforeSend)
3377 char initfilename[MAXPGPATH];
3379 snprintf(initfilename, sizeof(initfilename), "%s/%s",
3380 DatabasePath, RELCACHE_INIT_FILENAME);
3384 /* no interlock needed here */
3385 unlink(initfilename);
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.
3397 LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3398 unlink(initfilename);
3399 LWLockRelease(RelCacheInitLock);