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.215 2005-01-10 20:02:23 tgl Exp $
13
*-------------------------------------------------------------------------
17
* RelationCacheInitialize - initialize relcache
18
* RelationCacheInitializePhase2 - finish initializing relcache
19
* RelationIdGetRelation - get a reldesc by relation id
20
* RelationSysNameGetRelation - get a reldesc by system rel name
21
* RelationIdCacheGetRelation - get a cached reldesc by relid
22
* RelationClose - close an open relation
25
* The following code contains many undocumented hacks. Please be
35
#include "access/genam.h"
36
#include "access/heapam.h"
37
#include "catalog/catalog.h"
38
#include "catalog/catname.h"
39
#include "catalog/indexing.h"
40
#include "catalog/namespace.h"
41
#include "catalog/pg_amop.h"
42
#include "catalog/pg_amproc.h"
43
#include "catalog/pg_attrdef.h"
44
#include "catalog/pg_attribute.h"
45
#include "catalog/pg_constraint.h"
46
#include "catalog/pg_index.h"
47
#include "catalog/pg_namespace.h"
48
#include "catalog/pg_opclass.h"
49
#include "catalog/pg_proc.h"
50
#include "catalog/pg_rewrite.h"
51
#include "catalog/pg_type.h"
52
#include "commands/trigger.h"
53
#include "miscadmin.h"
54
#include "optimizer/clauses.h"
55
#include "optimizer/planmain.h"
56
#include "optimizer/prep.h"
57
#include "storage/fd.h"
58
#include "storage/smgr.h"
59
#include "utils/builtins.h"
60
#include "utils/catcache.h"
61
#include "utils/fmgroids.h"
62
#include "utils/inval.h"
63
#include "utils/lsyscache.h"
64
#include "utils/relcache.h"
65
#include "utils/resowner.h"
66
#include "utils/syscache.h"
67
#include "utils/typcache.h"
71
* name of relcache init file, used to speed up backend startup
73
#define RELCACHE_INIT_FILENAME "pg_internal.init"
75
#define RELCACHE_INIT_FILEMAGIC 0x573262 /* version ID value */
78
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
80
static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
81
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
82
static FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
83
static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
86
* Hash tables that index the relation cache
88
* Relations are looked up two ways, by OID and by name,
89
* thus there are two hash tables for referencing them.
91
* The OID index covers all relcache entries. The name index
92
* covers *only* system relations (only those in PG_CATALOG_NAMESPACE).
94
static HTAB *RelationIdCache;
95
static HTAB *RelationSysNameCache;
98
* This flag is false until we have prepared the critical relcache entries
99
* that are needed to do indexscans on the tables read by relcache building.
101
bool criticalRelcachesBuilt = false;
104
* This flag is set if we discover that we need to write a new relcache
105
* cache file at the end of startup.
107
static bool needNewCacheFile = false;
110
* This counter counts relcache inval events received since backend startup
111
* (but only for rels that are actually in cache). Presently, we use it only
112
* to detect whether data about to be written by write_relcache_init_file()
113
* might already be obsolete.
115
static long relcacheInvalsReceived = 0L;
118
* This list remembers the OIDs of the relations cached in the relcache
121
static List *initFileRelationIds = NIL;
124
* This flag lets us optimize away work in AtEOSubXact_RelationCache().
126
static bool need_eosubxact_work = false;
129
* RelationBuildDescInfo exists so code can be shared
130
* between RelationIdGetRelation() and RelationSysNameGetRelation()
132
typedef struct RelationBuildDescInfo
134
int infotype; /* lookup by id or by name */
136
#define INFO_RELNAME 2
139
Oid info_id; /* relation object id */
140
char *info_name; /* system relation name */
142
} RelationBuildDescInfo;
144
typedef struct relidcacheent
150
typedef struct relnamecacheent
157
* macros to manipulate the lookup hashtables
159
#define RelationCacheInsert(RELATION) \
161
RelIdCacheEnt *idhentry; bool found; \
162
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
163
(void *) &(RELATION->rd_id), \
166
if (idhentry == NULL) \
168
(errcode(ERRCODE_OUT_OF_MEMORY), \
169
errmsg("out of memory"))); \
170
/* used to give notice if found -- now just keep quiet */ \
171
idhentry->reldesc = RELATION; \
172
if (IsSystemNamespace(RelationGetNamespace(RELATION))) \
174
char *relname = RelationGetRelationName(RELATION); \
175
RelNameCacheEnt *namehentry; \
176
namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \
180
if (namehentry == NULL) \
182
(errcode(ERRCODE_OUT_OF_MEMORY), \
183
errmsg("out of memory"))); \
184
/* used to give notice if found -- now just keep quiet */ \
185
namehentry->reldesc = RELATION; \
189
#define RelationIdCacheLookup(ID, RELATION) \
191
RelIdCacheEnt *hentry; \
192
hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
193
(void *)&(ID), HASH_FIND,NULL); \
195
RELATION = hentry->reldesc; \
200
#define RelationSysNameCacheLookup(NAME, RELATION) \
202
RelNameCacheEnt *hentry; \
203
hentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \
204
(void *) (NAME), HASH_FIND,NULL); \
206
RELATION = hentry->reldesc; \
211
#define RelationCacheDelete(RELATION) \
213
RelIdCacheEnt *idhentry; \
214
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
215
(void *)&(RELATION->rd_id), \
216
HASH_REMOVE, NULL); \
217
if (idhentry == NULL) \
218
elog(WARNING, "trying to delete a rd_id reldesc that does not exist"); \
219
if (IsSystemNamespace(RelationGetNamespace(RELATION))) \
221
char *relname = RelationGetRelationName(RELATION); \
222
RelNameCacheEnt *namehentry; \
223
namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \
225
HASH_REMOVE, NULL); \
226
if (namehentry == NULL) \
227
elog(WARNING, "trying to delete a relname reldesc that does not exist"); \
233
* Special cache for opclass-related information
235
* Note: only default-subtype operators and support procs get cached
237
typedef struct opclasscacheent
239
Oid opclassoid; /* lookup key: OID of opclass */
240
bool valid; /* set TRUE after successful fill-in */
241
StrategyNumber numStrats; /* max # of strategies (from pg_am) */
242
StrategyNumber numSupport; /* max # of support procs (from pg_am) */
243
Oid *operatorOids; /* strategy operators' OIDs */
244
RegProcedure *supportProcs; /* support procs */
247
static HTAB *OpClassCache = NULL;
250
/* non-export function prototypes */
252
static void RelationClearRelation(Relation relation, bool rebuild);
254
static void RelationReloadClassinfo(Relation relation);
255
static void RelationFlushRelation(Relation relation);
256
static Relation RelationSysNameCacheGetRelation(const char *relationName);
257
static bool load_relcache_init_file(void);
258
static void write_relcache_init_file(void);
260
static void formrdesc(const char *relationName, Oid relationReltype,
261
bool hasoids, int natts, FormData_pg_attribute *att);
263
static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK);
264
static Relation AllocateRelationDesc(Relation relation, Form_pg_class relp);
265
static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
267
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
268
Relation oldrelation);
269
static void RelationInitPhysicalAddr(Relation relation);
270
static void AttrDefaultFetch(Relation relation);
271
static void CheckConstraintFetch(Relation relation);
272
static List *insert_ordered_oid(List *list, Oid datum);
273
static void IndexSupportInitialize(Form_pg_index iform,
275
RegProcedure *indexSupport,
276
StrategyNumber maxStrategyNumber,
277
StrategyNumber maxSupportNumber,
278
AttrNumber maxAttributeNumber);
279
static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
280
StrategyNumber numStrats,
281
StrategyNumber numSupport);
287
* this is used by RelationBuildDesc to find a pg_class
288
* tuple matching either a relation name or a relation id
289
* as specified in buildinfo.
291
* NB: the returned tuple has been copied into palloc'd storage
292
* and must eventually be freed with heap_freetuple.
295
ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
297
HeapTuple pg_class_tuple;
298
Relation pg_class_desc;
299
const char *indexRelname;
300
SysScanDesc pg_class_scan;
307
switch (buildinfo.infotype)
311
ObjectIdAttributeNumber,
312
BTEqualStrategyNumber, F_OIDEQ,
313
ObjectIdGetDatum(buildinfo.i.info_id));
315
indexRelname = ClassOidIndex;
320
Anum_pg_class_relname,
321
BTEqualStrategyNumber, F_NAMEEQ,
322
NameGetDatum(buildinfo.i.info_name));
324
Anum_pg_class_relnamespace,
325
BTEqualStrategyNumber, F_OIDEQ,
326
ObjectIdGetDatum(PG_CATALOG_NAMESPACE));
328
indexRelname = ClassNameNspIndex;
332
elog(ERROR, "unrecognized buildinfo type: %d",
334
return NULL; /* keep compiler quiet */
338
* Open pg_class and fetch a tuple. Force heap scan if we haven't yet
339
* built the critical relcache entries (this includes initdb and
340
* startup without a pg_internal.init file). The caller can also
341
* force a heap scan by setting indexOK == false.
343
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
344
pg_class_scan = systable_beginscan(pg_class_desc, indexRelname,
345
indexOK && criticalRelcachesBuilt,
349
pg_class_tuple = systable_getnext(pg_class_scan);
352
* Must copy tuple before releasing buffer.
354
if (HeapTupleIsValid(pg_class_tuple))
355
pg_class_tuple = heap_copytuple(pg_class_tuple);
358
systable_endscan(pg_class_scan);
359
heap_close(pg_class_desc, AccessShareLock);
361
return pg_class_tuple;
365
* AllocateRelationDesc
367
* This is used to allocate memory for a new relation descriptor
368
* and initialize the rd_rel field.
370
* If 'relation' is NULL, allocate a new RelationData object.
371
* If not, reuse the given object (that path is taken only when
372
* we have to rebuild a relcache entry during RelationClearRelation).
375
AllocateRelationDesc(Relation relation, Form_pg_class relp)
377
MemoryContext oldcxt;
378
Form_pg_class relationForm;
380
/* Relcache entries must live in CacheMemoryContext */
381
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
384
* allocate space for new relation descriptor, if needed
386
if (relation == NULL)
387
relation = (Relation) palloc(sizeof(RelationData));
390
* clear all fields of reldesc
392
MemSet((char *) relation, 0, sizeof(RelationData));
393
relation->rd_targblock = InvalidBlockNumber;
395
/* make sure relation is marked as having no open file yet */
396
relation->rd_smgr = NULL;
399
* Copy the relation tuple form
401
* We only allocate space for the fixed fields, ie, CLASS_TUPLE_SIZE.
402
* relacl is NOT stored in the relcache --- there'd be little point in
403
* it, since we don't copy the tuple's nullvalues bitmap and hence
404
* wouldn't know if the value is valid ... bottom line is that relacl
405
* *cannot* be retrieved from the relcache. Get it from the syscache
408
relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
410
memcpy((char *) relationForm, (char *) relp, CLASS_TUPLE_SIZE);
412
/* initialize relation tuple form */
413
relation->rd_rel = relationForm;
415
/* and allocate attribute tuple form storage */
416
relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts,
417
relationForm->relhasoids);
419
MemoryContextSwitchTo(oldcxt);
425
* RelationBuildTupleDesc
427
* Form the relation's tuple descriptor from information in
428
* the pg_attribute, pg_attrdef & pg_constraint system catalogs.
431
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
434
HeapTuple pg_attribute_tuple;
435
Relation pg_attribute_desc;
436
SysScanDesc pg_attribute_scan;
440
AttrDefault *attrdef = NULL;
443
/* copy some fields from pg_class row to rd_att */
444
relation->rd_att->tdtypeid = relation->rd_rel->reltype;
445
relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
446
relation->rd_att->tdhasoid = relation->rd_rel->relhasoids;
448
constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
449
sizeof(TupleConstr));
450
constr->has_not_null = false;
453
* Form a scan key that selects only user attributes (attnum > 0).
454
* (Eliminating system attribute rows at the index level is lots
455
* faster than fetching them.)
457
ScanKeyInit(&skey[0],
458
Anum_pg_attribute_attrelid,
459
BTEqualStrategyNumber, F_OIDEQ,
460
ObjectIdGetDatum(RelationGetRelid(relation)));
461
ScanKeyInit(&skey[1],
462
Anum_pg_attribute_attnum,
463
BTGreaterStrategyNumber, F_INT2GT,
467
* Open pg_attribute and begin a scan. Force heap scan if we haven't
468
* yet built the critical relcache entries (this includes initdb and
469
* startup without a pg_internal.init file).
471
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
472
pg_attribute_scan = systable_beginscan(pg_attribute_desc,
473
AttributeRelidNumIndex,
474
criticalRelcachesBuilt,
479
* add attribute data to relation->rd_att
481
need = relation->rd_rel->relnatts;
483
while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
485
Form_pg_attribute attp;
487
attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
489
if (attp->attnum <= 0 ||
490
attp->attnum > relation->rd_rel->relnatts)
491
elog(ERROR, "invalid attribute number %d for %s",
492
attp->attnum, RelationGetRelationName(relation));
494
relation->rd_att->attrs[attp->attnum - 1] =
495
(Form_pg_attribute) MemoryContextAlloc(CacheMemoryContext,
496
ATTRIBUTE_TUPLE_SIZE);
498
memcpy((char *) (relation->rd_att->attrs[attp->attnum - 1]),
500
ATTRIBUTE_TUPLE_SIZE);
502
/* Update constraint/default info */
503
if (attp->attnotnull)
504
constr->has_not_null = true;
509
attrdef = (AttrDefault *)
510
MemoryContextAllocZero(CacheMemoryContext,
511
relation->rd_rel->relnatts *
512
sizeof(AttrDefault));
513
attrdef[ndef].adnum = attp->attnum;
514
attrdef[ndef].adbin = NULL;
523
* end the scan and close the attribute relation
525
systable_endscan(pg_attribute_scan);
526
heap_close(pg_attribute_desc, AccessShareLock);
529
elog(ERROR, "catalog is missing %d attribute(s) for relid %u",
530
need, RelationGetRelid(relation));
533
* The attcacheoff values we read from pg_attribute should all be -1
534
* ("unknown"). Verify this if assert checking is on. They will be
535
* computed when and if needed during tuple access.
537
#ifdef USE_ASSERT_CHECKING
541
for (i = 0; i < relation->rd_rel->relnatts; i++)
542
Assert(relation->rd_att->attrs[i]->attcacheoff == -1);
547
* However, we can easily set the attcacheoff value for the first
548
* attribute: it must be zero. This eliminates the need for special
549
* cases for attnum=1 that used to exist in fastgetattr() and
552
if (relation->rd_rel->relnatts > 0)
553
relation->rd_att->attrs[0]->attcacheoff = 0;
556
* Set up constraint/default info
558
if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
560
relation->rd_att->constr = constr;
562
if (ndef > 0) /* DEFAULTs */
564
if (ndef < relation->rd_rel->relnatts)
565
constr->defval = (AttrDefault *)
566
repalloc(attrdef, ndef * sizeof(AttrDefault));
568
constr->defval = attrdef;
569
constr->num_defval = ndef;
570
AttrDefaultFetch(relation);
573
constr->num_defval = 0;
575
if (relation->rd_rel->relchecks > 0) /* CHECKs */
577
constr->num_check = relation->rd_rel->relchecks;
578
constr->check = (ConstrCheck *)
579
MemoryContextAllocZero(CacheMemoryContext,
580
constr->num_check * sizeof(ConstrCheck));
581
CheckConstraintFetch(relation);
584
constr->num_check = 0;
589
relation->rd_att->constr = NULL;
594
* RelationBuildRuleLock
596
* Form the relation's rewrite rules from information in
597
* the pg_rewrite system catalog.
599
* Note: The rule parsetrees are potentially very complex node structures.
600
* To allow these trees to be freed when the relcache entry is flushed,
601
* we make a private memory context to hold the RuleLock information for
602
* each relcache entry that has associated rules. The context is used
603
* just for rule info, not for any other subsidiary data of the relcache
604
* entry, because that keeps the update logic in RelationClearRelation()
605
* manageable. The other subsidiary data structures are simple enough
606
* to be easy to free explicitly, anyway.
609
RelationBuildRuleLock(Relation relation)
611
MemoryContext rulescxt;
612
MemoryContext oldcxt;
613
HeapTuple rewrite_tuple;
614
Relation rewrite_desc;
615
TupleDesc rewrite_tupdesc;
616
SysScanDesc rewrite_scan;
624
* Make the private context. Parameters are set on the assumption
625
* that it'll probably not contain much data.
627
rulescxt = AllocSetContextCreate(CacheMemoryContext,
628
RelationGetRelationName(relation),
629
ALLOCSET_SMALL_MINSIZE,
630
ALLOCSET_SMALL_INITSIZE,
631
ALLOCSET_SMALL_MAXSIZE);
632
relation->rd_rulescxt = rulescxt;
635
* allocate an array to hold the rewrite rules (the array is extended
639
rules = (RewriteRule **)
640
MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
647
Anum_pg_rewrite_ev_class,
648
BTEqualStrategyNumber, F_OIDEQ,
649
ObjectIdGetDatum(RelationGetRelid(relation)));
652
* open pg_rewrite and begin a scan
654
* Note: since we scan the rules using RewriteRelRulenameIndex, we will
655
* be reading the rules in name order, except possibly during
656
* emergency-recovery operations (ie, IsIgnoringSystemIndexes). This
657
* in turn ensures that rules will be fired in name order.
659
rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
660
rewrite_tupdesc = RelationGetDescr(rewrite_desc);
661
rewrite_scan = systable_beginscan(rewrite_desc,
662
RewriteRelRulenameIndex,
666
while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan)))
668
Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(rewrite_tuple);
672
char *ruleaction_str;
673
char *rule_evqual_str;
676
rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
677
sizeof(RewriteRule));
679
rule->ruleId = HeapTupleGetOid(rewrite_tuple);
681
rule->event = rewrite_form->ev_type - '0';
682
rule->attrno = rewrite_form->ev_attr;
683
rule->isInstead = rewrite_form->is_instead;
685
/* Must use heap_getattr to fetch ev_qual and ev_action */
687
ruleaction = heap_getattr(rewrite_tuple,
688
Anum_pg_rewrite_ev_action,
692
ruleaction_str = DatumGetCString(DirectFunctionCall1(textout,
694
oldcxt = MemoryContextSwitchTo(rulescxt);
695
rule->actions = (List *) stringToNode(ruleaction_str);
696
MemoryContextSwitchTo(oldcxt);
697
pfree(ruleaction_str);
699
rule_evqual = heap_getattr(rewrite_tuple,
700
Anum_pg_rewrite_ev_qual,
704
rule_evqual_str = DatumGetCString(DirectFunctionCall1(textout,
706
oldcxt = MemoryContextSwitchTo(rulescxt);
707
rule->qual = (Node *) stringToNode(rule_evqual_str);
708
MemoryContextSwitchTo(oldcxt);
709
pfree(rule_evqual_str);
711
if (numlocks >= maxlocks)
714
rules = (RewriteRule **)
715
repalloc(rules, sizeof(RewriteRule *) * maxlocks);
717
rules[numlocks++] = rule;
721
* end the scan and close the attribute relation
723
systable_endscan(rewrite_scan);
724
heap_close(rewrite_desc, AccessShareLock);
727
* form a RuleLock and insert into relation
729
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
730
rulelock->numLocks = numlocks;
731
rulelock->rules = rules;
733
relation->rd_rules = rulelock;
739
* Determine whether two RuleLocks are equivalent
741
* Probably this should be in the rules code someplace...
744
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
749
* As of 7.3 we assume the rule ordering is repeatable, because
750
* RelationBuildRuleLock should read 'em in a consistent order. So
751
* just compare corresponding slots.
757
if (rlock1->numLocks != rlock2->numLocks)
759
for (i = 0; i < rlock1->numLocks; i++)
761
RewriteRule *rule1 = rlock1->rules[i];
762
RewriteRule *rule2 = rlock2->rules[i];
764
if (rule1->ruleId != rule2->ruleId)
766
if (rule1->event != rule2->event)
768
if (rule1->attrno != rule2->attrno)
770
if (rule1->isInstead != rule2->isInstead)
772
if (!equal(rule1->qual, rule2->qual))
774
if (!equal(rule1->actions, rule2->actions))
778
else if (rlock2 != NULL)
784
/* ----------------------------------
787
* Build a relation descriptor --- either a new one, or by
788
* recycling the given old relation object. The latter case
789
* supports rebuilding a relcache entry without invalidating
791
* --------------------------------
794
RelationBuildDesc(RelationBuildDescInfo buildinfo,
795
Relation oldrelation)
799
HeapTuple pg_class_tuple;
801
MemoryContext oldcxt;
804
* find the tuple in pg_class corresponding to the given relation id
806
pg_class_tuple = ScanPgRelation(buildinfo, true);
809
* if no such tuple exists, return NULL
811
if (!HeapTupleIsValid(pg_class_tuple))
815
* get information from the pg_class_tuple
817
relid = HeapTupleGetOid(pg_class_tuple);
818
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
821
* allocate storage for the relation descriptor, and copy
822
* pg_class_tuple to relation->rd_rel.
824
relation = AllocateRelationDesc(oldrelation, relp);
827
* now we can free the memory allocated for pg_class_tuple
829
heap_freetuple(pg_class_tuple);
832
* initialize the relation's relation id (relation->rd_id)
834
RelationGetRelid(relation) = relid;
837
* normal relations are not nailed into the cache; nor can a
838
* pre-existing relation be new. It could be temp though. (Actually,
839
* it could be new too, but it's okay to forget that fact if forced to
842
relation->rd_refcnt = 0;
843
relation->rd_isnailed = false;
844
relation->rd_createSubid = InvalidSubTransactionId;
845
relation->rd_istemp = isTempNamespace(relation->rd_rel->relnamespace);
848
* initialize the tuple descriptor (relation->rd_att).
850
RelationBuildTupleDesc(buildinfo, relation);
853
* Fetch rules and triggers that affect this relation
855
if (relation->rd_rel->relhasrules)
856
RelationBuildRuleLock(relation);
859
relation->rd_rules = NULL;
860
relation->rd_rulescxt = NULL;
863
if (relation->rd_rel->reltriggers > 0)
864
RelationBuildTriggers(relation);
866
relation->trigdesc = NULL;
869
* if it's an index, initialize index-related information
871
if (OidIsValid(relation->rd_rel->relam))
872
RelationInitIndexAccessInfo(relation);
875
* initialize the relation lock manager information
877
RelationInitLockInfo(relation); /* see lmgr.c */
880
* initialize physical addressing information for the relation
882
RelationInitPhysicalAddr(relation);
884
/* make sure relation is marked as having no open file yet */
885
relation->rd_smgr = NULL;
888
* Insert newly created relation into relcache hash tables.
890
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
891
RelationCacheInsert(relation);
892
MemoryContextSwitchTo(oldcxt);
894
/* It's fully valid */
895
relation->rd_isvalid = true;
901
* Initialize the physical addressing info (RelFileNode) for a relcache entry
904
RelationInitPhysicalAddr(Relation relation)
906
if (relation->rd_rel->reltablespace)
907
relation->rd_node.spcNode = relation->rd_rel->reltablespace;
909
relation->rd_node.spcNode = MyDatabaseTableSpace;
910
if (relation->rd_rel->relisshared)
911
relation->rd_node.dbNode = InvalidOid;
913
relation->rd_node.dbNode = MyDatabaseId;
914
relation->rd_node.relNode = relation->rd_rel->relfilenode;
918
* Initialize index-access-method support data for an index relation
921
RelationInitIndexAccessInfo(Relation relation)
925
MemoryContext indexcxt;
926
MemoryContext oldcontext;
928
RegProcedure *support;
929
FmgrInfo *supportinfo;
935
* Make a copy of the pg_index entry for the index. Since pg_index
936
* contains variable-length and possibly-null fields, we have to do
937
* this honestly rather than just treating it as a Form_pg_index
940
tuple = SearchSysCache(INDEXRELID,
941
ObjectIdGetDatum(RelationGetRelid(relation)),
943
if (!HeapTupleIsValid(tuple))
944
elog(ERROR, "cache lookup failed for index %u",
945
RelationGetRelid(relation));
946
oldcontext = MemoryContextSwitchTo(CacheMemoryContext);
947
relation->rd_indextuple = heap_copytuple(tuple);
948
relation->rd_index = (Form_pg_index) GETSTRUCT(relation->rd_indextuple);
949
MemoryContextSwitchTo(oldcontext);
950
ReleaseSysCache(tuple);
953
* Make a copy of the pg_am entry for the index's access method
955
tuple = SearchSysCache(AMOID,
956
ObjectIdGetDatum(relation->rd_rel->relam),
958
if (!HeapTupleIsValid(tuple))
959
elog(ERROR, "cache lookup failed for access method %u",
960
relation->rd_rel->relam);
961
aform = (Form_pg_am) MemoryContextAlloc(CacheMemoryContext, sizeof *aform);
962
memcpy(aform, GETSTRUCT(tuple), sizeof *aform);
963
ReleaseSysCache(tuple);
964
relation->rd_am = aform;
966
natts = relation->rd_rel->relnatts;
967
if (natts != relation->rd_index->indnatts)
968
elog(ERROR, "relnatts disagrees with indnatts for index %u",
969
RelationGetRelid(relation));
970
amstrategies = aform->amstrategies;
971
amsupport = aform->amsupport;
974
* Make the private context to hold index access info. The reason we
975
* need a context, and not just a couple of pallocs, is so that we
976
* won't leak any subsidiary info attached to fmgr lookup records.
978
* Context parameters are set on the assumption that it'll probably not
981
indexcxt = AllocSetContextCreate(CacheMemoryContext,
982
RelationGetRelationName(relation),
983
ALLOCSET_SMALL_MINSIZE,
984
ALLOCSET_SMALL_INITSIZE,
985
ALLOCSET_SMALL_MAXSIZE);
986
relation->rd_indexcxt = indexcxt;
989
* Allocate arrays to hold data
991
if (amstrategies > 0)
993
MemoryContextAllocZero(indexcxt,
994
natts * amstrategies * sizeof(Oid));
1000
int nsupport = natts * amsupport;
1002
support = (RegProcedure *)
1003
MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
1004
supportinfo = (FmgrInfo *)
1005
MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
1013
relation->rd_operator = operator;
1014
relation->rd_support = support;
1015
relation->rd_supportinfo = supportinfo;
1018
* Fill the operator and support procedure OID arrays. (supportinfo is
1019
* left as zeroes, and is filled on-the-fly when used)
1021
IndexSupportInitialize(relation->rd_index,
1023
amstrategies, amsupport, natts);
1026
* expressions and predicate cache will be filled later
1028
relation->rd_indexprs = NIL;
1029
relation->rd_indpred = NIL;
1033
* IndexSupportInitialize
1034
* Initializes an index's cached opclass information,
1035
* given the index's pg_index tuple.
1037
* Data is returned into *indexOperator and *indexSupport, which are arrays
1038
* allocated by the caller.
1040
* The caller also passes maxStrategyNumber, maxSupportNumber, and
1041
* maxAttributeNumber, since these indicate the size of the arrays
1042
* it has allocated --- but in practice these numbers must always match
1043
* those obtainable from the system catalog entries for the index and
1047
IndexSupportInitialize(Form_pg_index iform,
1049
RegProcedure *indexSupport,
1050
StrategyNumber maxStrategyNumber,
1051
StrategyNumber maxSupportNumber,
1052
AttrNumber maxAttributeNumber)
1057
* XXX note that the following assumes the INDEX tuple is well formed
1058
* and that the *key and *class are 0 terminated.
1060
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
1062
OpClassCacheEnt *opcentry;
1064
if (!OidIsValid(iform->indclass[attIndex]))
1065
elog(ERROR, "bogus pg_index tuple");
1067
/* look up the info for this opclass, using a cache */
1068
opcentry = LookupOpclassInfo(iform->indclass[attIndex],
1072
/* copy cached data into relcache entry */
1073
if (maxStrategyNumber > 0)
1074
memcpy(&indexOperator[attIndex * maxStrategyNumber],
1075
opcentry->operatorOids,
1076
maxStrategyNumber * sizeof(Oid));
1077
if (maxSupportNumber > 0)
1078
memcpy(&indexSupport[attIndex * maxSupportNumber],
1079
opcentry->supportProcs,
1080
maxSupportNumber * sizeof(RegProcedure));
1087
* This routine maintains a per-opclass cache of the information needed
1088
* by IndexSupportInitialize(). This is more efficient than relying on
1089
* the catalog cache, because we can load all the info about a particular
1090
* opclass in a single indexscan of pg_amproc or pg_amop.
1092
* The information from pg_am about expected range of strategy and support
1093
* numbers is passed in, rather than being looked up, mainly because the
1094
* caller will have it already.
1096
* XXX There isn't any provision for flushing the cache. However, there
1097
* isn't any provision for flushing relcache entries when opclass info
1098
* changes, either :-(
1100
static OpClassCacheEnt *
1101
LookupOpclassInfo(Oid operatorClassOid,
1102
StrategyNumber numStrats,
1103
StrategyNumber numSupport)
1105
OpClassCacheEnt *opcentry;
1109
ScanKeyData skey[2];
1113
if (OpClassCache == NULL)
1115
/* First time through: initialize the opclass cache */
1118
if (!CacheMemoryContext)
1119
CreateCacheMemoryContext();
1121
MemSet(&ctl, 0, sizeof(ctl));
1122
ctl.keysize = sizeof(Oid);
1123
ctl.entrysize = sizeof(OpClassCacheEnt);
1124
ctl.hash = tag_hash;
1125
OpClassCache = hash_create("Operator class cache", 64,
1126
&ctl, HASH_ELEM | HASH_FUNCTION);
1129
opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
1130
(void *) &operatorClassOid,
1131
HASH_ENTER, &found);
1132
if (opcentry == NULL)
1134
(errcode(ERRCODE_OUT_OF_MEMORY),
1135
errmsg("out of memory")));
1137
if (found && opcentry->valid)
1139
/* Already made an entry for it */
1140
Assert(numStrats == opcentry->numStrats);
1141
Assert(numSupport == opcentry->numSupport);
1145
/* Need to fill in new entry */
1146
opcentry->valid = false; /* until known OK */
1147
opcentry->numStrats = numStrats;
1148
opcentry->numSupport = numSupport;
1151
opcentry->operatorOids = (Oid *)
1152
MemoryContextAllocZero(CacheMemoryContext,
1153
numStrats * sizeof(Oid));
1155
opcentry->operatorOids = NULL;
1158
opcentry->supportProcs = (RegProcedure *)
1159
MemoryContextAllocZero(CacheMemoryContext,
1160
numSupport * sizeof(RegProcedure));
1162
opcentry->supportProcs = NULL;
1165
* To avoid infinite recursion during startup, force heap scans if
1166
* we're looking up info for the opclasses used by the indexes we
1167
* would like to reference here.
1169
indexOK = criticalRelcachesBuilt ||
1170
(operatorClassOid != OID_BTREE_OPS_OID &&
1171
operatorClassOid != INT2_BTREE_OPS_OID);
1174
* Scan pg_amop to obtain operators for the opclass. We only fetch
1175
* the default ones (those with subtype zero).
1179
ScanKeyInit(&skey[0],
1180
Anum_pg_amop_amopclaid,
1181
BTEqualStrategyNumber, F_OIDEQ,
1182
ObjectIdGetDatum(operatorClassOid));
1183
ScanKeyInit(&skey[1],
1184
Anum_pg_amop_amopsubtype,
1185
BTEqualStrategyNumber, F_OIDEQ,
1186
ObjectIdGetDatum(InvalidOid));
1187
rel = heap_openr(AccessMethodOperatorRelationName,
1189
scan = systable_beginscan(rel, AccessMethodStrategyIndex, indexOK,
1190
SnapshotNow, 2, skey);
1192
while (HeapTupleIsValid(htup = systable_getnext(scan)))
1194
Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
1196
if (amopform->amopstrategy <= 0 ||
1197
(StrategyNumber) amopform->amopstrategy > numStrats)
1198
elog(ERROR, "invalid amopstrategy number %d for opclass %u",
1199
amopform->amopstrategy, operatorClassOid);
1200
opcentry->operatorOids[amopform->amopstrategy - 1] =
1204
systable_endscan(scan);
1205
heap_close(rel, AccessShareLock);
1209
* Scan pg_amproc to obtain support procs for the opclass. We only
1210
* fetch the default ones (those with subtype zero).
1214
ScanKeyInit(&skey[0],
1215
Anum_pg_amproc_amopclaid,
1216
BTEqualStrategyNumber, F_OIDEQ,
1217
ObjectIdGetDatum(operatorClassOid));
1218
ScanKeyInit(&skey[1],
1219
Anum_pg_amproc_amprocsubtype,
1220
BTEqualStrategyNumber, F_OIDEQ,
1221
ObjectIdGetDatum(InvalidOid));
1222
rel = heap_openr(AccessMethodProcedureRelationName,
1224
scan = systable_beginscan(rel, AccessMethodProcedureIndex, indexOK,
1225
SnapshotNow, 2, skey);
1227
while (HeapTupleIsValid(htup = systable_getnext(scan)))
1229
Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
1231
if (amprocform->amprocnum <= 0 ||
1232
(StrategyNumber) amprocform->amprocnum > numSupport)
1233
elog(ERROR, "invalid amproc number %d for opclass %u",
1234
amprocform->amprocnum, operatorClassOid);
1236
opcentry->supportProcs[amprocform->amprocnum - 1] =
1240
systable_endscan(scan);
1241
heap_close(rel, AccessShareLock);
1244
opcentry->valid = true;
1252
* This is a special cut-down version of RelationBuildDesc()
1253
* used by RelationCacheInitialize() in initializing the relcache.
1254
* The relation descriptor is built just from the supplied parameters,
1255
* without actually looking at any system table entries. We cheat
1256
* quite a lot since we only need to work for a few basic system
1259
* formrdesc is currently used for: pg_class, pg_attribute, pg_proc,
1260
* and pg_type (see RelationCacheInitialize).
1262
* Note that these catalogs can't have constraints (except attnotnull),
1263
* default values, rules, or triggers, since we don't cope with any of that.
1265
* NOTE: we assume we are already switched into CacheMemoryContext.
1268
formrdesc(const char *relationName, Oid relationReltype,
1269
bool hasoids, int natts, FormData_pg_attribute *att)
1276
* allocate new relation desc, clear all fields of reldesc
1278
relation = (Relation) palloc0(sizeof(RelationData));
1279
relation->rd_targblock = InvalidBlockNumber;
1281
/* make sure relation is marked as having no open file yet */
1282
relation->rd_smgr = NULL;
1285
* initialize reference count: 1 because it is nailed in cache
1287
relation->rd_refcnt = 1;
1290
* all entries built with this routine are nailed-in-cache; none are
1291
* for new or temp relations.
1293
relation->rd_isnailed = true;
1294
relation->rd_createSubid = InvalidSubTransactionId;
1295
relation->rd_istemp = false;
1298
* initialize relation tuple form
1300
* The data we insert here is pretty incomplete/bogus, but it'll serve to
1301
* get us launched. RelationCacheInitializePhase2() will read the
1302
* real data from pg_class and replace what we've done here.
1304
relation->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
1306
namestrcpy(&relation->rd_rel->relname, relationName);
1307
relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
1308
relation->rd_rel->reltype = relationReltype;
1311
* It's important to distinguish between shared and non-shared
1312
* relations, even at bootstrap time, to make sure we know where they
1313
* are stored. At present, all relations that formrdesc is used for
1316
relation->rd_rel->relisshared = false;
1318
relation->rd_rel->relpages = 1;
1319
relation->rd_rel->reltuples = 1;
1320
relation->rd_rel->relkind = RELKIND_RELATION;
1321
relation->rd_rel->relhasoids = hasoids;
1322
relation->rd_rel->relnatts = (int16) natts;
1325
* initialize attribute tuple form
1327
* Unlike the case with the relation tuple, this data had better be right
1328
* because it will never be replaced. The input values must be
1329
* correctly defined by macros in src/include/catalog/ headers.
1331
relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
1332
relation->rd_att->tdtypeid = relationReltype;
1333
relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
1336
* initialize tuple desc info
1338
has_not_null = false;
1339
for (i = 0; i < natts; i++)
1341
relation->rd_att->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
1342
memcpy((char *) relation->rd_att->attrs[i],
1344
ATTRIBUTE_TUPLE_SIZE);
1345
has_not_null |= att[i].attnotnull;
1346
/* make sure attcacheoff is valid */
1347
relation->rd_att->attrs[i]->attcacheoff = -1;
1350
/* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
1351
relation->rd_att->attrs[0]->attcacheoff = 0;
1353
/* mark not-null status */
1356
TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
1358
constr->has_not_null = true;
1359
relation->rd_att->constr = constr;
1363
* initialize relation id from info in att array (my, this is ugly)
1365
RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
1366
relation->rd_rel->relfilenode = RelationGetRelid(relation);
1369
* initialize the relation lock manager information
1371
RelationInitLockInfo(relation); /* see lmgr.c */
1374
* initialize physical addressing information for the relation
1376
RelationInitPhysicalAddr(relation);
1379
* initialize the rel-has-index flag, using hardwired knowledge
1381
if (IsBootstrapProcessingMode())
1383
/* In bootstrap mode, we have no indexes */
1384
relation->rd_rel->relhasindex = false;
1388
/* Otherwise, all the rels formrdesc is used for have indexes */
1389
relation->rd_rel->relhasindex = true;
1393
* add new reldesc to relcache
1395
RelationCacheInsert(relation);
1397
/* It's fully valid */
1398
relation->rd_isvalid = true;
1402
/* ----------------------------------------------------------------
1403
* Relation Descriptor Lookup Interface
1404
* ----------------------------------------------------------------
1408
* RelationIdCacheGetRelation
1410
* Lookup an existing reldesc by OID.
1412
* Only try to get the reldesc by looking in the cache,
1413
* do not go to the disk if it's not present.
1415
* NB: relation ref count is incremented if successful.
1416
* Caller should eventually decrement count. (Usually,
1417
* that happens by calling RelationClose().)
1420
RelationIdCacheGetRelation(Oid relationId)
1424
RelationIdCacheLookup(relationId, rd);
1426
if (RelationIsValid(rd))
1428
RelationIncrementReferenceCount(rd);
1429
/* revalidate nailed index if necessary */
1430
if (!rd->rd_isvalid)
1431
RelationReloadClassinfo(rd);
1438
* RelationSysNameCacheGetRelation
1440
* As above, but lookup by name; only works for system catalogs.
1443
RelationSysNameCacheGetRelation(const char *relationName)
1449
* make sure that the name key used for hash lookup is properly
1452
namestrcpy(&name, relationName);
1453
RelationSysNameCacheLookup(NameStr(name), rd);
1455
if (RelationIsValid(rd))
1457
RelationIncrementReferenceCount(rd);
1458
/* revalidate nailed index if necessary */
1459
if (!rd->rd_isvalid)
1460
RelationReloadClassinfo(rd);
1467
* RelationIdGetRelation
1469
* Lookup a reldesc by OID; make one if not already in cache.
1471
* NB: relation ref count is incremented, or set to 1 if new entry.
1472
* Caller should eventually decrement count. (Usually,
1473
* that happens by calling RelationClose().)
1476
RelationIdGetRelation(Oid relationId)
1479
RelationBuildDescInfo buildinfo;
1482
* first try and get a reldesc from the cache
1484
rd = RelationIdCacheGetRelation(relationId);
1485
if (RelationIsValid(rd))
1489
* no reldesc in the cache, so have RelationBuildDesc() build one and
1492
buildinfo.infotype = INFO_RELID;
1493
buildinfo.i.info_id = relationId;
1495
rd = RelationBuildDesc(buildinfo, NULL);
1496
if (RelationIsValid(rd))
1497
RelationIncrementReferenceCount(rd);
1502
* RelationSysNameGetRelation
1504
* As above, but lookup by name; only works for system catalogs.
1507
RelationSysNameGetRelation(const char *relationName)
1510
RelationBuildDescInfo buildinfo;
1513
* first try and get a reldesc from the cache
1515
rd = RelationSysNameCacheGetRelation(relationName);
1516
if (RelationIsValid(rd))
1520
* no reldesc in the cache, so have RelationBuildDesc() build one and
1523
buildinfo.infotype = INFO_RELNAME;
1524
buildinfo.i.info_name = (char *) relationName;
1526
rd = RelationBuildDesc(buildinfo, NULL);
1527
if (RelationIsValid(rd))
1528
RelationIncrementReferenceCount(rd);
1532
/* ----------------------------------------------------------------
1533
* cache invalidation support routines
1534
* ----------------------------------------------------------------
1538
* RelationIncrementReferenceCount
1539
* Increments relation reference count.
1541
* Note: bootstrap mode has its own weird ideas about relation refcount
1542
* behavior; we ought to fix it someday, but for now, just disable
1543
* reference count ownership tracking in bootstrap mode.
1546
RelationIncrementReferenceCount(Relation rel)
1548
ResourceOwnerEnlargeRelationRefs(CurrentResourceOwner);
1549
rel->rd_refcnt += 1;
1550
if (!IsBootstrapProcessingMode())
1551
ResourceOwnerRememberRelationRef(CurrentResourceOwner, rel);
1555
* RelationDecrementReferenceCount
1556
* Decrements relation reference count.
1559
RelationDecrementReferenceCount(Relation rel)
1561
Assert(rel->rd_refcnt > 0);
1562
rel->rd_refcnt -= 1;
1563
if (!IsBootstrapProcessingMode())
1564
ResourceOwnerForgetRelationRef(CurrentResourceOwner, rel);
1568
* RelationClose - close an open relation
1570
* Actually, we just decrement the refcount.
1572
* NOTE: if compiled with -DRELCACHE_FORCE_RELEASE then relcache entries
1573
* will be freed as soon as their refcount goes to zero. In combination
1574
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
1575
* to catch references to already-released relcache entries. It slows
1576
* things down quite a bit, however.
1579
RelationClose(Relation relation)
1581
/* Note: no locking manipulations needed */
1582
RelationDecrementReferenceCount(relation);
1584
#ifdef RELCACHE_FORCE_RELEASE
1585
if (RelationHasReferenceCountZero(relation) &&
1586
relation->rd_createSubid == InvalidSubTransactionId)
1587
RelationClearRelation(relation, false);
1592
* RelationReloadClassinfo - reload the pg_class row (only)
1594
* This function is used only for nailed indexes. Since a REINDEX can
1595
* change the relfilenode value for a nailed index, we have to reread
1596
* the pg_class row anytime we get an SI invalidation on a nailed index
1597
* (without throwing away the whole relcache entry, since we'd be unable
1600
* We can't necessarily reread the pg_class row right away; we might be
1601
* in a failed transaction when we receive the SI notification. If so,
1602
* RelationClearRelation just marks the entry as invalid by setting
1603
* rd_isvalid to false. This routine is called to fix the entry when it
1607
RelationReloadClassinfo(Relation relation)
1609
RelationBuildDescInfo buildinfo;
1611
HeapTuple pg_class_tuple;
1614
/* Should be called only for invalidated nailed indexes */
1615
Assert(relation->rd_isnailed && !relation->rd_isvalid &&
1616
relation->rd_rel->relkind == RELKIND_INDEX);
1617
/* Read the pg_class row */
1618
buildinfo.infotype = INFO_RELID;
1619
buildinfo.i.info_id = relation->rd_id;
1622
* Don't try to use an indexscan of pg_class_oid_index to reload the
1623
* info for pg_class_oid_index ...
1625
indexOK = strcmp(RelationGetRelationName(relation), ClassOidIndex) != 0;
1626
pg_class_tuple = ScanPgRelation(buildinfo, indexOK);
1627
if (!HeapTupleIsValid(pg_class_tuple))
1628
elog(ERROR, "could not find tuple for system relation %u",
1630
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
1631
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
1632
/* Now we can recalculate physical address */
1633
RelationInitPhysicalAddr(relation);
1634
heap_freetuple(pg_class_tuple);
1635
relation->rd_targblock = InvalidBlockNumber;
1636
/* Okay, now it's valid again */
1637
relation->rd_isvalid = true;
1641
* RelationClearRelation
1643
* Physically blow away a relation cache entry, or reset it and rebuild
1644
* it from scratch (that is, from catalog entries). The latter path is
1645
* usually used when we are notified of a change to an open relation
1646
* (one with refcount > 0). However, this routine just does whichever
1647
* it's told to do; callers must determine which they want.
1650
RelationClearRelation(Relation relation, bool rebuild)
1652
Oid old_reltype = relation->rd_rel->reltype;
1653
MemoryContext oldcxt;
1656
* Make sure smgr and lower levels close the relation's files, if they
1657
* weren't closed already. If the relation is not getting deleted,
1658
* the next smgr access should reopen the files automatically. This
1659
* ensures that the low-level file access state is updated after, say,
1660
* a vacuum truncation.
1662
RelationCloseSmgr(relation);
1665
* Never, never ever blow away a nailed-in system relation, because
1666
* we'd be unable to recover. However, we must reset rd_targblock, in
1667
* case we got called because of a relation cache flush that was
1668
* triggered by VACUUM.
1670
* If it's a nailed index, then we need to re-read the pg_class row to
1671
* see if its relfilenode changed. We can't necessarily do that here,
1672
* because we might be in a failed transaction. We assume it's okay
1673
* to do it if there are open references to the relcache entry (cf
1674
* notes for AtEOXact_RelationCache). Otherwise just mark the entry
1675
* as possibly invalid, and it'll be fixed when next opened.
1677
if (relation->rd_isnailed)
1679
relation->rd_targblock = InvalidBlockNumber;
1680
if (relation->rd_rel->relkind == RELKIND_INDEX)
1682
relation->rd_isvalid = false; /* needs to be revalidated */
1683
if (relation->rd_refcnt > 1)
1684
RelationReloadClassinfo(relation);
1690
* Remove relation from hash tables
1692
* Note: we might be reinserting it momentarily, but we must not have it
1693
* visible in the hash tables until it's valid again, so don't try to
1694
* optimize this away...
1696
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
1697
RelationCacheDelete(relation);
1698
MemoryContextSwitchTo(oldcxt);
1700
/* Clear out catcache's entries for this relation */
1701
CatalogCacheFlushRelation(RelationGetRelid(relation));
1704
* Free all the subsidiary data structures of the relcache entry. We
1705
* cannot free rd_att if we are trying to rebuild the entry, however,
1706
* because pointers to it may be cached in various places. The rule
1707
* manager might also have pointers into the rewrite rules. So to
1708
* begin with, we can only get rid of these fields:
1710
FreeTriggerDesc(relation->trigdesc);
1711
if (relation->rd_indextuple)
1712
pfree(relation->rd_indextuple);
1713
if (relation->rd_am)
1714
pfree(relation->rd_am);
1715
if (relation->rd_rel)
1716
pfree(relation->rd_rel);
1717
list_free(relation->rd_indexlist);
1718
if (relation->rd_indexcxt)
1719
MemoryContextDelete(relation->rd_indexcxt);
1722
* If we're really done with the relcache entry, blow it away. But if
1723
* someone is still using it, reconstruct the whole deal without
1724
* moving the physical RelationData record (so that the someone's
1725
* pointer is still valid).
1729
/* ok to zap remaining substructure */
1730
flush_rowtype_cache(old_reltype);
1731
FreeTupleDesc(relation->rd_att);
1732
if (relation->rd_rulescxt)
1733
MemoryContextDelete(relation->rd_rulescxt);
1739
* When rebuilding an open relcache entry, must preserve ref count
1740
* and rd_createSubid state. Also attempt to preserve the
1741
* tupledesc and rewrite-rule substructures in place.
1743
* Note that this process does not touch CurrentResourceOwner; which
1744
* is good because whatever ref counts the entry may have do not
1745
* necessarily belong to that resource owner.
1747
int old_refcnt = relation->rd_refcnt;
1748
SubTransactionId old_createSubid = relation->rd_createSubid;
1749
TupleDesc old_att = relation->rd_att;
1750
RuleLock *old_rules = relation->rd_rules;
1751
MemoryContext old_rulescxt = relation->rd_rulescxt;
1752
RelationBuildDescInfo buildinfo;
1754
buildinfo.infotype = INFO_RELID;
1755
buildinfo.i.info_id = RelationGetRelid(relation);
1757
if (RelationBuildDesc(buildinfo, relation) != relation)
1759
/* Should only get here if relation was deleted */
1760
flush_rowtype_cache(old_reltype);
1761
FreeTupleDesc(old_att);
1763
MemoryContextDelete(old_rulescxt);
1765
elog(ERROR, "relation %u deleted while still in use",
1766
buildinfo.i.info_id);
1768
relation->rd_refcnt = old_refcnt;
1769
relation->rd_createSubid = old_createSubid;
1770
if (equalTupleDescs(old_att, relation->rd_att))
1772
/* needn't flush typcache here */
1773
FreeTupleDesc(relation->rd_att);
1774
relation->rd_att = old_att;
1778
flush_rowtype_cache(old_reltype);
1779
FreeTupleDesc(old_att);
1781
if (equalRuleLocks(old_rules, relation->rd_rules))
1783
if (relation->rd_rulescxt)
1784
MemoryContextDelete(relation->rd_rulescxt);
1785
relation->rd_rules = old_rules;
1786
relation->rd_rulescxt = old_rulescxt;
1791
MemoryContextDelete(old_rulescxt);
1797
* RelationFlushRelation
1799
* Rebuild the relation if it is open (refcount > 0), else blow it away.
1802
RelationFlushRelation(Relation relation)
1806
if (relation->rd_createSubid != InvalidSubTransactionId)
1809
* New relcache entries are always rebuilt, not flushed; else we'd
1810
* forget the "new" status of the relation, which is a useful
1811
* optimization to have.
1818
* Pre-existing rels can be dropped from the relcache if not open.
1820
rebuild = !RelationHasReferenceCountZero(relation);
1823
RelationClearRelation(relation, rebuild);
1827
* RelationForgetRelation - unconditionally remove a relcache entry
1829
* External interface for destroying a relcache entry when we
1830
* drop the relation.
1833
RelationForgetRelation(Oid rid)
1837
RelationIdCacheLookup(rid, relation);
1839
if (!PointerIsValid(relation))
1840
return; /* not in cache, nothing to do */
1842
if (!RelationHasReferenceCountZero(relation))
1843
elog(ERROR, "relation %u is still open", rid);
1845
/* Unconditionally destroy the relcache entry */
1846
RelationClearRelation(relation, false);
1850
* RelationCacheInvalidateEntry
1852
* This routine is invoked for SI cache flush messages.
1854
* Any relcache entry matching the relid must be flushed. (Note: caller has
1855
* already determined that the relid belongs to our database or is a shared
1858
* We used to skip local relations, on the grounds that they could
1859
* not be targets of cross-backend SI update messages; but it seems
1860
* safer to process them, so that our *own* SI update messages will
1861
* have the same effects during CommandCounterIncrement for both
1862
* local and nonlocal relations.
1865
RelationCacheInvalidateEntry(Oid relationId)
1869
RelationIdCacheLookup(relationId, relation);
1871
if (PointerIsValid(relation))
1873
relcacheInvalsReceived++;
1874
RelationFlushRelation(relation);
1879
* RelationCacheInvalidate
1880
* Blow away cached relation descriptors that have zero reference counts,
1881
* and rebuild those with positive reference counts. Also reset the smgr
1884
* This is currently used only to recover from SI message buffer overflow,
1885
* so we do not touch new-in-transaction relations; they cannot be targets
1886
* of cross-backend SI updates (and our own updates now go through a
1887
* separate linked list that isn't limited by the SI message buffer size).
1889
* We do this in two phases: the first pass deletes deletable items, and
1890
* the second one rebuilds the rebuildable items. This is essential for
1891
* safety, because hash_seq_search only copes with concurrent deletion of
1892
* the element it is currently visiting. If a second SI overflow were to
1893
* occur while we are walking the table, resulting in recursive entry to
1894
* this routine, we could crash because the inner invocation blows away
1895
* the entry next to be visited by the outer scan. But this way is OK,
1896
* because (a) during the first pass we won't process any more SI messages,
1897
* so hash_seq_search will complete safely; (b) during the second pass we
1898
* only hold onto pointers to nondeletable entries.
1900
* The two-phase approach also makes it easy to ensure that we process
1901
* nailed-in-cache indexes before other nondeletable items, and that we
1902
* process pg_class_oid_index first of all. In scenarios where a nailed
1903
* index has been given a new relfilenode, we have to detect that update
1904
* before the nailed index is used in reloading any other relcache entry.
1907
RelationCacheInvalidate(void)
1909
HASH_SEQ_STATUS status;
1910
RelIdCacheEnt *idhentry;
1912
List *rebuildFirstList = NIL;
1913
List *rebuildList = NIL;
1917
hash_seq_init(&status, RelationIdCache);
1919
while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1921
relation = idhentry->reldesc;
1923
/* Must close all smgr references to avoid leaving dangling ptrs */
1924
RelationCloseSmgr(relation);
1926
/* Ignore new relations, since they are never SI targets */
1927
if (relation->rd_createSubid != InvalidSubTransactionId)
1930
relcacheInvalsReceived++;
1932
if (RelationHasReferenceCountZero(relation))
1934
/* Delete this entry immediately */
1935
Assert(!relation->rd_isnailed);
1936
RelationClearRelation(relation, false);
1941
* Add this entry to list of stuff to rebuild in second pass.
1942
* pg_class_oid_index goes on the front of rebuildFirstList,
1943
* other nailed indexes on the back, and everything else into
1944
* rebuildList (in no particular order).
1946
if (relation->rd_isnailed &&
1947
relation->rd_rel->relkind == RELKIND_INDEX)
1949
if (strcmp(RelationGetRelationName(relation),
1950
ClassOidIndex) == 0)
1951
rebuildFirstList = lcons(relation, rebuildFirstList);
1953
rebuildFirstList = lappend(rebuildFirstList, relation);
1956
rebuildList = lcons(relation, rebuildList);
1960
rebuildList = list_concat(rebuildFirstList, rebuildList);
1963
* Now zap any remaining smgr cache entries. This must happen before
1964
* we start to rebuild entries, since that may involve catalog fetches
1965
* which will re-open catalog files.
1969
/* Phase 2: rebuild the items found to need rebuild in phase 1 */
1970
foreach(l, rebuildList)
1972
relation = (Relation) lfirst(l);
1973
RelationClearRelation(relation, true);
1975
list_free(rebuildList);
1979
* AtEOXact_RelationCache
1981
* Clean up the relcache at main-transaction commit or abort.
1983
* Note: this must be called *before* processing invalidation messages.
1984
* In the case of abort, we don't want to try to rebuild any invalidated
1985
* cache entries (since we can't safely do database accesses). Therefore
1986
* we must reset refcnts before handling pending invalidations.
1989
AtEOXact_RelationCache(bool isCommit)
1991
HASH_SEQ_STATUS status;
1992
RelIdCacheEnt *idhentry;
1994
hash_seq_init(&status, RelationIdCache);
1996
while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
1998
Relation relation = idhentry->reldesc;
1999
int expected_refcnt;
2002
* Is it a relation created in the current transaction?
2004
* During commit, reset the flag to zero, since we are now out of the
2005
* creating transaction. During abort, simply delete the relcache
2006
* entry --- it isn't interesting any longer. (NOTE: if we have
2007
* forgotten the new-ness of a new relation due to a forced cache
2008
* flush, the entry will get deleted anyway by shared-cache-inval
2009
* processing of the aborted pg_class insertion.)
2011
if (relation->rd_createSubid != InvalidSubTransactionId)
2014
relation->rd_createSubid = InvalidSubTransactionId;
2017
RelationClearRelation(relation, false);
2023
* During transaction abort, we must also reset relcache entry ref
2024
* counts to their normal not-in-a-transaction state. A ref count
2025
* may be too high because some routine was exited by ereport()
2026
* between incrementing and decrementing the count.
2028
* During commit, we should not have to do this, but it's still
2029
* useful to check that the counts are correct to catch missed
2032
* In bootstrap mode, do NOT reset the refcnt nor complain that it's
2033
* nonzero --- the bootstrap code expects relations to stay open
2034
* across start/commit transaction calls. (That seems bogus, but
2035
* it's not worth fixing.)
2037
expected_refcnt = relation->rd_isnailed ? 1 : 0;
2041
if (relation->rd_refcnt != expected_refcnt &&
2042
!IsBootstrapProcessingMode())
2044
elog(WARNING, "relcache reference leak: relation \"%s\" has refcnt %d instead of %d",
2045
RelationGetRelationName(relation),
2046
relation->rd_refcnt, expected_refcnt);
2047
relation->rd_refcnt = expected_refcnt;
2052
/* abort case, just reset it quietly */
2053
relation->rd_refcnt = expected_refcnt;
2057
* Flush any temporary index list.
2059
if (relation->rd_indexvalid == 2)
2061
list_free(relation->rd_indexlist);
2062
relation->rd_indexlist = NIL;
2063
relation->rd_indexvalid = 0;
2067
/* Once done with the transaction, we can reset need_eosubxact_work */
2068
need_eosubxact_work = false;
2072
* AtEOSubXact_RelationCache
2074
* Clean up the relcache at sub-transaction commit or abort.
2076
* Note: this must be called *before* processing invalidation messages.
2079
AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
2080
SubTransactionId parentSubid)
2082
HASH_SEQ_STATUS status;
2083
RelIdCacheEnt *idhentry;
2086
* In the majority of subtransactions there is not anything for this
2087
* routine to do, and since there are usually many entries in the
2088
* relcache, uselessly scanning the cache represents a surprisingly
2089
* large fraction of the subtransaction entry/exit overhead. To avoid
2090
* this, we keep a static flag that must be set whenever a condition
2091
* is created that requires subtransaction-end work. (Currently, this
2092
* means either a relation is created in the current xact, or an index
2093
* list is forced.) For simplicity, the flag remains set till end of
2094
* top-level transaction, even though we could clear it earlier in some
2097
if (!need_eosubxact_work)
2100
hash_seq_init(&status, RelationIdCache);
2102
while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
2104
Relation relation = idhentry->reldesc;
2107
* Is it a relation created in the current subtransaction?
2109
* During subcommit, mark it as belonging to the parent, instead.
2110
* During subabort, simply delete the relcache entry.
2112
if (relation->rd_createSubid == mySubid)
2115
relation->rd_createSubid = parentSubid;
2118
Assert(RelationHasReferenceCountZero(relation));
2119
RelationClearRelation(relation, false);
2125
* Flush any temporary index list.
2127
if (relation->rd_indexvalid == 2)
2129
list_free(relation->rd_indexlist);
2130
relation->rd_indexlist = NIL;
2131
relation->rd_indexvalid = 0;
2137
* RelationBuildLocalRelation
2138
* Build a relcache entry for an about-to-be-created relation,
2139
* and enter it into the relcache.
2142
RelationBuildLocalRelation(const char *relname,
2147
bool shared_relation,
2151
MemoryContext oldcxt;
2152
int natts = tupDesc->natts;
2156
AssertArg(natts >= 0);
2159
* switch to the cache context to create the relcache entry.
2161
if (!CacheMemoryContext)
2162
CreateCacheMemoryContext();
2164
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2167
* allocate a new relation descriptor and fill in basic state fields.
2169
rel = (Relation) palloc0(sizeof(RelationData));
2171
rel->rd_targblock = InvalidBlockNumber;
2173
/* make sure relation is marked as having no open file yet */
2174
rel->rd_smgr = NULL;
2176
rel->rd_refcnt = nailit ? 1 : 0;
2178
/* it's being created in this transaction */
2179
rel->rd_createSubid = GetCurrentSubTransactionId();
2181
/* must flag that we have rels created in this transaction */
2182
need_eosubxact_work = true;
2184
/* is it a temporary relation? */
2185
rel->rd_istemp = isTempNamespace(relnamespace);
2188
* nail the reldesc if this is a bootstrap create reln and we may need
2189
* it in the cache later on in the bootstrap process so we don't ever
2190
* want it kicked out. e.g. pg_attribute!!!
2193
rel->rd_isnailed = true;
2196
* create a new tuple descriptor from the one passed in. We do this
2197
* partly to copy it into the cache context, and partly because the
2198
* new relation can't have any defaults or constraints yet; they have
2199
* to be added in later steps, because they require additions to
2200
* multiple system catalogs. We can copy attnotnull constraints here,
2203
rel->rd_att = CreateTupleDescCopy(tupDesc);
2204
has_not_null = false;
2205
for (i = 0; i < natts; i++)
2207
rel->rd_att->attrs[i]->attnotnull = tupDesc->attrs[i]->attnotnull;
2208
has_not_null |= tupDesc->attrs[i]->attnotnull;
2213
TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
2215
constr->has_not_null = true;
2216
rel->rd_att->constr = constr;
2220
* initialize relation tuple form (caller may add/override data later)
2222
rel->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
2224
namestrcpy(&rel->rd_rel->relname, relname);
2225
rel->rd_rel->relnamespace = relnamespace;
2227
rel->rd_rel->relkind = RELKIND_UNCATALOGED;
2228
rel->rd_rel->relhasoids = rel->rd_att->tdhasoid;
2229
rel->rd_rel->relnatts = natts;
2230
rel->rd_rel->reltype = InvalidOid;
2233
* Insert relation physical and logical identifiers (OIDs) into the
2234
* right places. Note that the physical ID (relfilenode) is initially
2235
* the same as the logical ID (OID).
2237
rel->rd_rel->relisshared = shared_relation;
2239
RelationGetRelid(rel) = relid;
2241
for (i = 0; i < natts; i++)
2242
rel->rd_att->attrs[i]->attrelid = relid;
2244
rel->rd_rel->relfilenode = relid;
2245
rel->rd_rel->reltablespace = reltablespace;
2247
RelationInitLockInfo(rel); /* see lmgr.c */
2249
RelationInitPhysicalAddr(rel);
2252
* Okay to insert into the relcache hash tables.
2254
RelationCacheInsert(rel);
2257
* done building relcache entry.
2259
MemoryContextSwitchTo(oldcxt);
2261
/* It's fully valid */
2262
rel->rd_isvalid = true;
2265
* Caller expects us to pin the returned entry.
2267
RelationIncrementReferenceCount(rel);
2273
* RelationCacheInitialize
2275
* This initializes the relation descriptor cache. At the time
2276
* that this is invoked, we can't do database access yet (mainly
2277
* because the transaction subsystem is not up), so we can't get
2278
* "real" info. However it's okay to read the pg_internal.init
2279
* cache file, if one is available. Otherwise we make phony
2280
* entries for the minimum set of nailed-in-cache relations.
2283
#define INITRELCACHESIZE 400
2286
RelationCacheInitialize(void)
2288
MemoryContext oldcxt;
2292
* switch to cache memory context
2294
if (!CacheMemoryContext)
2295
CreateCacheMemoryContext();
2297
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2300
* create hashtables that index the relcache
2302
MemSet(&ctl, 0, sizeof(ctl));
2303
ctl.keysize = sizeof(NameData);
2304
ctl.entrysize = sizeof(RelNameCacheEnt);
2305
RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
2308
ctl.keysize = sizeof(Oid);
2309
ctl.entrysize = sizeof(RelIdCacheEnt);
2310
ctl.hash = tag_hash;
2311
RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE,
2312
&ctl, HASH_ELEM | HASH_FUNCTION);
2315
* Try to load the relcache cache file. If successful, we're done for
2316
* now. Otherwise, initialize the cache with pre-made descriptors for
2317
* the critical "nailed-in" system catalogs.
2319
if (IsBootstrapProcessingMode() ||
2320
!load_relcache_init_file())
2322
formrdesc(RelationRelationName, PG_CLASS_RELTYPE_OID,
2323
true, Natts_pg_class, Desc_pg_class);
2324
formrdesc(AttributeRelationName, PG_ATTRIBUTE_RELTYPE_OID,
2325
false, Natts_pg_attribute, Desc_pg_attribute);
2326
formrdesc(ProcedureRelationName, PG_PROC_RELTYPE_OID,
2327
true, Natts_pg_proc, Desc_pg_proc);
2328
formrdesc(TypeRelationName, PG_TYPE_RELTYPE_OID,
2329
true, Natts_pg_type, Desc_pg_type);
2331
#define NUM_CRITICAL_RELS 4 /* fix if you change list above */
2334
MemoryContextSwitchTo(oldcxt);
2338
* RelationCacheInitializePhase2
2340
* This is called as soon as the catcache and transaction system
2341
* are functional. At this point we can actually read data from
2342
* the system catalogs. Update the relcache entries made during
2343
* RelationCacheInitialize, and make sure we have entries for the
2344
* critical system indexes.
2347
RelationCacheInitializePhase2(void)
2349
HASH_SEQ_STATUS status;
2350
RelIdCacheEnt *idhentry;
2352
if (IsBootstrapProcessingMode())
2356
* If we didn't get the critical system indexes loaded into relcache,
2357
* do so now. These are critical because the catcache depends on them
2358
* for catcache fetches that are done during relcache load. Thus, we
2359
* have an infinite-recursion problem. We can break the recursion by
2360
* doing heapscans instead of indexscans at certain key spots. To
2361
* avoid hobbling performance, we only want to do that until we have
2362
* the critical indexes loaded into relcache. Thus, the flag
2363
* criticalRelcachesBuilt is used to decide whether to do heapscan or
2364
* indexscan at the key spots, and we set it true after we've loaded
2365
* the critical indexes.
2367
* The critical indexes are marked as "nailed in cache", partly to make
2368
* it easy for load_relcache_init_file to count them, but mainly
2369
* because we cannot flush and rebuild them once we've set
2370
* criticalRelcachesBuilt to true. (NOTE: perhaps it would be
2371
* possible to reload them by temporarily setting
2372
* criticalRelcachesBuilt to false again. For now, though, we just
2375
if (!criticalRelcachesBuilt)
2377
RelationBuildDescInfo buildinfo;
2380
#define LOAD_CRIT_INDEX(indname) \
2382
buildinfo.infotype = INFO_RELNAME; \
2383
buildinfo.i.info_name = (indname); \
2384
ird = RelationBuildDesc(buildinfo, NULL); \
2385
ird->rd_isnailed = true; \
2386
ird->rd_refcnt = 1; \
2389
LOAD_CRIT_INDEX(ClassNameNspIndex);
2390
LOAD_CRIT_INDEX(ClassOidIndex);
2391
LOAD_CRIT_INDEX(AttributeRelidNumIndex);
2392
LOAD_CRIT_INDEX(IndexRelidIndex);
2393
LOAD_CRIT_INDEX(AccessMethodStrategyIndex);
2394
LOAD_CRIT_INDEX(AccessMethodProcedureIndex);
2395
LOAD_CRIT_INDEX(OperatorOidIndex);
2397
#define NUM_CRITICAL_INDEXES 7 /* fix if you change list above */
2399
criticalRelcachesBuilt = true;
2403
* Now, scan all the relcache entries and update anything that might
2404
* be wrong in the results from formrdesc or the relcache cache file.
2405
* If we faked up relcache entries using formrdesc, then read the real
2406
* pg_class rows and replace the fake entries with them. Also, if any
2407
* of the relcache entries have rules or triggers, load that info the
2408
* hard way since it isn't recorded in the cache file.
2410
hash_seq_init(&status, RelationIdCache);
2412
while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
2414
Relation relation = idhentry->reldesc;
2417
* If it's a faked-up entry, read the real pg_class tuple.
2419
if (needNewCacheFile && relation->rd_isnailed)
2424
htup = SearchSysCache(RELOID,
2425
ObjectIdGetDatum(RelationGetRelid(relation)),
2427
if (!HeapTupleIsValid(htup))
2428
elog(FATAL, "cache lookup failed for relation %u",
2429
RelationGetRelid(relation));
2430
relp = (Form_pg_class) GETSTRUCT(htup);
2433
* Copy tuple to relation->rd_rel. (See notes in
2434
* AllocateRelationDesc())
2436
Assert(relation->rd_rel != NULL);
2437
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
2440
* Also update the derived fields in rd_att.
2442
relation->rd_att->tdtypeid = relp->reltype;
2443
relation->rd_att->tdtypmod = -1; /* unnecessary, but... */
2444
relation->rd_att->tdhasoid = relp->relhasoids;
2446
ReleaseSysCache(htup);
2450
* Fix data that isn't saved in relcache cache file.
2452
if (relation->rd_rel->relhasrules && relation->rd_rules == NULL)
2453
RelationBuildRuleLock(relation);
2454
if (relation->rd_rel->reltriggers > 0 && relation->trigdesc == NULL)
2455
RelationBuildTriggers(relation);
2460
* RelationCacheInitializePhase3
2462
* Final step of relcache initialization: write out a new relcache
2463
* cache file if one is needed.
2466
RelationCacheInitializePhase3(void)
2468
if (IsBootstrapProcessingMode())
2471
if (needNewCacheFile)
2474
* Force all the catcaches to finish initializing and thereby open
2475
* the catalogs and indexes they use. This will preload the
2476
* relcache with entries for all the most important system
2477
* catalogs and indexes, so that the init file will be most useful
2478
* for future backends.
2480
InitCatalogCachePhase2();
2482
/* now write the file */
2483
write_relcache_init_file();
2488
AttrDefaultFetch(Relation relation)
2490
AttrDefault *attrdef = relation->rd_att->constr->defval;
2491
int ndef = relation->rd_att->constr->num_defval;
2502
Anum_pg_attrdef_adrelid,
2503
BTEqualStrategyNumber, F_OIDEQ,
2504
ObjectIdGetDatum(RelationGetRelid(relation)));
2506
adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
2507
adscan = systable_beginscan(adrel, AttrDefaultIndex, true,
2508
SnapshotNow, 1, &skey);
2511
while (HeapTupleIsValid(htup = systable_getnext(adscan)))
2513
Form_pg_attrdef adform = (Form_pg_attrdef) GETSTRUCT(htup);
2515
for (i = 0; i < ndef; i++)
2517
if (adform->adnum != attrdef[i].adnum)
2519
if (attrdef[i].adbin != NULL)
2520
elog(WARNING, "multiple attrdef records found for attr %s of rel %s",
2521
NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname),
2522
RelationGetRelationName(relation));
2526
val = fastgetattr(htup,
2527
Anum_pg_attrdef_adbin,
2528
adrel->rd_att, &isnull);
2530
elog(WARNING, "null adbin for attr %s of rel %s",
2531
NameStr(relation->rd_att->attrs[adform->adnum - 1]->attname),
2532
RelationGetRelationName(relation));
2534
attrdef[i].adbin = MemoryContextStrdup(CacheMemoryContext,
2535
DatumGetCString(DirectFunctionCall1(textout,
2541
elog(WARNING, "unexpected attrdef record found for attr %d of rel %s",
2542
adform->adnum, RelationGetRelationName(relation));
2545
systable_endscan(adscan);
2546
heap_close(adrel, AccessShareLock);
2549
elog(WARNING, "%d attrdef record(s) missing for rel %s",
2550
ndef - found, RelationGetRelationName(relation));
2554
CheckConstraintFetch(Relation relation)
2556
ConstrCheck *check = relation->rd_att->constr->check;
2557
int ncheck = relation->rd_att->constr->num_check;
2559
SysScanDesc conscan;
2560
ScanKeyData skey[1];
2566
ScanKeyInit(&skey[0],
2567
Anum_pg_constraint_conrelid,
2568
BTEqualStrategyNumber, F_OIDEQ,
2569
ObjectIdGetDatum(RelationGetRelid(relation)));
2571
conrel = heap_openr(ConstraintRelationName, AccessShareLock);
2572
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
2573
SnapshotNow, 1, skey);
2575
while (HeapTupleIsValid(htup = systable_getnext(conscan)))
2577
Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup);
2579
/* We want check constraints only */
2580
if (conform->contype != CONSTRAINT_CHECK)
2583
if (found >= ncheck)
2584
elog(ERROR, "unexpected constraint record found for rel %s",
2585
RelationGetRelationName(relation));
2587
check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
2588
NameStr(conform->conname));
2590
/* Grab and test conbin is actually set */
2591
val = fastgetattr(htup,
2592
Anum_pg_constraint_conbin,
2593
conrel->rd_att, &isnull);
2595
elog(ERROR, "null conbin for rel %s",
2596
RelationGetRelationName(relation));
2598
check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
2599
DatumGetCString(DirectFunctionCall1(textout,
2604
systable_endscan(conscan);
2605
heap_close(conrel, AccessShareLock);
2607
if (found != ncheck)
2608
elog(ERROR, "%d constraint record(s) missing for rel %s",
2609
ncheck - found, RelationGetRelationName(relation));
2613
* RelationGetIndexList -- get a list of OIDs of indexes on this relation
2615
* The index list is created only if someone requests it. We scan pg_index
2616
* to find relevant indexes, and add the list to the relcache entry so that
2617
* we won't have to compute it again. Note that shared cache inval of a
2618
* relcache entry will delete the old list and set rd_indexvalid to 0,
2619
* so that we must recompute the index list on next request. This handles
2620
* creation or deletion of an index.
2622
* The returned list is guaranteed to be sorted in order by OID. This is
2623
* needed by the executor, since for index types that we obtain exclusive
2624
* locks on when updating the index, all backends must lock the indexes in
2625
* the same order or we will get deadlocks (see ExecOpenIndices()). Any
2626
* consistent ordering would do, but ordering by OID is easy.
2628
* Since shared cache inval causes the relcache's copy of the list to go away,
2629
* we return a copy of the list palloc'd in the caller's context. The caller
2630
* may freeList() the returned list after scanning it. This is necessary
2631
* since the caller will typically be doing syscache lookups on the relevant
2632
* indexes, and syscache lookup could cause SI messages to be processed!
2635
RelationGetIndexList(Relation relation)
2638
SysScanDesc indscan;
2642
MemoryContext oldcxt;
2644
/* Quick exit if we already computed the list. */
2645
if (relation->rd_indexvalid != 0)
2646
return list_copy(relation->rd_indexlist);
2649
* We build the list we intend to return (in the caller's context)
2650
* while doing the scan. After successfully completing the scan, we
2651
* copy that list into the relcache entry. This avoids cache-context
2652
* memory leakage if we get some sort of error partway through.
2656
/* Prepare to scan pg_index for entries having indrelid = this rel. */
2658
Anum_pg_index_indrelid,
2659
BTEqualStrategyNumber, F_OIDEQ,
2660
ObjectIdGetDatum(RelationGetRelid(relation)));
2662
indrel = heap_openr(IndexRelationName, AccessShareLock);
2663
indscan = systable_beginscan(indrel, IndexIndrelidIndex, true,
2664
SnapshotNow, 1, &skey);
2666
while (HeapTupleIsValid(htup = systable_getnext(indscan)))
2668
Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
2670
result = insert_ordered_oid(result, index->indexrelid);
2673
systable_endscan(indscan);
2674
heap_close(indrel, AccessShareLock);
2676
/* Now save a copy of the completed list in the relcache entry. */
2677
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2678
relation->rd_indexlist = list_copy(result);
2679
relation->rd_indexvalid = 1;
2680
MemoryContextSwitchTo(oldcxt);
2686
* insert_ordered_oid
2687
* Insert a new Oid into a sorted list of Oids, preserving ordering
2689
* Building the ordered list this way is O(N^2), but with a pretty small
2690
* constant, so for the number of entries we expect it will probably be
2691
* faster than trying to apply qsort(). Most tables don't have very many
2695
insert_ordered_oid(List *list, Oid datum)
2699
/* Does the datum belong at the front? */
2700
if (list == NIL || datum < linitial_oid(list))
2701
return lcons_oid(datum, list);
2702
/* No, so find the entry it belongs after */
2703
prev = list_head(list);
2706
ListCell *curr = lnext(prev);
2708
if (curr == NULL || datum < lfirst_oid(curr))
2709
break; /* it belongs after 'prev', before 'curr' */
2713
/* Insert datum into list after 'prev' */
2714
lappend_cell_oid(list, prev, datum);
2719
* RelationSetIndexList -- externally force the index list contents
2721
* This is used to temporarily override what we think the set of valid
2722
* indexes is. The forcing will be valid only until transaction commit
2725
* This should only be applied to nailed relations, because in a non-nailed
2726
* relation the hacked index list could be lost at any time due to SI
2727
* messages. In practice it is only used on pg_class (see REINDEX).
2729
* It is up to the caller to make sure the given list is correctly ordered.
2732
RelationSetIndexList(Relation relation, List *indexIds)
2734
MemoryContext oldcxt;
2736
Assert(relation->rd_isnailed);
2737
/* Copy the list into the cache context (could fail for lack of mem) */
2738
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2739
indexIds = list_copy(indexIds);
2740
MemoryContextSwitchTo(oldcxt);
2741
/* Okay to replace old list */
2742
list_free(relation->rd_indexlist);
2743
relation->rd_indexlist = indexIds;
2744
relation->rd_indexvalid = 2; /* mark list as forced */
2745
/* must flag that we have a forced index list */
2746
need_eosubxact_work = true;
2750
* RelationGetIndexExpressions -- get the index expressions for an index
2752
* We cache the result of transforming pg_index.indexprs into a node tree.
2753
* If the rel is not an index or has no expressional columns, we return NIL.
2754
* Otherwise, the returned tree is copied into the caller's memory context.
2755
* (We don't want to return a pointer to the relcache copy, since it could
2756
* disappear due to relcache invalidation.)
2759
RelationGetIndexExpressions(Relation relation)
2765
MemoryContext oldcxt;
2767
/* Quick exit if we already computed the result. */
2768
if (relation->rd_indexprs)
2769
return (List *) copyObject(relation->rd_indexprs);
2771
/* Quick exit if there is nothing to do. */
2772
if (relation->rd_indextuple == NULL ||
2773
heap_attisnull(relation->rd_indextuple, Anum_pg_index_indexprs))
2777
* We build the tree we intend to return in the caller's context.
2778
* After successfully completing the work, we copy it into the
2779
* relcache entry. This avoids problems if we get some sort of error
2782
* We make use of the syscache's copy of pg_index's tupledesc to access
2783
* the non-fixed fields of the tuple. We assume that the syscache
2784
* will be initialized before any access of a partial index could
2785
* occur. (This would probably fail if we were to allow partial
2786
* indexes on system catalogs.)
2788
exprsDatum = SysCacheGetAttr(INDEXRELID, relation->rd_indextuple,
2789
Anum_pg_index_indexprs, &isnull);
2791
exprsString = DatumGetCString(DirectFunctionCall1(textout, exprsDatum));
2792
result = (List *) stringToNode(exprsString);
2796
* Run the expressions through flatten_andors and
2797
* eval_const_expressions. This is not just an optimization, but is
2798
* necessary, because the planner will be comparing them to
2799
* similarly-processed qual clauses, and may fail to detect valid
2800
* matches without this.
2802
result = (List *) flatten_andors((Node *) result);
2804
result = (List *) eval_const_expressions((Node *) result);
2807
* Also mark any coercion format fields as "don't care", so that the
2808
* planner can match to both explicit and implicit coercions.
2810
set_coercionform_dontcare((Node *) result);
2812
/* May as well fix opfuncids too */
2813
fix_opfuncids((Node *) result);
2815
/* Now save a copy of the completed tree in the relcache entry. */
2816
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2817
relation->rd_indexprs = (List *) copyObject(result);
2818
MemoryContextSwitchTo(oldcxt);
2824
* RelationGetIndexPredicate -- get the index predicate for an index
2826
* We cache the result of transforming pg_index.indpred into an implicit-AND
2827
* node tree (suitable for ExecQual).
2828
* If the rel is not an index or has no predicate, we return NIL.
2829
* Otherwise, the returned tree is copied into the caller's memory context.
2830
* (We don't want to return a pointer to the relcache copy, since it could
2831
* disappear due to relcache invalidation.)
2834
RelationGetIndexPredicate(Relation relation)
2840
MemoryContext oldcxt;
2842
/* Quick exit if we already computed the result. */
2843
if (relation->rd_indpred)
2844
return (List *) copyObject(relation->rd_indpred);
2846
/* Quick exit if there is nothing to do. */
2847
if (relation->rd_indextuple == NULL ||
2848
heap_attisnull(relation->rd_indextuple, Anum_pg_index_indpred))
2852
* We build the tree we intend to return in the caller's context.
2853
* After successfully completing the work, we copy it into the
2854
* relcache entry. This avoids problems if we get some sort of error
2857
* We make use of the syscache's copy of pg_index's tupledesc to access
2858
* the non-fixed fields of the tuple. We assume that the syscache
2859
* will be initialized before any access of a partial index could
2860
* occur. (This would probably fail if we were to allow partial
2861
* indexes on system catalogs.)
2863
predDatum = SysCacheGetAttr(INDEXRELID, relation->rd_indextuple,
2864
Anum_pg_index_indpred, &isnull);
2866
predString = DatumGetCString(DirectFunctionCall1(textout, predDatum));
2867
result = (List *) stringToNode(predString);
2871
* Run the expression through canonicalize_qual and
2872
* eval_const_expressions. This is not just an optimization, but is
2873
* necessary, because the planner will be comparing it to
2874
* similarly-processed qual clauses, and may fail to detect valid
2875
* matches without this.
2877
result = (List *) canonicalize_qual((Expr *) result);
2879
result = (List *) eval_const_expressions((Node *) result);
2882
* Also mark any coercion format fields as "don't care", so that the
2883
* planner can match to both explicit and implicit coercions.
2885
set_coercionform_dontcare((Node *) result);
2887
/* Also convert to implicit-AND format */
2888
result = make_ands_implicit((Expr *) result);
2890
/* May as well fix opfuncids too */
2891
fix_opfuncids((Node *) result);
2893
/* Now save a copy of the completed tree in the relcache entry. */
2894
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
2895
relation->rd_indpred = (List *) copyObject(result);
2896
MemoryContextSwitchTo(oldcxt);
2903
* load_relcache_init_file, write_relcache_init_file
2905
* In late 1992, we started regularly having databases with more than
2906
* a thousand classes in them. With this number of classes, it became
2907
* critical to do indexed lookups on the system catalogs.
2909
* Bootstrapping these lookups is very hard. We want to be able to
2910
* use an index on pg_attribute, for example, but in order to do so,
2911
* we must have read pg_attribute for the attributes in the index,
2912
* which implies that we need to use the index.
2914
* In order to get around the problem, we do the following:
2916
* + When the database system is initialized (at initdb time), we
2917
* don't use indexes. We do sequential scans.
2919
* + When the backend is started up in normal mode, we load an image
2920
* of the appropriate relation descriptors, in internal format,
2921
* from an initialization file in the data/base/... directory.
2923
* + If the initialization file isn't there, then we create the
2924
* relation descriptors using sequential scans and write 'em to
2925
* the initialization file for use by subsequent backends.
2927
* We could dispense with the initialization file and just build the
2928
* critical reldescs the hard way on every backend startup, but that
2929
* slows down backend startup noticeably.
2931
* We can in fact go further, and save more relcache entries than
2932
* just the ones that are absolutely critical; this allows us to speed
2933
* up backend startup by not having to build such entries the hard way.
2934
* Presently, all the catalog and index entries that are referred to
2935
* by catcaches are stored in the initialization file.
2937
* The same mechanism that detects when catcache and relcache entries
2938
* need to be invalidated (due to catalog updates) also arranges to
2939
* unlink the initialization file when its contents may be out of date.
2940
* The file will then be rebuilt during the next backend startup.
2944
* load_relcache_init_file -- attempt to load cache from the init file
2946
* If successful, return TRUE and set criticalRelcachesBuilt to true.
2947
* If not successful, return FALSE and set needNewCacheFile to true.
2949
* NOTE: we assume we are already switched into CacheMemoryContext.
2952
load_relcache_init_file(void)
2955
char initfilename[MAXPGPATH];
2965
snprintf(initfilename, sizeof(initfilename), "%s/%s",
2966
DatabasePath, RELCACHE_INIT_FILENAME);
2968
fp = AllocateFile(initfilename, PG_BINARY_R);
2971
needNewCacheFile = true;
2976
* Read the index relcache entries from the file. Note we will not
2977
* enter any of them into the cache if the read fails partway through;
2978
* this helps to guard against broken init files.
2981
rels = (Relation *) palloc(max_rels * sizeof(Relation));
2983
nailed_rels = nailed_indexes = 0;
2984
initFileRelationIds = NIL;
2986
/* check for correct magic number (compatible version) */
2987
if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
2989
if (magic != RELCACHE_INIT_FILEMAGIC)
2992
for (relno = 0;; relno++)
2997
Form_pg_class relform;
3000
/* first read the relation descriptor length */
3001
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3004
break; /* end of file */
3008
/* safety check for incompatible relcache layout */
3009
if (len != sizeof(RelationData))
3012
/* allocate another relcache header */
3013
if (num_rels >= max_rels)
3016
rels = (Relation *) repalloc(rels, max_rels * sizeof(Relation));
3019
rel = rels[num_rels++] = (Relation) palloc(len);
3021
/* then, read the Relation structure */
3022
if ((nread = fread(rel, 1, len, fp)) != len)
3025
/* next read the relation tuple form */
3026
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3029
relform = (Form_pg_class) palloc(len);
3030
if ((nread = fread(relform, 1, len, fp)) != len)
3033
rel->rd_rel = relform;
3035
/* initialize attribute tuple forms */
3036
rel->rd_att = CreateTemplateTupleDesc(relform->relnatts,
3037
relform->relhasoids);
3038
rel->rd_att->tdtypeid = relform->reltype;
3039
rel->rd_att->tdtypmod = -1; /* unnecessary, but... */
3041
/* next read all the attribute tuple form data entries */
3042
has_not_null = false;
3043
for (i = 0; i < relform->relnatts; i++)
3045
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3048
rel->rd_att->attrs[i] = (Form_pg_attribute) palloc(len);
3050
if ((nread = fread(rel->rd_att->attrs[i], 1, len, fp)) != len)
3053
has_not_null |= rel->rd_att->attrs[i]->attnotnull;
3056
/* mark not-null status */
3059
TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
3061
constr->has_not_null = true;
3062
rel->rd_att->constr = constr;
3065
/* If it's an index, there's more to do */
3066
if (rel->rd_rel->relkind == RELKIND_INDEX)
3069
MemoryContext indexcxt;
3071
RegProcedure *support;
3074
/* Count nailed indexes to ensure we have 'em all */
3075
if (rel->rd_isnailed)
3078
/* next, read the pg_index tuple */
3079
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3082
rel->rd_indextuple = (HeapTuple) palloc(len);
3083
if ((nread = fread(rel->rd_indextuple, 1, len, fp)) != len)
3086
/* Fix up internal pointers in the tuple -- see heap_copytuple */
3087
rel->rd_indextuple->t_datamcxt = CurrentMemoryContext;
3088
rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE);
3089
rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple);
3091
/* next, read the access method tuple form */
3092
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3095
am = (Form_pg_am) palloc(len);
3096
if ((nread = fread(am, 1, len, fp)) != len)
3101
* prepare index info context --- parameters should match
3102
* RelationInitIndexAccessInfo
3104
indexcxt = AllocSetContextCreate(CacheMemoryContext,
3105
RelationGetRelationName(rel),
3106
ALLOCSET_SMALL_MINSIZE,
3107
ALLOCSET_SMALL_INITSIZE,
3108
ALLOCSET_SMALL_MAXSIZE);
3109
rel->rd_indexcxt = indexcxt;
3111
/* next, read the vector of operator OIDs */
3112
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3115
operator = (Oid *) MemoryContextAlloc(indexcxt, len);
3116
if ((nread = fread(operator, 1, len, fp)) != len)
3119
rel->rd_operator = operator;
3121
/* finally, read the vector of support procedures */
3122
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
3124
support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
3125
if ((nread = fread(support, 1, len, fp)) != len)
3128
rel->rd_support = support;
3130
/* add a zeroed support-fmgr-info vector */
3131
nsupport = relform->relnatts * am->amsupport;
3132
rel->rd_supportinfo = (FmgrInfo *)
3133
MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
3137
/* Count nailed rels to ensure we have 'em all */
3138
if (rel->rd_isnailed)
3141
Assert(rel->rd_index == NULL);
3142
Assert(rel->rd_indextuple == NULL);
3143
Assert(rel->rd_am == NULL);
3144
Assert(rel->rd_indexcxt == NULL);
3145
Assert(rel->rd_operator == NULL);
3146
Assert(rel->rd_support == NULL);
3147
Assert(rel->rd_supportinfo == NULL);
3151
* Rules and triggers are not saved (mainly because the internal
3152
* format is complex and subject to change). They must be rebuilt
3153
* if needed by RelationCacheInitializePhase2. This is not
3154
* expected to be a big performance hit since few system catalogs
3155
* have such. Ditto for index expressions and predicates.
3157
rel->rd_rules = NULL;
3158
rel->rd_rulescxt = NULL;
3159
rel->trigdesc = NULL;
3160
rel->rd_indexprs = NIL;
3161
rel->rd_indpred = NIL;
3164
* Reset transient-state fields in the relcache entry
3166
rel->rd_smgr = NULL;
3167
rel->rd_targblock = InvalidBlockNumber;
3168
if (rel->rd_isnailed)
3172
rel->rd_indexvalid = 0;
3173
rel->rd_indexlist = NIL;
3174
rel->rd_createSubid = InvalidSubTransactionId;
3175
MemSet(&rel->pgstat_info, 0, sizeof(rel->pgstat_info));
3178
* Recompute lock and physical addressing info. This is needed in
3179
* case the pg_internal.init file was copied from some other
3180
* database by CREATE DATABASE.
3182
RelationInitLockInfo(rel);
3183
RelationInitPhysicalAddr(rel);
3187
* We reached the end of the init file without apparent problem. Did
3188
* we get the right number of nailed items? (This is a useful
3189
* crosscheck in case the set of critical rels or indexes changes.)
3191
if (nailed_rels != NUM_CRITICAL_RELS ||
3192
nailed_indexes != NUM_CRITICAL_INDEXES)
3196
* OK, all appears well.
3198
* Now insert all the new relcache entries into the cache.
3200
for (relno = 0; relno < num_rels; relno++)
3202
RelationCacheInsert(rels[relno]);
3203
/* also make a list of their OIDs, for RelationIdIsInInitFile */
3204
initFileRelationIds = lcons_oid(RelationGetRelid(rels[relno]),
3205
initFileRelationIds);
3211
criticalRelcachesBuilt = true;
3215
* init file is broken, so do it the hard way. We don't bother trying
3216
* to free the clutter we just allocated; it's not in the relcache so
3223
needNewCacheFile = true;
3228
* Write out a new initialization file with the current contents
3232
write_relcache_init_file(void)
3235
char tempfilename[MAXPGPATH];
3236
char finalfilename[MAXPGPATH];
3238
HASH_SEQ_STATUS status;
3239
RelIdCacheEnt *idhentry;
3240
MemoryContext oldcxt;
3244
* We must write a temporary file and rename it into place. Otherwise,
3245
* another backend starting at about the same time might crash trying
3246
* to read the partially-complete file.
3248
snprintf(tempfilename, sizeof(tempfilename), "%s/%s.%d",
3249
DatabasePath, RELCACHE_INIT_FILENAME, MyProcPid);
3250
snprintf(finalfilename, sizeof(finalfilename), "%s/%s",
3251
DatabasePath, RELCACHE_INIT_FILENAME);
3253
unlink(tempfilename); /* in case it exists w/wrong permissions */
3255
fp = AllocateFile(tempfilename, PG_BINARY_W);
3259
* We used to consider this a fatal error, but we might as well
3260
* continue with backend startup ...
3263
(errcode_for_file_access(),
3264
errmsg("could not create relation-cache initialization file \"%s\": %m",
3266
errdetail("Continuing anyway, but there's something wrong.")));
3271
* Write a magic number to serve as a file version identifier. We can
3272
* change the magic number whenever the relcache layout changes.
3274
magic = RELCACHE_INIT_FILEMAGIC;
3275
if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
3276
elog(FATAL, "could not write init file");
3279
* Write all the reldescs (in no particular order).
3281
hash_seq_init(&status, RelationIdCache);
3283
initFileRelationIds = NIL;
3285
while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3287
Relation rel = idhentry->reldesc;
3288
Form_pg_class relform = rel->rd_rel;
3292
* first write the relcache entry proper
3294
len = sizeof(RelationData);
3296
/* first, write the relation descriptor length */
3297
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3298
elog(FATAL, "could not write init file");
3300
/* next, write out the Relation structure */
3301
if (fwrite(rel, 1, len, fp) != len)
3302
elog(FATAL, "could not write init file");
3304
/* next write the relation tuple form */
3305
len = sizeof(FormData_pg_class);
3306
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3307
elog(FATAL, "could not write init file");
3309
if (fwrite(relform, 1, len, fp) != len)
3310
elog(FATAL, "could not write init file");
3312
/* next, do all the attribute tuple form data entries */
3313
for (i = 0; i < relform->relnatts; i++)
3315
len = ATTRIBUTE_TUPLE_SIZE;
3316
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3317
elog(FATAL, "could not write init file");
3318
if (fwrite(rel->rd_att->attrs[i], 1, len, fp) != len)
3319
elog(FATAL, "could not write init file");
3322
/* If it's an index, there's more to do */
3323
if (rel->rd_rel->relkind == RELKIND_INDEX)
3325
Form_pg_am am = rel->rd_am;
3327
/* write the pg_index tuple */
3328
/* we assume this was created by heap_copytuple! */
3329
len = HEAPTUPLESIZE + rel->rd_indextuple->t_len;
3330
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3331
elog(FATAL, "could not write init file");
3333
if (fwrite(rel->rd_indextuple, 1, len, fp) != len)
3334
elog(FATAL, "could not write init file");
3336
/* next, write the access method tuple form */
3337
len = sizeof(FormData_pg_am);
3338
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3339
elog(FATAL, "could not write init file");
3341
if (fwrite(am, 1, len, fp) != len)
3342
elog(FATAL, "could not write init file");
3344
/* next, write the vector of operator OIDs */
3345
len = relform->relnatts * (am->amstrategies * sizeof(Oid));
3346
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3347
elog(FATAL, "could not write init file");
3349
if (fwrite(rel->rd_operator, 1, len, fp) != len)
3350
elog(FATAL, "could not write init file");
3352
/* finally, write the vector of support procedures */
3353
len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
3354
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
3355
elog(FATAL, "could not write init file");
3357
if (fwrite(rel->rd_support, 1, len, fp) != len)
3358
elog(FATAL, "could not write init file");
3361
/* also make a list of their OIDs, for RelationIdIsInInitFile */
3362
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
3363
initFileRelationIds = lcons_oid(RelationGetRelid(rel),
3364
initFileRelationIds);
3365
MemoryContextSwitchTo(oldcxt);
3369
elog(FATAL, "could not write init file");
3372
* Now we have to check whether the data we've so painstakingly
3373
* accumulated is already obsolete due to someone else's
3374
* just-committed catalog changes. If so, we just delete the temp
3375
* file and leave it to the next backend to try again. (Our own
3376
* relcache entries will be updated by SI message processing, but we
3377
* can't be sure whether what we wrote out was up-to-date.)
3379
* This mustn't run concurrently with RelationCacheInitFileInvalidate, so
3380
* grab a serialization lock for the duration.
3382
LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3384
/* Make sure we have seen all incoming SI messages */
3385
AcceptInvalidationMessages();
3388
* If we have received any SI relcache invals since backend start,
3389
* assume we may have written out-of-date data.
3391
if (relcacheInvalsReceived == 0L)
3394
* OK, rename the temp file to its final name, deleting any
3395
* previously-existing init file.
3397
* Note: a failure here is possible under Cygwin, if some other
3398
* backend is holding open an unlinked-but-not-yet-gone init file.
3399
* So treat this as a noncritical failure; just remove the useless
3400
* temp file on failure.
3402
if (rename(tempfilename, finalfilename) < 0)
3403
unlink(tempfilename);
3407
/* Delete the already-obsolete temp file */
3408
unlink(tempfilename);
3411
LWLockRelease(RelCacheInitLock);
3415
* Detect whether a given relation (identified by OID) is one of the ones
3416
* we store in the init file.
3418
* Note that we effectively assume that all backends running in a database
3419
* would choose to store the same set of relations in the init file;
3420
* otherwise there are cases where we'd fail to detect the need for an init
3421
* file invalidation. This does not seem likely to be a problem in practice.
3424
RelationIdIsInInitFile(Oid relationId)
3426
return list_member_oid(initFileRelationIds, relationId);
3430
* Invalidate (remove) the init file during commit of a transaction that
3431
* changed one or more of the relation cache entries that are kept in the
3434
* We actually need to remove the init file twice: once just before sending
3435
* the SI messages that include relcache inval for such relations, and once
3436
* just after sending them. The unlink before ensures that a backend that's
3437
* currently starting cannot read the now-obsolete init file and then miss
3438
* the SI messages that will force it to update its relcache entries. (This
3439
* works because the backend startup sequence gets into the PROC array before
3440
* trying to load the init file.) The unlink after is to synchronize with a
3441
* backend that may currently be trying to write an init file based on data
3442
* that we've just rendered invalid. Such a backend will see the SI messages,
3443
* but we can't leave the init file sitting around to fool later backends.
3445
* Ignore any failure to unlink the file, since it might not be there if
3446
* no backend has been started since the last removal.
3449
RelationCacheInitFileInvalidate(bool beforeSend)
3451
char initfilename[MAXPGPATH];
3453
snprintf(initfilename, sizeof(initfilename), "%s/%s",
3454
DatabasePath, RELCACHE_INIT_FILENAME);
3458
/* no interlock needed here */
3459
unlink(initfilename);
3464
* We need to interlock this against write_relcache_init_file, to
3465
* guard against possibility that someone renames a new-but-
3466
* already-obsolete init file into place just after we unlink.
3467
* With the interlock, it's certain that write_relcache_init_file
3468
* will notice our SI inval message before renaming into place, or
3469
* else that we will execute second and successfully unlink the
3472
LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
3473
unlink(initfilename);
3474
LWLockRelease(RelCacheInitLock);