PostgreSQL Source Code  git master
relcache.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * relcache.c
4  * POSTGRES relation descriptor cache code
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/utils/cache/relcache.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * INTERFACE ROUTINES
17  * RelationCacheInitialize - initialize relcache (to empty)
18  * RelationCacheInitializePhase2 - initialize shared-catalog entries
19  * RelationCacheInitializePhase3 - finish initializing relcache
20  * RelationIdGetRelation - get a reldesc by relation id
21  * RelationClose - close an open relation
22  *
23  * NOTES
24  * The following code contains many undocumented hacks. Please be
25  * careful....
26  */
27 #include "postgres.h"
28 
29 #include <sys/file.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 
33 #include "access/htup_details.h"
34 #include "access/multixact.h"
35 #include "access/parallel.h"
36 #include "access/reloptions.h"
37 #include "access/sysattr.h"
38 #include "access/table.h"
39 #include "access/tableam.h"
40 #include "access/tupdesc_details.h"
41 #include "access/xact.h"
42 #include "catalog/binary_upgrade.h"
43 #include "catalog/catalog.h"
44 #include "catalog/indexing.h"
45 #include "catalog/namespace.h"
46 #include "catalog/partition.h"
47 #include "catalog/pg_am.h"
48 #include "catalog/pg_amproc.h"
49 #include "catalog/pg_attrdef.h"
51 #include "catalog/pg_authid.h"
52 #include "catalog/pg_constraint.h"
53 #include "catalog/pg_database.h"
54 #include "catalog/pg_namespace.h"
55 #include "catalog/pg_opclass.h"
56 #include "catalog/pg_proc.h"
57 #include "catalog/pg_publication.h"
58 #include "catalog/pg_rewrite.h"
59 #include "catalog/pg_shseclabel.h"
62 #include "catalog/pg_tablespace.h"
63 #include "catalog/pg_trigger.h"
64 #include "catalog/pg_type.h"
65 #include "catalog/schemapg.h"
66 #include "catalog/storage.h"
67 #include "commands/policy.h"
69 #include "commands/trigger.h"
70 #include "common/int.h"
71 #include "miscadmin.h"
72 #include "nodes/makefuncs.h"
73 #include "nodes/nodeFuncs.h"
74 #include "optimizer/optimizer.h"
75 #include "pgstat.h"
76 #include "rewrite/rewriteDefine.h"
77 #include "rewrite/rowsecurity.h"
78 #include "storage/lmgr.h"
79 #include "storage/smgr.h"
80 #include "utils/array.h"
81 #include "utils/builtins.h"
82 #include "utils/catcache.h"
83 #include "utils/datum.h"
84 #include "utils/fmgroids.h"
85 #include "utils/inval.h"
86 #include "utils/lsyscache.h"
87 #include "utils/memutils.h"
88 #include "utils/relmapper.h"
89 #include "utils/resowner.h"
90 #include "utils/snapmgr.h"
91 #include "utils/syscache.h"
92 
93 #define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */
94 
95 /*
96  * Whether to bother checking if relation cache memory needs to be freed
97  * eagerly. See also RelationBuildDesc() and pg_config_manual.h.
98  */
99 #if defined(RECOVER_RELATION_BUILD_MEMORY) && (RECOVER_RELATION_BUILD_MEMORY != 0)
100 #define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1
101 #else
102 #define RECOVER_RELATION_BUILD_MEMORY 0
103 #ifdef DISCARD_CACHES_ENABLED
104 #define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1
105 #endif
106 #endif
107 
108 /*
109  * hardcoded tuple descriptors, contents generated by genbki.pl
110  */
111 static const FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
112 static const FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
113 static const FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
114 static const FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
115 static const FormData_pg_attribute Desc_pg_database[Natts_pg_database] = {Schema_pg_database};
116 static const FormData_pg_attribute Desc_pg_authid[Natts_pg_authid] = {Schema_pg_authid};
117 static const FormData_pg_attribute Desc_pg_auth_members[Natts_pg_auth_members] = {Schema_pg_auth_members};
118 static const FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
119 static const FormData_pg_attribute Desc_pg_shseclabel[Natts_pg_shseclabel] = {Schema_pg_shseclabel};
120 static const FormData_pg_attribute Desc_pg_subscription[Natts_pg_subscription] = {Schema_pg_subscription};
121 
122 /*
123  * Hash tables that index the relation cache
124  *
125  * We used to index the cache by both name and OID, but now there
126  * is only an index by OID.
127  */
128 typedef struct relidcacheent
129 {
133 
135 
136 /*
137  * This flag is false until we have prepared the critical relcache entries
138  * that are needed to do indexscans on the tables read by relcache building.
139  */
141 
142 /*
143  * This flag is false until we have prepared the critical relcache entries
144  * for shared catalogs (which are the tables needed for login).
145  */
147 
148 /*
149  * This counter counts relcache inval events received since backend startup
150  * (but only for rels that are actually in cache). Presently, we use it only
151  * to detect whether data about to be written by write_relcache_init_file()
152  * might already be obsolete.
153  */
154 static long relcacheInvalsReceived = 0L;
155 
156 /*
157  * in_progress_list is a stack of ongoing RelationBuildDesc() calls. CREATE
158  * INDEX CONCURRENTLY makes catalog changes under ShareUpdateExclusiveLock.
159  * It critically relies on each backend absorbing those changes no later than
160  * next transaction start. Hence, RelationBuildDesc() loops until it finishes
161  * without accepting a relevant invalidation. (Most invalidation consumers
162  * don't do this.)
163  */
164 typedef struct inprogressent
165 {
166  Oid reloid; /* OID of relation being built */
167  bool invalidated; /* whether an invalidation arrived for it */
169 
173 
174 /*
175  * eoxact_list[] stores the OIDs of relations that (might) need AtEOXact
176  * cleanup work. This list intentionally has limited size; if it overflows,
177  * we fall back to scanning the whole hashtable. There is no value in a very
178  * large list because (1) at some point, a hash_seq_search scan is faster than
179  * retail lookups, and (2) the value of this is to reduce EOXact work for
180  * short transactions, which can't have dirtied all that many tables anyway.
181  * EOXactListAdd() does not bother to prevent duplicate list entries, so the
182  * cleanup processing must be idempotent.
183  */
184 #define MAX_EOXACT_LIST 32
186 static int eoxact_list_len = 0;
187 static bool eoxact_list_overflowed = false;
188 
189 #define EOXactListAdd(rel) \
190  do { \
191  if (eoxact_list_len < MAX_EOXACT_LIST) \
192  eoxact_list[eoxact_list_len++] = (rel)->rd_id; \
193  else \
194  eoxact_list_overflowed = true; \
195  } while (0)
196 
197 /*
198  * EOXactTupleDescArray stores TupleDescs that (might) need AtEOXact
199  * cleanup work. The array expands as needed; there is no hashtable because
200  * we don't need to access individual items except at EOXact.
201  */
203 static int NextEOXactTupleDescNum = 0;
204 static int EOXactTupleDescArrayLen = 0;
205 
206 /*
207  * macros to manipulate the lookup hashtable
208  */
209 #define RelationCacheInsert(RELATION, replace_allowed) \
210 do { \
211  RelIdCacheEnt *hentry; bool found; \
212  hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
213  &((RELATION)->rd_id), \
214  HASH_ENTER, &found); \
215  if (found) \
216  { \
217  /* see comments in RelationBuildDesc and RelationBuildLocalRelation */ \
218  Relation _old_rel = hentry->reldesc; \
219  Assert(replace_allowed); \
220  hentry->reldesc = (RELATION); \
221  if (RelationHasReferenceCountZero(_old_rel)) \
222  RelationDestroyRelation(_old_rel, false); \
223  else if (!IsBootstrapProcessingMode()) \
224  elog(WARNING, "leaking still-referenced relcache entry for \"%s\"", \
225  RelationGetRelationName(_old_rel)); \
226  } \
227  else \
228  hentry->reldesc = (RELATION); \
229 } while(0)
230 
231 #define RelationIdCacheLookup(ID, RELATION) \
232 do { \
233  RelIdCacheEnt *hentry; \
234  hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
235  &(ID), \
236  HASH_FIND, NULL); \
237  if (hentry) \
238  RELATION = hentry->reldesc; \
239  else \
240  RELATION = NULL; \
241 } while(0)
242 
243 #define RelationCacheDelete(RELATION) \
244 do { \
245  RelIdCacheEnt *hentry; \
246  hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
247  &((RELATION)->rd_id), \
248  HASH_REMOVE, NULL); \
249  if (hentry == NULL) \
250  elog(WARNING, "failed to delete relcache entry for OID %u", \
251  (RELATION)->rd_id); \
252 } while(0)
253 
254 
255 /*
256  * Special cache for opclass-related information
257  *
258  * Note: only default support procs get cached, ie, those with
259  * lefttype = righttype = opcintype.
260  */
261 typedef struct opclasscacheent
262 {
263  Oid opclassoid; /* lookup key: OID of opclass */
264  bool valid; /* set true after successful fill-in */
265  StrategyNumber numSupport; /* max # of support procs (from pg_am) */
266  Oid opcfamily; /* OID of opclass's family */
267  Oid opcintype; /* OID of opclass's declared input type */
268  RegProcedure *supportProcs; /* OIDs of support procedures */
270 
271 static HTAB *OpClassCache = NULL;
272 
273 
274 /* non-export function prototypes */
275 
276 static void RelationCloseCleanup(Relation relation);
277 static void RelationDestroyRelation(Relation relation, bool remember_tupdesc);
278 static void RelationInvalidateRelation(Relation relation);
279 static void RelationClearRelation(Relation relation, bool rebuild);
280 
281 static void RelationReloadIndexInfo(Relation relation);
282 static void RelationReloadNailed(Relation relation);
283 static void RelationFlushRelation(Relation relation);
285 #ifdef USE_ASSERT_CHECKING
286 static void AssertPendingSyncConsistency(Relation relation);
287 #endif
288 static void AtEOXact_cleanup(Relation relation, bool isCommit);
289 static void AtEOSubXact_cleanup(Relation relation, bool isCommit,
290  SubTransactionId mySubid, SubTransactionId parentSubid);
291 static bool load_relcache_init_file(bool shared);
292 static void write_relcache_init_file(bool shared);
293 static void write_item(const void *data, Size len, FILE *fp);
294 
295 static void formrdesc(const char *relationName, Oid relationReltype,
296  bool isshared, int natts, const FormData_pg_attribute *attrs);
297 
298 static HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic);
300 static void RelationParseRelOptions(Relation relation, HeapTuple tuple);
301 static void RelationBuildTupleDesc(Relation relation);
302 static Relation RelationBuildDesc(Oid targetRelId, bool insertIt);
303 static void RelationInitPhysicalAddr(Relation relation);
304 static void load_critical_index(Oid indexoid, Oid heapoid);
305 static TupleDesc GetPgClassDescriptor(void);
306 static TupleDesc GetPgIndexDescriptor(void);
307 static void AttrDefaultFetch(Relation relation, int ndef);
308 static int AttrDefaultCmp(const void *a, const void *b);
309 static void CheckConstraintFetch(Relation relation);
310 static int CheckConstraintCmp(const void *a, const void *b);
311 static void InitIndexAmRoutine(Relation relation);
312 static void IndexSupportInitialize(oidvector *indclass,
313  RegProcedure *indexSupport,
314  Oid *opFamily,
315  Oid *opcInType,
316  StrategyNumber maxSupportNumber,
317  AttrNumber maxAttributeNumber);
318 static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
319  StrategyNumber numSupport);
320 static void RelationCacheInitFileRemoveInDir(const char *tblspcpath);
321 static void unlink_initfile(const char *initfilename, int elevel);
322 
323 
324 /*
325  * ScanPgRelation
326  *
327  * This is used by RelationBuildDesc to find a pg_class
328  * tuple matching targetRelId. The caller must hold at least
329  * AccessShareLock on the target relid to prevent concurrent-update
330  * scenarios; it isn't guaranteed that all scans used to build the
331  * relcache entry will use the same snapshot. If, for example,
332  * an attribute were to be added after scanning pg_class and before
333  * scanning pg_attribute, relnatts wouldn't match.
334  *
335  * NB: the returned tuple has been copied into palloc'd storage
336  * and must eventually be freed with heap_freetuple.
337  */
338 static HeapTuple
339 ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
340 {
341  HeapTuple pg_class_tuple;
342  Relation pg_class_desc;
343  SysScanDesc pg_class_scan;
344  ScanKeyData key[1];
345  Snapshot snapshot = NULL;
346 
347  /*
348  * If something goes wrong during backend startup, we might find ourselves
349  * trying to read pg_class before we've selected a database. That ain't
350  * gonna work, so bail out with a useful error message. If this happens,
351  * it probably means a relcache entry that needs to be nailed isn't.
352  */
353  if (!OidIsValid(MyDatabaseId))
354  elog(FATAL, "cannot read pg_class without having selected a database");
355 
356  /*
357  * form a scan key
358  */
359  ScanKeyInit(&key[0],
360  Anum_pg_class_oid,
361  BTEqualStrategyNumber, F_OIDEQ,
362  ObjectIdGetDatum(targetRelId));
363 
364  /*
365  * Open pg_class and fetch a tuple. Force heap scan if we haven't yet
366  * built the critical relcache entries (this includes initdb and startup
367  * without a pg_internal.init file). The caller can also force a heap
368  * scan by setting indexOK == false.
369  */
370  pg_class_desc = table_open(RelationRelationId, AccessShareLock);
371 
372  /*
373  * The caller might need a tuple that's newer than the one the historic
374  * snapshot; currently the only case requiring to do so is looking up the
375  * relfilenumber of non mapped system relations during decoding. That
376  * snapshot can't change in the midst of a relcache build, so there's no
377  * need to register the snapshot.
378  */
379  if (force_non_historic)
380  snapshot = GetNonHistoricCatalogSnapshot(RelationRelationId);
381 
382  pg_class_scan = systable_beginscan(pg_class_desc, ClassOidIndexId,
383  indexOK && criticalRelcachesBuilt,
384  snapshot,
385  1, key);
386 
387  pg_class_tuple = systable_getnext(pg_class_scan);
388 
389  /*
390  * Must copy tuple before releasing buffer.
391  */
392  if (HeapTupleIsValid(pg_class_tuple))
393  pg_class_tuple = heap_copytuple(pg_class_tuple);
394 
395  /* all done */
396  systable_endscan(pg_class_scan);
397  table_close(pg_class_desc, AccessShareLock);
398 
399  return pg_class_tuple;
400 }
401 
402 /*
403  * AllocateRelationDesc
404  *
405  * This is used to allocate memory for a new relation descriptor
406  * and initialize the rd_rel field from the given pg_class tuple.
407  */
408 static Relation
410 {
411  Relation relation;
412  MemoryContext oldcxt;
413  Form_pg_class relationForm;
414 
415  /* Relcache entries must live in CacheMemoryContext */
417 
418  /*
419  * allocate and zero space for new relation descriptor
420  */
421  relation = (Relation) palloc0(sizeof(RelationData));
422 
423  /* make sure relation is marked as having no open file yet */
424  relation->rd_smgr = NULL;
425 
426  /*
427  * Copy the relation tuple form
428  *
429  * We only allocate space for the fixed fields, ie, CLASS_TUPLE_SIZE. The
430  * variable-length fields (relacl, reloptions) are NOT stored in the
431  * relcache --- there'd be little point in it, since we don't copy the
432  * tuple's nulls bitmap and hence wouldn't know if the values are valid.
433  * Bottom line is that relacl *cannot* be retrieved from the relcache. Get
434  * it from the syscache if you need it. The same goes for the original
435  * form of reloptions (however, we do store the parsed form of reloptions
436  * in rd_options).
437  */
438  relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
439 
440  memcpy(relationForm, relp, CLASS_TUPLE_SIZE);
441 
442  /* initialize relation tuple form */
443  relation->rd_rel = relationForm;
444 
445  /* and allocate attribute tuple form storage */
446  relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts);
447  /* which we mark as a reference-counted tupdesc */
448  relation->rd_att->tdrefcount = 1;
449 
450  MemoryContextSwitchTo(oldcxt);
451 
452  return relation;
453 }
454 
455 /*
456  * RelationParseRelOptions
457  * Convert pg_class.reloptions into pre-parsed rd_options
458  *
459  * tuple is the real pg_class tuple (not rd_rel!) for relation
460  *
461  * Note: rd_rel and (if an index) rd_indam must be valid already
462  */
463 static void
465 {
466  bytea *options;
467  amoptions_function amoptsfn;
468 
469  relation->rd_options = NULL;
470 
471  /*
472  * Look up any AM-specific parse function; fall out if relkind should not
473  * have options.
474  */
475  switch (relation->rd_rel->relkind)
476  {
477  case RELKIND_RELATION:
478  case RELKIND_TOASTVALUE:
479  case RELKIND_VIEW:
480  case RELKIND_MATVIEW:
481  case RELKIND_PARTITIONED_TABLE:
482  amoptsfn = NULL;
483  break;
484  case RELKIND_INDEX:
485  case RELKIND_PARTITIONED_INDEX:
486  amoptsfn = relation->rd_indam->amoptions;
487  break;
488  default:
489  return;
490  }
491 
492  /*
493  * Fetch reloptions from tuple; have to use a hardwired descriptor because
494  * we might not have any other for pg_class yet (consider executing this
495  * code for pg_class itself)
496  */
497  options = extractRelOptions(tuple, GetPgClassDescriptor(), amoptsfn);
498 
499  /*
500  * Copy parsed data into CacheMemoryContext. To guard against the
501  * possibility of leaks in the reloptions code, we want to do the actual
502  * parsing in the caller's memory context and copy the results into
503  * CacheMemoryContext after the fact.
504  */
505  if (options)
506  {
508  VARSIZE(options));
509  memcpy(relation->rd_options, options, VARSIZE(options));
510  pfree(options);
511  }
512 }
513 
514 /*
515  * RelationBuildTupleDesc
516  *
517  * Form the relation's tuple descriptor from information in
518  * the pg_attribute, pg_attrdef & pg_constraint system catalogs.
519  */
520 static void
522 {
523  HeapTuple pg_attribute_tuple;
524  Relation pg_attribute_desc;
525  SysScanDesc pg_attribute_scan;
526  ScanKeyData skey[2];
527  int need;
528  TupleConstr *constr;
529  AttrMissing *attrmiss = NULL;
530  int ndef = 0;
531 
532  /* fill rd_att's type ID fields (compare heap.c's AddNewRelationTuple) */
533  relation->rd_att->tdtypeid =
534  relation->rd_rel->reltype ? relation->rd_rel->reltype : RECORDOID;
535  relation->rd_att->tdtypmod = -1; /* just to be sure */
536 
538  sizeof(TupleConstr));
539 
540  /*
541  * Form a scan key that selects only user attributes (attnum > 0).
542  * (Eliminating system attribute rows at the index level is lots faster
543  * than fetching them.)
544  */
545  ScanKeyInit(&skey[0],
546  Anum_pg_attribute_attrelid,
547  BTEqualStrategyNumber, F_OIDEQ,
549  ScanKeyInit(&skey[1],
550  Anum_pg_attribute_attnum,
551  BTGreaterStrategyNumber, F_INT2GT,
552  Int16GetDatum(0));
553 
554  /*
555  * Open pg_attribute and begin a scan. Force heap scan if we haven't yet
556  * built the critical relcache entries (this includes initdb and startup
557  * without a pg_internal.init file).
558  */
559  pg_attribute_desc = table_open(AttributeRelationId, AccessShareLock);
560  pg_attribute_scan = systable_beginscan(pg_attribute_desc,
561  AttributeRelidNumIndexId,
563  NULL,
564  2, skey);
565 
566  /*
567  * add attribute data to relation->rd_att
568  */
569  need = RelationGetNumberOfAttributes(relation);
570 
571  while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
572  {
573  Form_pg_attribute attp;
574  int attnum;
575 
576  attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
577 
578  attnum = attp->attnum;
579  if (attnum <= 0 || attnum > RelationGetNumberOfAttributes(relation))
580  elog(ERROR, "invalid attribute number %d for relation \"%s\"",
581  attp->attnum, RelationGetRelationName(relation));
582 
583  memcpy(TupleDescAttr(relation->rd_att, attnum - 1),
584  attp,
586 
587  /* Update constraint/default info */
588  if (attp->attnotnull)
589  constr->has_not_null = true;
590  if (attp->attgenerated == ATTRIBUTE_GENERATED_STORED)
591  constr->has_generated_stored = true;
592  if (attp->atthasdef)
593  ndef++;
594 
595  /* If the column has a "missing" value, put it in the attrmiss array */
596  if (attp->atthasmissing)
597  {
598  Datum missingval;
599  bool missingNull;
600 
601  /* Do we have a missing value? */
602  missingval = heap_getattr(pg_attribute_tuple,
603  Anum_pg_attribute_attmissingval,
604  pg_attribute_desc->rd_att,
605  &missingNull);
606  if (!missingNull)
607  {
608  /* Yes, fetch from the array */
609  MemoryContext oldcxt;
610  bool is_null;
611  int one = 1;
612  Datum missval;
613 
614  if (attrmiss == NULL)
615  attrmiss = (AttrMissing *)
617  relation->rd_rel->relnatts *
618  sizeof(AttrMissing));
619 
620  missval = array_get_element(missingval,
621  1,
622  &one,
623  -1,
624  attp->attlen,
625  attp->attbyval,
626  attp->attalign,
627  &is_null);
628  Assert(!is_null);
629  if (attp->attbyval)
630  {
631  /* for copy by val just copy the datum direct */
632  attrmiss[attnum - 1].am_value = missval;
633  }
634  else
635  {
636  /* otherwise copy in the correct context */
638  attrmiss[attnum - 1].am_value = datumCopy(missval,
639  attp->attbyval,
640  attp->attlen);
641  MemoryContextSwitchTo(oldcxt);
642  }
643  attrmiss[attnum - 1].am_present = true;
644  }
645  }
646  need--;
647  if (need == 0)
648  break;
649  }
650 
651  /*
652  * end the scan and close the attribute relation
653  */
654  systable_endscan(pg_attribute_scan);
655  table_close(pg_attribute_desc, AccessShareLock);
656 
657  if (need != 0)
658  elog(ERROR, "pg_attribute catalog is missing %d attribute(s) for relation OID %u",
659  need, RelationGetRelid(relation));
660 
661  /*
662  * The attcacheoff values we read from pg_attribute should all be -1
663  * ("unknown"). Verify this if assert checking is on. They will be
664  * computed when and if needed during tuple access.
665  */
666 #ifdef USE_ASSERT_CHECKING
667  {
668  int i;
669 
670  for (i = 0; i < RelationGetNumberOfAttributes(relation); i++)
671  Assert(TupleDescAttr(relation->rd_att, i)->attcacheoff == -1);
672  }
673 #endif
674 
675  /*
676  * However, we can easily set the attcacheoff value for the first
677  * attribute: it must be zero. This eliminates the need for special cases
678  * for attnum=1 that used to exist in fastgetattr() and index_getattr().
679  */
680  if (RelationGetNumberOfAttributes(relation) > 0)
681  TupleDescAttr(relation->rd_att, 0)->attcacheoff = 0;
682 
683  /*
684  * Set up constraint/default info
685  */
686  if (constr->has_not_null ||
687  constr->has_generated_stored ||
688  ndef > 0 ||
689  attrmiss ||
690  relation->rd_rel->relchecks > 0)
691  {
692  relation->rd_att->constr = constr;
693 
694  if (ndef > 0) /* DEFAULTs */
695  AttrDefaultFetch(relation, ndef);
696  else
697  constr->num_defval = 0;
698 
699  constr->missing = attrmiss;
700 
701  if (relation->rd_rel->relchecks > 0) /* CHECKs */
702  CheckConstraintFetch(relation);
703  else
704  constr->num_check = 0;
705  }
706  else
707  {
708  pfree(constr);
709  relation->rd_att->constr = NULL;
710  }
711 }
712 
713 /*
714  * RelationBuildRuleLock
715  *
716  * Form the relation's rewrite rules from information in
717  * the pg_rewrite system catalog.
718  *
719  * Note: The rule parsetrees are potentially very complex node structures.
720  * To allow these trees to be freed when the relcache entry is flushed,
721  * we make a private memory context to hold the RuleLock information for
722  * each relcache entry that has associated rules. The context is used
723  * just for rule info, not for any other subsidiary data of the relcache
724  * entry, because that keeps the update logic in RelationClearRelation()
725  * manageable. The other subsidiary data structures are simple enough
726  * to be easy to free explicitly, anyway.
727  *
728  * Note: The relation's reloptions must have been extracted first.
729  */
730 static void
732 {
733  MemoryContext rulescxt;
734  MemoryContext oldcxt;
735  HeapTuple rewrite_tuple;
736  Relation rewrite_desc;
737  TupleDesc rewrite_tupdesc;
738  SysScanDesc rewrite_scan;
740  RuleLock *rulelock;
741  int numlocks;
742  RewriteRule **rules;
743  int maxlocks;
744 
745  /*
746  * Make the private context. Assume it'll not contain much data.
747  */
749  "relation rules",
751  relation->rd_rulescxt = rulescxt;
753  RelationGetRelationName(relation));
754 
755  /*
756  * allocate an array to hold the rewrite rules (the array is extended if
757  * necessary)
758  */
759  maxlocks = 4;
760  rules = (RewriteRule **)
761  MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
762  numlocks = 0;
763 
764  /*
765  * form a scan key
766  */
767  ScanKeyInit(&key,
768  Anum_pg_rewrite_ev_class,
769  BTEqualStrategyNumber, F_OIDEQ,
771 
772  /*
773  * open pg_rewrite and begin a scan
774  *
775  * Note: since we scan the rules using RewriteRelRulenameIndexId, we will
776  * be reading the rules in name order, except possibly during
777  * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn
778  * ensures that rules will be fired in name order.
779  */
780  rewrite_desc = table_open(RewriteRelationId, AccessShareLock);
781  rewrite_tupdesc = RelationGetDescr(rewrite_desc);
782  rewrite_scan = systable_beginscan(rewrite_desc,
783  RewriteRelRulenameIndexId,
784  true, NULL,
785  1, &key);
786 
787  while (HeapTupleIsValid(rewrite_tuple = systable_getnext(rewrite_scan)))
788  {
789  Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(rewrite_tuple);
790  bool isnull;
791  Datum rule_datum;
792  char *rule_str;
793  RewriteRule *rule;
794  Oid check_as_user;
795 
796  rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
797  sizeof(RewriteRule));
798 
799  rule->ruleId = rewrite_form->oid;
800 
801  rule->event = rewrite_form->ev_type - '0';
802  rule->enabled = rewrite_form->ev_enabled;
803  rule->isInstead = rewrite_form->is_instead;
804 
805  /*
806  * Must use heap_getattr to fetch ev_action and ev_qual. Also, the
807  * rule strings are often large enough to be toasted. To avoid
808  * leaking memory in the caller's context, do the detoasting here so
809  * we can free the detoasted version.
810  */
811  rule_datum = heap_getattr(rewrite_tuple,
812  Anum_pg_rewrite_ev_action,
813  rewrite_tupdesc,
814  &isnull);
815  Assert(!isnull);
816  rule_str = TextDatumGetCString(rule_datum);
817  oldcxt = MemoryContextSwitchTo(rulescxt);
818  rule->actions = (List *) stringToNode(rule_str);
819  MemoryContextSwitchTo(oldcxt);
820  pfree(rule_str);
821 
822  rule_datum = heap_getattr(rewrite_tuple,
823  Anum_pg_rewrite_ev_qual,
824  rewrite_tupdesc,
825  &isnull);
826  Assert(!isnull);
827  rule_str = TextDatumGetCString(rule_datum);
828  oldcxt = MemoryContextSwitchTo(rulescxt);
829  rule->qual = (Node *) stringToNode(rule_str);
830  MemoryContextSwitchTo(oldcxt);
831  pfree(rule_str);
832 
833  /*
834  * If this is a SELECT rule defining a view, and the view has
835  * "security_invoker" set, we must perform all permissions checks on
836  * relations referred to by the rule as the invoking user.
837  *
838  * In all other cases (including non-SELECT rules on security invoker
839  * views), perform the permissions checks as the relation owner.
840  */
841  if (rule->event == CMD_SELECT &&
842  relation->rd_rel->relkind == RELKIND_VIEW &&
843  RelationHasSecurityInvoker(relation))
844  check_as_user = InvalidOid;
845  else
846  check_as_user = relation->rd_rel->relowner;
847 
848  /*
849  * Scan through the rule's actions and set the checkAsUser field on
850  * all RTEPermissionInfos. We have to look at the qual as well, in
851  * case it contains sublinks.
852  *
853  * The reason for doing this when the rule is loaded, rather than when
854  * it is stored, is that otherwise ALTER TABLE OWNER would have to
855  * grovel through stored rules to update checkAsUser fields. Scanning
856  * the rule tree during load is relatively cheap (compared to
857  * constructing it in the first place), so we do it here.
858  */
859  setRuleCheckAsUser((Node *) rule->actions, check_as_user);
860  setRuleCheckAsUser(rule->qual, check_as_user);
861 
862  if (numlocks >= maxlocks)
863  {
864  maxlocks *= 2;
865  rules = (RewriteRule **)
866  repalloc(rules, sizeof(RewriteRule *) * maxlocks);
867  }
868  rules[numlocks++] = rule;
869  }
870 
871  /*
872  * end the scan and close the attribute relation
873  */
874  systable_endscan(rewrite_scan);
875  table_close(rewrite_desc, AccessShareLock);
876 
877  /*
878  * there might not be any rules (if relhasrules is out-of-date)
879  */
880  if (numlocks == 0)
881  {
882  relation->rd_rules = NULL;
883  relation->rd_rulescxt = NULL;
884  MemoryContextDelete(rulescxt);
885  return;
886  }
887 
888  /*
889  * form a RuleLock and insert into relation
890  */
891  rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
892  rulelock->numLocks = numlocks;
893  rulelock->rules = rules;
894 
895  relation->rd_rules = rulelock;
896 }
897 
898 /*
899  * equalRuleLocks
900  *
901  * Determine whether two RuleLocks are equivalent
902  *
903  * Probably this should be in the rules code someplace...
904  */
905 static bool
907 {
908  int i;
909 
910  /*
911  * As of 7.3 we assume the rule ordering is repeatable, because
912  * RelationBuildRuleLock should read 'em in a consistent order. So just
913  * compare corresponding slots.
914  */
915  if (rlock1 != NULL)
916  {
917  if (rlock2 == NULL)
918  return false;
919  if (rlock1->numLocks != rlock2->numLocks)
920  return false;
921  for (i = 0; i < rlock1->numLocks; i++)
922  {
923  RewriteRule *rule1 = rlock1->rules[i];
924  RewriteRule *rule2 = rlock2->rules[i];
925 
926  if (rule1->ruleId != rule2->ruleId)
927  return false;
928  if (rule1->event != rule2->event)
929  return false;
930  if (rule1->enabled != rule2->enabled)
931  return false;
932  if (rule1->isInstead != rule2->isInstead)
933  return false;
934  if (!equal(rule1->qual, rule2->qual))
935  return false;
936  if (!equal(rule1->actions, rule2->actions))
937  return false;
938  }
939  }
940  else if (rlock2 != NULL)
941  return false;
942  return true;
943 }
944 
945 /*
946  * equalPolicy
947  *
948  * Determine whether two policies are equivalent
949  */
950 static bool
952 {
953  int i;
954  Oid *r1,
955  *r2;
956 
957  if (policy1 != NULL)
958  {
959  if (policy2 == NULL)
960  return false;
961 
962  if (policy1->polcmd != policy2->polcmd)
963  return false;
964  if (policy1->hassublinks != policy2->hassublinks)
965  return false;
966  if (strcmp(policy1->policy_name, policy2->policy_name) != 0)
967  return false;
968  if (ARR_DIMS(policy1->roles)[0] != ARR_DIMS(policy2->roles)[0])
969  return false;
970 
971  r1 = (Oid *) ARR_DATA_PTR(policy1->roles);
972  r2 = (Oid *) ARR_DATA_PTR(policy2->roles);
973 
974  for (i = 0; i < ARR_DIMS(policy1->roles)[0]; i++)
975  {
976  if (r1[i] != r2[i])
977  return false;
978  }
979 
980  if (!equal(policy1->qual, policy2->qual))
981  return false;
982  if (!equal(policy1->with_check_qual, policy2->with_check_qual))
983  return false;
984  }
985  else if (policy2 != NULL)
986  return false;
987 
988  return true;
989 }
990 
991 /*
992  * equalRSDesc
993  *
994  * Determine whether two RowSecurityDesc's are equivalent
995  */
996 static bool
998 {
999  ListCell *lc,
1000  *rc;
1001 
1002  if (rsdesc1 == NULL && rsdesc2 == NULL)
1003  return true;
1004 
1005  if ((rsdesc1 != NULL && rsdesc2 == NULL) ||
1006  (rsdesc1 == NULL && rsdesc2 != NULL))
1007  return false;
1008 
1009  if (list_length(rsdesc1->policies) != list_length(rsdesc2->policies))
1010  return false;
1011 
1012  /* RelationBuildRowSecurity should build policies in order */
1013  forboth(lc, rsdesc1->policies, rc, rsdesc2->policies)
1014  {
1017 
1018  if (!equalPolicy(l, r))
1019  return false;
1020  }
1021 
1022  return true;
1023 }
1024 
1025 /*
1026  * RelationBuildDesc
1027  *
1028  * Build a relation descriptor. The caller must hold at least
1029  * AccessShareLock on the target relid.
1030  *
1031  * The new descriptor is inserted into the hash table if insertIt is true.
1032  *
1033  * Returns NULL if no pg_class row could be found for the given relid
1034  * (suggesting we are trying to access a just-deleted relation).
1035  * Any other error is reported via elog.
1036  */
1037 static Relation
1038 RelationBuildDesc(Oid targetRelId, bool insertIt)
1039 {
1040  int in_progress_offset;
1041  Relation relation;
1042  Oid relid;
1043  HeapTuple pg_class_tuple;
1044  Form_pg_class relp;
1045 
1046  /*
1047  * This function and its subroutines can allocate a good deal of transient
1048  * data in CurrentMemoryContext. Traditionally we've just leaked that
1049  * data, reasoning that the caller's context is at worst of transaction
1050  * scope, and relcache loads shouldn't happen so often that it's essential
1051  * to recover transient data before end of statement/transaction. However
1052  * that's definitely not true when debug_discard_caches is active, and
1053  * perhaps it's not true in other cases.
1054  *
1055  * When debug_discard_caches is active or when forced to by
1056  * RECOVER_RELATION_BUILD_MEMORY=1, arrange to allocate the junk in a
1057  * temporary context that we'll free before returning. Make it a child of
1058  * caller's context so that it will get cleaned up appropriately if we
1059  * error out partway through.
1060  */
1061 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1062  MemoryContext tmpcxt = NULL;
1063  MemoryContext oldcxt = NULL;
1064 
1066  {
1068  "RelationBuildDesc workspace",
1070  oldcxt = MemoryContextSwitchTo(tmpcxt);
1071  }
1072 #endif
1073 
1074  /* Register to catch invalidation messages */
1076  {
1077  int allocsize;
1078 
1079  allocsize = in_progress_list_maxlen * 2;
1081  allocsize * sizeof(*in_progress_list));
1082  in_progress_list_maxlen = allocsize;
1083  }
1084  in_progress_offset = in_progress_list_len++;
1085  in_progress_list[in_progress_offset].reloid = targetRelId;
1086 retry:
1087  in_progress_list[in_progress_offset].invalidated = false;
1088 
1089  /*
1090  * find the tuple in pg_class corresponding to the given relation id
1091  */
1092  pg_class_tuple = ScanPgRelation(targetRelId, true, false);
1093 
1094  /*
1095  * if no such tuple exists, return NULL
1096  */
1097  if (!HeapTupleIsValid(pg_class_tuple))
1098  {
1099 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1100  if (tmpcxt)
1101  {
1102  /* Return to caller's context, and blow away the temporary context */
1103  MemoryContextSwitchTo(oldcxt);
1104  MemoryContextDelete(tmpcxt);
1105  }
1106 #endif
1107  Assert(in_progress_offset + 1 == in_progress_list_len);
1109  return NULL;
1110  }
1111 
1112  /*
1113  * get information from the pg_class_tuple
1114  */
1115  relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
1116  relid = relp->oid;
1117  Assert(relid == targetRelId);
1118 
1119  /*
1120  * allocate storage for the relation descriptor, and copy pg_class_tuple
1121  * to relation->rd_rel.
1122  */
1123  relation = AllocateRelationDesc(relp);
1124 
1125  /*
1126  * initialize the relation's relation id (relation->rd_id)
1127  */
1128  RelationGetRelid(relation) = relid;
1129 
1130  /*
1131  * Normal relations are not nailed into the cache. Since we don't flush
1132  * new relations, it won't be new. It could be temp though.
1133  */
1134  relation->rd_refcnt = 0;
1135  relation->rd_isnailed = false;
1140  switch (relation->rd_rel->relpersistence)
1141  {
1142  case RELPERSISTENCE_UNLOGGED:
1143  case RELPERSISTENCE_PERMANENT:
1144  relation->rd_backend = INVALID_PROC_NUMBER;
1145  relation->rd_islocaltemp = false;
1146  break;
1147  case RELPERSISTENCE_TEMP:
1148  if (isTempOrTempToastNamespace(relation->rd_rel->relnamespace))
1149  {
1150  relation->rd_backend = ProcNumberForTempRelations();
1151  relation->rd_islocaltemp = true;
1152  }
1153  else
1154  {
1155  /*
1156  * If it's a temp table, but not one of ours, we have to use
1157  * the slow, grotty method to figure out the owning backend.
1158  *
1159  * Note: it's possible that rd_backend gets set to
1160  * MyProcNumber here, in case we are looking at a pg_class
1161  * entry left over from a crashed backend that coincidentally
1162  * had the same ProcNumber we're using. We should *not*
1163  * consider such a table to be "ours"; this is why we need the
1164  * separate rd_islocaltemp flag. The pg_class entry will get
1165  * flushed if/when we clean out the corresponding temp table
1166  * namespace in preparation for using it.
1167  */
1168  relation->rd_backend =
1169  GetTempNamespaceProcNumber(relation->rd_rel->relnamespace);
1170  Assert(relation->rd_backend != INVALID_PROC_NUMBER);
1171  relation->rd_islocaltemp = false;
1172  }
1173  break;
1174  default:
1175  elog(ERROR, "invalid relpersistence: %c",
1176  relation->rd_rel->relpersistence);
1177  break;
1178  }
1179 
1180  /*
1181  * initialize the tuple descriptor (relation->rd_att).
1182  */
1183  RelationBuildTupleDesc(relation);
1184 
1185  /* foreign key data is not loaded till asked for */
1186  relation->rd_fkeylist = NIL;
1187  relation->rd_fkeyvalid = false;
1188 
1189  /* partitioning data is not loaded till asked for */
1190  relation->rd_partkey = NULL;
1191  relation->rd_partkeycxt = NULL;
1192  relation->rd_partdesc = NULL;
1193  relation->rd_partdesc_nodetached = NULL;
1195  relation->rd_pdcxt = NULL;
1196  relation->rd_pddcxt = NULL;
1197  relation->rd_partcheck = NIL;
1198  relation->rd_partcheckvalid = false;
1199  relation->rd_partcheckcxt = NULL;
1200 
1201  /*
1202  * initialize access method information
1203  */
1204  if (relation->rd_rel->relkind == RELKIND_INDEX ||
1205  relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
1206  RelationInitIndexAccessInfo(relation);
1207  else if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) ||
1208  relation->rd_rel->relkind == RELKIND_SEQUENCE)
1210  else if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1211  {
1212  /*
1213  * Do nothing: access methods are a setting that partitions can
1214  * inherit.
1215  */
1216  }
1217  else
1218  Assert(relation->rd_rel->relam == InvalidOid);
1219 
1220  /* extract reloptions if any */
1221  RelationParseRelOptions(relation, pg_class_tuple);
1222 
1223  /*
1224  * Fetch rules and triggers that affect this relation.
1225  *
1226  * Note that RelationBuildRuleLock() relies on this being done after
1227  * extracting the relation's reloptions.
1228  */
1229  if (relation->rd_rel->relhasrules)
1230  RelationBuildRuleLock(relation);
1231  else
1232  {
1233  relation->rd_rules = NULL;
1234  relation->rd_rulescxt = NULL;
1235  }
1236 
1237  if (relation->rd_rel->relhastriggers)
1238  RelationBuildTriggers(relation);
1239  else
1240  relation->trigdesc = NULL;
1241 
1242  if (relation->rd_rel->relrowsecurity)
1243  RelationBuildRowSecurity(relation);
1244  else
1245  relation->rd_rsdesc = NULL;
1246 
1247  /*
1248  * initialize the relation lock manager information
1249  */
1250  RelationInitLockInfo(relation); /* see lmgr.c */
1251 
1252  /*
1253  * initialize physical addressing information for the relation
1254  */
1255  RelationInitPhysicalAddr(relation);
1256 
1257  /* make sure relation is marked as having no open file yet */
1258  relation->rd_smgr = NULL;
1259 
1260  /*
1261  * now we can free the memory allocated for pg_class_tuple
1262  */
1263  heap_freetuple(pg_class_tuple);
1264 
1265  /*
1266  * If an invalidation arrived mid-build, start over. Between here and the
1267  * end of this function, don't add code that does or reasonably could read
1268  * system catalogs. That range must be free from invalidation processing
1269  * for the !insertIt case. For the insertIt case, RelationCacheInsert()
1270  * will enroll this relation in ordinary relcache invalidation processing,
1271  */
1272  if (in_progress_list[in_progress_offset].invalidated)
1273  {
1274  RelationDestroyRelation(relation, false);
1275  goto retry;
1276  }
1277  Assert(in_progress_offset + 1 == in_progress_list_len);
1279 
1280  /*
1281  * Insert newly created relation into relcache hash table, if requested.
1282  *
1283  * There is one scenario in which we might find a hashtable entry already
1284  * present, even though our caller failed to find it: if the relation is a
1285  * system catalog or index that's used during relcache load, we might have
1286  * recursively created the same relcache entry during the preceding steps.
1287  * So allow RelationCacheInsert to delete any already-present relcache
1288  * entry for the same OID. The already-present entry should have refcount
1289  * zero (else somebody forgot to close it); in the event that it doesn't,
1290  * we'll elog a WARNING and leak the already-present entry.
1291  */
1292  if (insertIt)
1293  RelationCacheInsert(relation, true);
1294 
1295  /* It's fully valid */
1296  relation->rd_isvalid = true;
1297 
1298 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1299  if (tmpcxt)
1300  {
1301  /* Return to caller's context, and blow away the temporary context */
1302  MemoryContextSwitchTo(oldcxt);
1303  MemoryContextDelete(tmpcxt);
1304  }
1305 #endif
1306 
1307  return relation;
1308 }
1309 
1310 /*
1311  * Initialize the physical addressing info (RelFileLocator) for a relcache entry
1312  *
1313  * Note: at the physical level, relations in the pg_global tablespace must
1314  * be treated as shared, even if relisshared isn't set. Hence we do not
1315  * look at relisshared here.
1316  */
1317 static void
1319 {
1320  RelFileNumber oldnumber = relation->rd_locator.relNumber;
1321 
1322  /* these relations kinds never have storage */
1323  if (!RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
1324  return;
1325 
1326  if (relation->rd_rel->reltablespace)
1327  relation->rd_locator.spcOid = relation->rd_rel->reltablespace;
1328  else
1330  if (relation->rd_locator.spcOid == GLOBALTABLESPACE_OID)
1331  relation->rd_locator.dbOid = InvalidOid;
1332  else
1333  relation->rd_locator.dbOid = MyDatabaseId;
1334 
1335  if (relation->rd_rel->relfilenode)
1336  {
1337  /*
1338  * Even if we are using a decoding snapshot that doesn't represent the
1339  * current state of the catalog we need to make sure the filenode
1340  * points to the current file since the older file will be gone (or
1341  * truncated). The new file will still contain older rows so lookups
1342  * in them will work correctly. This wouldn't work correctly if
1343  * rewrites were allowed to change the schema in an incompatible way,
1344  * but those are prevented both on catalog tables and on user tables
1345  * declared as additional catalog tables.
1346  */
1349  && IsTransactionState())
1350  {
1351  HeapTuple phys_tuple;
1352  Form_pg_class physrel;
1353 
1354  phys_tuple = ScanPgRelation(RelationGetRelid(relation),
1355  RelationGetRelid(relation) != ClassOidIndexId,
1356  true);
1357  if (!HeapTupleIsValid(phys_tuple))
1358  elog(ERROR, "could not find pg_class entry for %u",
1359  RelationGetRelid(relation));
1360  physrel = (Form_pg_class) GETSTRUCT(phys_tuple);
1361 
1362  relation->rd_rel->reltablespace = physrel->reltablespace;
1363  relation->rd_rel->relfilenode = physrel->relfilenode;
1364  heap_freetuple(phys_tuple);
1365  }
1366 
1367  relation->rd_locator.relNumber = relation->rd_rel->relfilenode;
1368  }
1369  else
1370  {
1371  /* Consult the relation mapper */
1372  relation->rd_locator.relNumber =
1374  relation->rd_rel->relisshared);
1375  if (!RelFileNumberIsValid(relation->rd_locator.relNumber))
1376  elog(ERROR, "could not find relation mapping for relation \"%s\", OID %u",
1377  RelationGetRelationName(relation), relation->rd_id);
1378  }
1379 
1380  /*
1381  * For RelationNeedsWAL() to answer correctly on parallel workers, restore
1382  * rd_firstRelfilelocatorSubid. No subtransactions start or end while in
1383  * parallel mode, so the specific SubTransactionId does not matter.
1384  */
1385  if (IsParallelWorker() && oldnumber != relation->rd_locator.relNumber)
1386  {
1387  if (RelFileLocatorSkippingWAL(relation->rd_locator))
1389  else
1391  }
1392 }
1393 
1394 /*
1395  * Fill in the IndexAmRoutine for an index relation.
1396  *
1397  * relation's rd_amhandler and rd_indexcxt must be valid already.
1398  */
1399 static void
1401 {
1402  IndexAmRoutine *cached,
1403  *tmp;
1404 
1405  /*
1406  * Call the amhandler in current, short-lived memory context, just in case
1407  * it leaks anything (it probably won't, but let's be paranoid).
1408  */
1409  tmp = GetIndexAmRoutine(relation->rd_amhandler);
1410 
1411  /* OK, now transfer the data into relation's rd_indexcxt. */
1412  cached = (IndexAmRoutine *) MemoryContextAlloc(relation->rd_indexcxt,
1413  sizeof(IndexAmRoutine));
1414  memcpy(cached, tmp, sizeof(IndexAmRoutine));
1415  relation->rd_indam = cached;
1416 
1417  pfree(tmp);
1418 }
1419 
1420 /*
1421  * Initialize index-access-method support data for an index relation
1422  */
1423 void
1425 {
1426  HeapTuple tuple;
1427  Form_pg_am aform;
1428  Datum indcollDatum;
1429  Datum indclassDatum;
1430  Datum indoptionDatum;
1431  bool isnull;
1432  oidvector *indcoll;
1433  oidvector *indclass;
1434  int2vector *indoption;
1435  MemoryContext indexcxt;
1436  MemoryContext oldcontext;
1437  int indnatts;
1438  int indnkeyatts;
1439  uint16 amsupport;
1440 
1441  /*
1442  * Make a copy of the pg_index entry for the index. Since pg_index
1443  * contains variable-length and possibly-null fields, we have to do this
1444  * honestly rather than just treating it as a Form_pg_index struct.
1445  */
1446  tuple = SearchSysCache1(INDEXRELID,
1447  ObjectIdGetDatum(RelationGetRelid(relation)));
1448  if (!HeapTupleIsValid(tuple))
1449  elog(ERROR, "cache lookup failed for index %u",
1450  RelationGetRelid(relation));
1452  relation->rd_indextuple = heap_copytuple(tuple);
1453  relation->rd_index = (Form_pg_index) GETSTRUCT(relation->rd_indextuple);
1454  MemoryContextSwitchTo(oldcontext);
1455  ReleaseSysCache(tuple);
1456 
1457  /*
1458  * Look up the index's access method, save the OID of its handler function
1459  */
1460  Assert(relation->rd_rel->relam != InvalidOid);
1461  tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(relation->rd_rel->relam));
1462  if (!HeapTupleIsValid(tuple))
1463  elog(ERROR, "cache lookup failed for access method %u",
1464  relation->rd_rel->relam);
1465  aform = (Form_pg_am) GETSTRUCT(tuple);
1466  relation->rd_amhandler = aform->amhandler;
1467  ReleaseSysCache(tuple);
1468 
1469  indnatts = RelationGetNumberOfAttributes(relation);
1470  if (indnatts != IndexRelationGetNumberOfAttributes(relation))
1471  elog(ERROR, "relnatts disagrees with indnatts for index %u",
1472  RelationGetRelid(relation));
1473  indnkeyatts = IndexRelationGetNumberOfKeyAttributes(relation);
1474 
1475  /*
1476  * Make the private context to hold index access info. The reason we need
1477  * a context, and not just a couple of pallocs, is so that we won't leak
1478  * any subsidiary info attached to fmgr lookup records.
1479  */
1481  "index info",
1483  relation->rd_indexcxt = indexcxt;
1485  RelationGetRelationName(relation));
1486 
1487  /*
1488  * Now we can fetch the index AM's API struct
1489  */
1490  InitIndexAmRoutine(relation);
1491 
1492  /*
1493  * Allocate arrays to hold data. Opclasses are not used for included
1494  * columns, so allocate them for indnkeyatts only.
1495  */
1496  relation->rd_opfamily = (Oid *)
1497  MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid));
1498  relation->rd_opcintype = (Oid *)
1499  MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid));
1500 
1501  amsupport = relation->rd_indam->amsupport;
1502  if (amsupport > 0)
1503  {
1504  int nsupport = indnatts * amsupport;
1505 
1506  relation->rd_support = (RegProcedure *)
1507  MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
1508  relation->rd_supportinfo = (FmgrInfo *)
1509  MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
1510  }
1511  else
1512  {
1513  relation->rd_support = NULL;
1514  relation->rd_supportinfo = NULL;
1515  }
1516 
1517  relation->rd_indcollation = (Oid *)
1518  MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid));
1519 
1520  relation->rd_indoption = (int16 *)
1521  MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(int16));
1522 
1523  /*
1524  * indcollation cannot be referenced directly through the C struct,
1525  * because it comes after the variable-width indkey field. Must extract
1526  * the datum the hard way...
1527  */
1528  indcollDatum = fastgetattr(relation->rd_indextuple,
1529  Anum_pg_index_indcollation,
1531  &isnull);
1532  Assert(!isnull);
1533  indcoll = (oidvector *) DatumGetPointer(indcollDatum);
1534  memcpy(relation->rd_indcollation, indcoll->values, indnkeyatts * sizeof(Oid));
1535 
1536  /*
1537  * indclass cannot be referenced directly through the C struct, because it
1538  * comes after the variable-width indkey field. Must extract the datum
1539  * the hard way...
1540  */
1541  indclassDatum = fastgetattr(relation->rd_indextuple,
1542  Anum_pg_index_indclass,
1544  &isnull);
1545  Assert(!isnull);
1546  indclass = (oidvector *) DatumGetPointer(indclassDatum);
1547 
1548  /*
1549  * Fill the support procedure OID array, as well as the info about
1550  * opfamilies and opclass input types. (aminfo and supportinfo are left
1551  * as zeroes, and are filled on-the-fly when used)
1552  */
1553  IndexSupportInitialize(indclass, relation->rd_support,
1554  relation->rd_opfamily, relation->rd_opcintype,
1555  amsupport, indnkeyatts);
1556 
1557  /*
1558  * Similarly extract indoption and copy it to the cache entry
1559  */
1560  indoptionDatum = fastgetattr(relation->rd_indextuple,
1561  Anum_pg_index_indoption,
1563  &isnull);
1564  Assert(!isnull);
1565  indoption = (int2vector *) DatumGetPointer(indoptionDatum);
1566  memcpy(relation->rd_indoption, indoption->values, indnkeyatts * sizeof(int16));
1567 
1568  (void) RelationGetIndexAttOptions(relation, false);
1569 
1570  /*
1571  * expressions, predicate, exclusion caches will be filled later
1572  */
1573  relation->rd_indexprs = NIL;
1574  relation->rd_indpred = NIL;
1575  relation->rd_exclops = NULL;
1576  relation->rd_exclprocs = NULL;
1577  relation->rd_exclstrats = NULL;
1578  relation->rd_amcache = NULL;
1579 }
1580 
1581 /*
1582  * IndexSupportInitialize
1583  * Initializes an index's cached opclass information,
1584  * given the index's pg_index.indclass entry.
1585  *
1586  * Data is returned into *indexSupport, *opFamily, and *opcInType,
1587  * which are arrays allocated by the caller.
1588  *
1589  * The caller also passes maxSupportNumber and maxAttributeNumber, since these
1590  * indicate the size of the arrays it has allocated --- but in practice these
1591  * numbers must always match those obtainable from the system catalog entries
1592  * for the index and access method.
1593  */
1594 static void
1596  RegProcedure *indexSupport,
1597  Oid *opFamily,
1598  Oid *opcInType,
1599  StrategyNumber maxSupportNumber,
1600  AttrNumber maxAttributeNumber)
1601 {
1602  int attIndex;
1603 
1604  for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
1605  {
1606  OpClassCacheEnt *opcentry;
1607 
1608  if (!OidIsValid(indclass->values[attIndex]))
1609  elog(ERROR, "bogus pg_index tuple");
1610 
1611  /* look up the info for this opclass, using a cache */
1612  opcentry = LookupOpclassInfo(indclass->values[attIndex],
1613  maxSupportNumber);
1614 
1615  /* copy cached data into relcache entry */
1616  opFamily[attIndex] = opcentry->opcfamily;
1617  opcInType[attIndex] = opcentry->opcintype;
1618  if (maxSupportNumber > 0)
1619  memcpy(&indexSupport[attIndex * maxSupportNumber],
1620  opcentry->supportProcs,
1621  maxSupportNumber * sizeof(RegProcedure));
1622  }
1623 }
1624 
1625 /*
1626  * LookupOpclassInfo
1627  *
1628  * This routine maintains a per-opclass cache of the information needed
1629  * by IndexSupportInitialize(). This is more efficient than relying on
1630  * the catalog cache, because we can load all the info about a particular
1631  * opclass in a single indexscan of pg_amproc.
1632  *
1633  * The information from pg_am about expected range of support function
1634  * numbers is passed in, rather than being looked up, mainly because the
1635  * caller will have it already.
1636  *
1637  * Note there is no provision for flushing the cache. This is OK at the
1638  * moment because there is no way to ALTER any interesting properties of an
1639  * existing opclass --- all you can do is drop it, which will result in
1640  * a useless but harmless dead entry in the cache. To support altering
1641  * opclass membership (not the same as opfamily membership!), we'd need to
1642  * be able to flush this cache as well as the contents of relcache entries
1643  * for indexes.
1644  */
1645 static OpClassCacheEnt *
1646 LookupOpclassInfo(Oid operatorClassOid,
1647  StrategyNumber numSupport)
1648 {
1649  OpClassCacheEnt *opcentry;
1650  bool found;
1651  Relation rel;
1652  SysScanDesc scan;
1653  ScanKeyData skey[3];
1654  HeapTuple htup;
1655  bool indexOK;
1656 
1657  if (OpClassCache == NULL)
1658  {
1659  /* First time through: initialize the opclass cache */
1660  HASHCTL ctl;
1661 
1662  /* Also make sure CacheMemoryContext exists */
1663  if (!CacheMemoryContext)
1665 
1666  ctl.keysize = sizeof(Oid);
1667  ctl.entrysize = sizeof(OpClassCacheEnt);
1668  OpClassCache = hash_create("Operator class cache", 64,
1669  &ctl, HASH_ELEM | HASH_BLOBS);
1670  }
1671 
1672  opcentry = (OpClassCacheEnt *) hash_search(OpClassCache,
1673  &operatorClassOid,
1674  HASH_ENTER, &found);
1675 
1676  if (!found)
1677  {
1678  /* Initialize new entry */
1679  opcentry->valid = false; /* until known OK */
1680  opcentry->numSupport = numSupport;
1681  opcentry->supportProcs = NULL; /* filled below */
1682  }
1683  else
1684  {
1685  Assert(numSupport == opcentry->numSupport);
1686  }
1687 
1688  /*
1689  * When aggressively testing cache-flush hazards, we disable the operator
1690  * class cache and force reloading of the info on each call. This models
1691  * no real-world behavior, since the cache entries are never invalidated
1692  * otherwise. However it can be helpful for detecting bugs in the cache
1693  * loading logic itself, such as reliance on a non-nailed index. Given
1694  * the limited use-case and the fact that this adds a great deal of
1695  * expense, we enable it only for high values of debug_discard_caches.
1696  */
1697 #ifdef DISCARD_CACHES_ENABLED
1698  if (debug_discard_caches > 2)
1699  opcentry->valid = false;
1700 #endif
1701 
1702  if (opcentry->valid)
1703  return opcentry;
1704 
1705  /*
1706  * Need to fill in new entry. First allocate space, unless we already did
1707  * so in some previous attempt.
1708  */
1709  if (opcentry->supportProcs == NULL && numSupport > 0)
1710  opcentry->supportProcs = (RegProcedure *)
1712  numSupport * sizeof(RegProcedure));
1713 
1714  /*
1715  * To avoid infinite recursion during startup, force heap scans if we're
1716  * looking up info for the opclasses used by the indexes we would like to
1717  * reference here.
1718  */
1719  indexOK = criticalRelcachesBuilt ||
1720  (operatorClassOid != OID_BTREE_OPS_OID &&
1721  operatorClassOid != INT2_BTREE_OPS_OID);
1722 
1723  /*
1724  * We have to fetch the pg_opclass row to determine its opfamily and
1725  * opcintype, which are needed to look up related operators and functions.
1726  * It'd be convenient to use the syscache here, but that probably doesn't
1727  * work while bootstrapping.
1728  */
1729  ScanKeyInit(&skey[0],
1730  Anum_pg_opclass_oid,
1731  BTEqualStrategyNumber, F_OIDEQ,
1732  ObjectIdGetDatum(operatorClassOid));
1733  rel = table_open(OperatorClassRelationId, AccessShareLock);
1734  scan = systable_beginscan(rel, OpclassOidIndexId, indexOK,
1735  NULL, 1, skey);
1736 
1737  if (HeapTupleIsValid(htup = systable_getnext(scan)))
1738  {
1739  Form_pg_opclass opclassform = (Form_pg_opclass) GETSTRUCT(htup);
1740 
1741  opcentry->opcfamily = opclassform->opcfamily;
1742  opcentry->opcintype = opclassform->opcintype;
1743  }
1744  else
1745  elog(ERROR, "could not find tuple for opclass %u", operatorClassOid);
1746 
1747  systable_endscan(scan);
1749 
1750  /*
1751  * Scan pg_amproc to obtain support procs for the opclass. We only fetch
1752  * the default ones (those with lefttype = righttype = opcintype).
1753  */
1754  if (numSupport > 0)
1755  {
1756  ScanKeyInit(&skey[0],
1757  Anum_pg_amproc_amprocfamily,
1758  BTEqualStrategyNumber, F_OIDEQ,
1759  ObjectIdGetDatum(opcentry->opcfamily));
1760  ScanKeyInit(&skey[1],
1761  Anum_pg_amproc_amproclefttype,
1762  BTEqualStrategyNumber, F_OIDEQ,
1763  ObjectIdGetDatum(opcentry->opcintype));
1764  ScanKeyInit(&skey[2],
1765  Anum_pg_amproc_amprocrighttype,
1766  BTEqualStrategyNumber, F_OIDEQ,
1767  ObjectIdGetDatum(opcentry->opcintype));
1768  rel = table_open(AccessMethodProcedureRelationId, AccessShareLock);
1769  scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK,
1770  NULL, 3, skey);
1771 
1772  while (HeapTupleIsValid(htup = systable_getnext(scan)))
1773  {
1774  Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
1775 
1776  if (amprocform->amprocnum <= 0 ||
1777  (StrategyNumber) amprocform->amprocnum > numSupport)
1778  elog(ERROR, "invalid amproc number %d for opclass %u",
1779  amprocform->amprocnum, operatorClassOid);
1780 
1781  opcentry->supportProcs[amprocform->amprocnum - 1] =
1782  amprocform->amproc;
1783  }
1784 
1785  systable_endscan(scan);
1787  }
1788 
1789  opcentry->valid = true;
1790  return opcentry;
1791 }
1792 
1793 /*
1794  * Fill in the TableAmRoutine for a relation
1795  *
1796  * relation's rd_amhandler must be valid already.
1797  */
1798 static void
1800 {
1801  relation->rd_tableam = GetTableAmRoutine(relation->rd_amhandler);
1802 }
1803 
1804 /*
1805  * Initialize table access method support for a table like relation
1806  */
1807 void
1809 {
1810  HeapTuple tuple;
1811  Form_pg_am aform;
1812 
1813  if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
1814  {
1815  /*
1816  * Sequences are currently accessed like heap tables, but it doesn't
1817  * seem prudent to show that in the catalog. So just overwrite it
1818  * here.
1819  */
1820  Assert(relation->rd_rel->relam == InvalidOid);
1821  relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER;
1822  }
1823  else if (IsCatalogRelation(relation))
1824  {
1825  /*
1826  * Avoid doing a syscache lookup for catalog tables.
1827  */
1828  Assert(relation->rd_rel->relam == HEAP_TABLE_AM_OID);
1829  relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER;
1830  }
1831  else
1832  {
1833  /*
1834  * Look up the table access method, save the OID of its handler
1835  * function.
1836  */
1837  Assert(relation->rd_rel->relam != InvalidOid);
1838  tuple = SearchSysCache1(AMOID,
1839  ObjectIdGetDatum(relation->rd_rel->relam));
1840  if (!HeapTupleIsValid(tuple))
1841  elog(ERROR, "cache lookup failed for access method %u",
1842  relation->rd_rel->relam);
1843  aform = (Form_pg_am) GETSTRUCT(tuple);
1844  relation->rd_amhandler = aform->amhandler;
1845  ReleaseSysCache(tuple);
1846  }
1847 
1848  /*
1849  * Now we can fetch the table AM's API struct
1850  */
1851  InitTableAmRoutine(relation);
1852 }
1853 
1854 /*
1855  * formrdesc
1856  *
1857  * This is a special cut-down version of RelationBuildDesc(),
1858  * used while initializing the relcache.
1859  * The relation descriptor is built just from the supplied parameters,
1860  * without actually looking at any system table entries. We cheat
1861  * quite a lot since we only need to work for a few basic system
1862  * catalogs.
1863  *
1864  * The catalogs this is used for can't have constraints (except attnotnull),
1865  * default values, rules, or triggers, since we don't cope with any of that.
1866  * (Well, actually, this only matters for properties that need to be valid
1867  * during bootstrap or before RelationCacheInitializePhase3 runs, and none of
1868  * these properties matter then...)
1869  *
1870  * NOTE: we assume we are already switched into CacheMemoryContext.
1871  */
1872 static void
1873 formrdesc(const char *relationName, Oid relationReltype,
1874  bool isshared,
1875  int natts, const FormData_pg_attribute *attrs)
1876 {
1877  Relation relation;
1878  int i;
1879  bool has_not_null;
1880 
1881  /*
1882  * allocate new relation desc, clear all fields of reldesc
1883  */
1884  relation = (Relation) palloc0(sizeof(RelationData));
1885 
1886  /* make sure relation is marked as having no open file yet */
1887  relation->rd_smgr = NULL;
1888 
1889  /*
1890  * initialize reference count: 1 because it is nailed in cache
1891  */
1892  relation->rd_refcnt = 1;
1893 
1894  /*
1895  * all entries built with this routine are nailed-in-cache; none are for
1896  * new or temp relations.
1897  */
1898  relation->rd_isnailed = true;
1903  relation->rd_backend = INVALID_PROC_NUMBER;
1904  relation->rd_islocaltemp = false;
1905 
1906  /*
1907  * initialize relation tuple form
1908  *
1909  * The data we insert here is pretty incomplete/bogus, but it'll serve to
1910  * get us launched. RelationCacheInitializePhase3() will read the real
1911  * data from pg_class and replace what we've done here. Note in
1912  * particular that relowner is left as zero; this cues
1913  * RelationCacheInitializePhase3 that the real data isn't there yet.
1914  */
1916 
1917  namestrcpy(&relation->rd_rel->relname, relationName);
1918  relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
1919  relation->rd_rel->reltype = relationReltype;
1920 
1921  /*
1922  * It's important to distinguish between shared and non-shared relations,
1923  * even at bootstrap time, to make sure we know where they are stored.
1924  */
1925  relation->rd_rel->relisshared = isshared;
1926  if (isshared)
1927  relation->rd_rel->reltablespace = GLOBALTABLESPACE_OID;
1928 
1929  /* formrdesc is used only for permanent relations */
1930  relation->rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
1931 
1932  /* ... and they're always populated, too */
1933  relation->rd_rel->relispopulated = true;
1934 
1935  relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
1936  relation->rd_rel->relpages = 0;
1937  relation->rd_rel->reltuples = -1;
1938  relation->rd_rel->relallvisible = 0;
1939  relation->rd_rel->relkind = RELKIND_RELATION;
1940  relation->rd_rel->relnatts = (int16) natts;
1941  relation->rd_rel->relam = HEAP_TABLE_AM_OID;
1942 
1943  /*
1944  * initialize attribute tuple form
1945  *
1946  * Unlike the case with the relation tuple, this data had better be right
1947  * because it will never be replaced. The data comes from
1948  * src/include/catalog/ headers via genbki.pl.
1949  */
1950  relation->rd_att = CreateTemplateTupleDesc(natts);
1951  relation->rd_att->tdrefcount = 1; /* mark as refcounted */
1952 
1953  relation->rd_att->tdtypeid = relationReltype;
1954  relation->rd_att->tdtypmod = -1; /* just to be sure */
1955 
1956  /*
1957  * initialize tuple desc info
1958  */
1959  has_not_null = false;
1960  for (i = 0; i < natts; i++)
1961  {
1962  memcpy(TupleDescAttr(relation->rd_att, i),
1963  &attrs[i],
1965  has_not_null |= attrs[i].attnotnull;
1966  /* make sure attcacheoff is valid */
1967  TupleDescAttr(relation->rd_att, i)->attcacheoff = -1;
1968  }
1969 
1970  /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
1971  TupleDescAttr(relation->rd_att, 0)->attcacheoff = 0;
1972 
1973  /* mark not-null status */
1974  if (has_not_null)
1975  {
1976  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
1977 
1978  constr->has_not_null = true;
1979  relation->rd_att->constr = constr;
1980  }
1981 
1982  /*
1983  * initialize relation id from info in att array (my, this is ugly)
1984  */
1985  RelationGetRelid(relation) = TupleDescAttr(relation->rd_att, 0)->attrelid;
1986 
1987  /*
1988  * All relations made with formrdesc are mapped. This is necessarily so
1989  * because there is no other way to know what filenumber they currently
1990  * have. In bootstrap mode, add them to the initial relation mapper data,
1991  * specifying that the initial filenumber is the same as the OID.
1992  */
1993  relation->rd_rel->relfilenode = InvalidRelFileNumber;
1996  RelationGetRelid(relation),
1997  isshared, true);
1998 
1999  /*
2000  * initialize the relation lock manager information
2001  */
2002  RelationInitLockInfo(relation); /* see lmgr.c */
2003 
2004  /*
2005  * initialize physical addressing information for the relation
2006  */
2007  RelationInitPhysicalAddr(relation);
2008 
2009  /*
2010  * initialize the table am handler
2011  */
2012  relation->rd_rel->relam = HEAP_TABLE_AM_OID;
2013  relation->rd_tableam = GetHeapamTableAmRoutine();
2014 
2015  /*
2016  * initialize the rel-has-index flag, using hardwired knowledge
2017  */
2019  {
2020  /* In bootstrap mode, we have no indexes */
2021  relation->rd_rel->relhasindex = false;
2022  }
2023  else
2024  {
2025  /* Otherwise, all the rels formrdesc is used for have indexes */
2026  relation->rd_rel->relhasindex = true;
2027  }
2028 
2029  /*
2030  * add new reldesc to relcache
2031  */
2032  RelationCacheInsert(relation, false);
2033 
2034  /* It's fully valid */
2035  relation->rd_isvalid = true;
2036 }
2037 
2038 
2039 /* ----------------------------------------------------------------
2040  * Relation Descriptor Lookup Interface
2041  * ----------------------------------------------------------------
2042  */
2043 
2044 /*
2045  * RelationIdGetRelation
2046  *
2047  * Lookup a reldesc by OID; make one if not already in cache.
2048  *
2049  * Returns NULL if no pg_class row could be found for the given relid
2050  * (suggesting we are trying to access a just-deleted relation).
2051  * Any other error is reported via elog.
2052  *
2053  * NB: caller should already have at least AccessShareLock on the
2054  * relation ID, else there are nasty race conditions.
2055  *
2056  * NB: relation ref count is incremented, or set to 1 if new entry.
2057  * Caller should eventually decrement count. (Usually,
2058  * that happens by calling RelationClose().)
2059  */
2060 Relation
2062 {
2063  Relation rd;
2064 
2065  /* Make sure we're in an xact, even if this ends up being a cache hit */
2067 
2068  /*
2069  * first try to find reldesc in the cache
2070  */
2071  RelationIdCacheLookup(relationId, rd);
2072 
2073  if (RelationIsValid(rd))
2074  {
2075  /* return NULL for dropped relations */
2077  {
2078  Assert(!rd->rd_isvalid);
2079  return NULL;
2080  }
2081 
2083  /* revalidate cache entry if necessary */
2084  if (!rd->rd_isvalid)
2085  {
2086  /*
2087  * Indexes only have a limited number of possible schema changes,
2088  * and we don't want to use the full-blown procedure because it's
2089  * a headache for indexes that reload itself depends on.
2090  */
2091  if (rd->rd_rel->relkind == RELKIND_INDEX ||
2092  rd->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
2094  else
2095  RelationClearRelation(rd, true);
2096 
2097  /*
2098  * Normally entries need to be valid here, but before the relcache
2099  * has been initialized, not enough infrastructure exists to
2100  * perform pg_class lookups. The structure of such entries doesn't
2101  * change, but we still want to update the rd_rel entry. So
2102  * rd_isvalid = false is left in place for a later lookup.
2103  */
2104  Assert(rd->rd_isvalid ||
2106  }
2107  return rd;
2108  }
2109 
2110  /*
2111  * no reldesc in the cache, so have RelationBuildDesc() build one and add
2112  * it.
2113  */
2114  rd = RelationBuildDesc(relationId, true);
2115  if (RelationIsValid(rd))
2117  return rd;
2118 }
2119 
2120 /* ----------------------------------------------------------------
2121  * cache invalidation support routines
2122  * ----------------------------------------------------------------
2123  */
2124 
2125 /* ResourceOwner callbacks to track relcache references */
2126 static void ResOwnerReleaseRelation(Datum res);
2127 static char *ResOwnerPrintRelCache(Datum res);
2128 
2130 {
2131  .name = "relcache reference",
2132  .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
2133  .release_priority = RELEASE_PRIO_RELCACHE_REFS,
2134  .ReleaseResource = ResOwnerReleaseRelation,
2135  .DebugPrint = ResOwnerPrintRelCache
2136 };
2137 
2138 /* Convenience wrappers over ResourceOwnerRemember/Forget */
2139 static inline void
2141 {
2143 }
2144 static inline void
2146 {
2148 }
2149 
2150 /*
2151  * RelationIncrementReferenceCount
2152  * Increments relation reference count.
2153  *
2154  * Note: bootstrap mode has its own weird ideas about relation refcount
2155  * behavior; we ought to fix it someday, but for now, just disable
2156  * reference count ownership tracking in bootstrap mode.
2157  */
2158 void
2160 {
2162  rel->rd_refcnt += 1;
2165 }
2166 
2167 /*
2168  * RelationDecrementReferenceCount
2169  * Decrements relation reference count.
2170  */
2171 void
2173 {
2174  Assert(rel->rd_refcnt > 0);
2175  rel->rd_refcnt -= 1;
2178 }
2179 
2180 /*
2181  * RelationClose - close an open relation
2182  *
2183  * Actually, we just decrement the refcount.
2184  *
2185  * NOTE: if compiled with -DRELCACHE_FORCE_RELEASE then relcache entries
2186  * will be freed as soon as their refcount goes to zero. In combination
2187  * with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
2188  * to catch references to already-released relcache entries. It slows
2189  * things down quite a bit, however.
2190  */
2191 void
2193 {
2194  /* Note: no locking manipulations needed */
2196 
2197  RelationCloseCleanup(relation);
2198 }
2199 
2200 static void
2202 {
2203  /*
2204  * If the relation is no longer open in this session, we can clean up any
2205  * stale partition descriptors it has. This is unlikely, so check to see
2206  * if there are child contexts before expending a call to mcxt.c.
2207  */
2208  if (RelationHasReferenceCountZero(relation))
2209  {
2210  if (relation->rd_pdcxt != NULL &&
2211  relation->rd_pdcxt->firstchild != NULL)
2213 
2214  if (relation->rd_pddcxt != NULL &&
2215  relation->rd_pddcxt->firstchild != NULL)
2217  }
2218 
2219 #ifdef RELCACHE_FORCE_RELEASE
2220  if (RelationHasReferenceCountZero(relation) &&
2221  relation->rd_createSubid == InvalidSubTransactionId &&
2223  RelationClearRelation(relation, false);
2224 #endif
2225 }
2226 
2227 /*
2228  * RelationReloadIndexInfo - reload minimal information for an open index
2229  *
2230  * This function is used only for indexes. A relcache inval on an index
2231  * can mean that its pg_class or pg_index row changed. There are only
2232  * very limited changes that are allowed to an existing index's schema,
2233  * so we can update the relcache entry without a complete rebuild; which
2234  * is fortunate because we can't rebuild an index entry that is "nailed"
2235  * and/or in active use. We support full replacement of the pg_class row,
2236  * as well as updates of a few simple fields of the pg_index row.
2237  *
2238  * We can't necessarily reread the catalog rows right away; we might be
2239  * in a failed transaction when we receive the SI notification. If so,
2240  * RelationClearRelation just marks the entry as invalid by setting
2241  * rd_isvalid to false. This routine is called to fix the entry when it
2242  * is next needed.
2243  *
2244  * We assume that at the time we are called, we have at least AccessShareLock
2245  * on the target index. (Note: in the calls from RelationClearRelation,
2246  * this is legitimate because we know the rel has positive refcount.)
2247  *
2248  * If the target index is an index on pg_class or pg_index, we'd better have
2249  * previously gotten at least AccessShareLock on its underlying catalog,
2250  * else we are at risk of deadlock against someone trying to exclusive-lock
2251  * the heap and index in that order. This is ensured in current usage by
2252  * only applying this to indexes being opened or having positive refcount.
2253  */
2254 static void
2256 {
2257  bool indexOK;
2258  HeapTuple pg_class_tuple;
2259  Form_pg_class relp;
2260 
2261  /* Should be called only for invalidated, live indexes */
2262  Assert((relation->rd_rel->relkind == RELKIND_INDEX ||
2263  relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
2264  !relation->rd_isvalid &&
2266 
2267  /* Ensure it's closed at smgr level */
2268  RelationCloseSmgr(relation);
2269 
2270  /* Must free any AM cached data upon relcache flush */
2271  if (relation->rd_amcache)
2272  pfree(relation->rd_amcache);
2273  relation->rd_amcache = NULL;
2274 
2275  /*
2276  * If it's a shared index, we might be called before backend startup has
2277  * finished selecting a database, in which case we have no way to read
2278  * pg_class yet. However, a shared index can never have any significant
2279  * schema updates, so it's okay to ignore the invalidation signal. Just
2280  * mark it valid and return without doing anything more.
2281  */
2282  if (relation->rd_rel->relisshared && !criticalRelcachesBuilt)
2283  {
2284  relation->rd_isvalid = true;
2285  return;
2286  }
2287 
2288  /*
2289  * Read the pg_class row
2290  *
2291  * Don't try to use an indexscan of pg_class_oid_index to reload the info
2292  * for pg_class_oid_index ...
2293  */
2294  indexOK = (RelationGetRelid(relation) != ClassOidIndexId);
2295  pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), indexOK, false);
2296  if (!HeapTupleIsValid(pg_class_tuple))
2297  elog(ERROR, "could not find pg_class tuple for index %u",
2298  RelationGetRelid(relation));
2299  relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
2300  memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
2301  /* Reload reloptions in case they changed */
2302  if (relation->rd_options)
2303  pfree(relation->rd_options);
2304  RelationParseRelOptions(relation, pg_class_tuple);
2305  /* done with pg_class tuple */
2306  heap_freetuple(pg_class_tuple);
2307  /* We must recalculate physical address in case it changed */
2308  RelationInitPhysicalAddr(relation);
2309 
2310  /*
2311  * For a non-system index, there are fields of the pg_index row that are
2312  * allowed to change, so re-read that row and update the relcache entry.
2313  * Most of the info derived from pg_index (such as support function lookup
2314  * info) cannot change, and indeed the whole point of this routine is to
2315  * update the relcache entry without clobbering that data; so wholesale
2316  * replacement is not appropriate.
2317  */
2318  if (!IsSystemRelation(relation))
2319  {
2320  HeapTuple tuple;
2322 
2323  tuple = SearchSysCache1(INDEXRELID,
2324  ObjectIdGetDatum(RelationGetRelid(relation)));
2325  if (!HeapTupleIsValid(tuple))
2326  elog(ERROR, "cache lookup failed for index %u",
2327  RelationGetRelid(relation));
2328  index = (Form_pg_index) GETSTRUCT(tuple);
2329 
2330  /*
2331  * Basically, let's just copy all the bool fields. There are one or
2332  * two of these that can't actually change in the current code, but
2333  * it's not worth it to track exactly which ones they are. None of
2334  * the array fields are allowed to change, though.
2335  */
2336  relation->rd_index->indisunique = index->indisunique;
2337  relation->rd_index->indnullsnotdistinct = index->indnullsnotdistinct;
2338  relation->rd_index->indisprimary = index->indisprimary;
2339  relation->rd_index->indisexclusion = index->indisexclusion;
2340  relation->rd_index->indimmediate = index->indimmediate;
2341  relation->rd_index->indisclustered = index->indisclustered;
2342  relation->rd_index->indisvalid = index->indisvalid;
2343  relation->rd_index->indcheckxmin = index->indcheckxmin;
2344  relation->rd_index->indisready = index->indisready;
2345  relation->rd_index->indislive = index->indislive;
2346  relation->rd_index->indisreplident = index->indisreplident;
2347 
2348  /* Copy xmin too, as that is needed to make sense of indcheckxmin */
2350  HeapTupleHeaderGetXmin(tuple->t_data));
2351 
2352  ReleaseSysCache(tuple);
2353  }
2354 
2355  /* Okay, now it's valid again */
2356  relation->rd_isvalid = true;
2357 }
2358 
2359 /*
2360  * RelationReloadNailed - reload minimal information for nailed relations.
2361  *
2362  * The structure of a nailed relation can never change (which is good, because
2363  * we rely on knowing their structure to be able to read catalog content). But
2364  * some parts, e.g. pg_class.relfrozenxid, are still important to have
2365  * accurate content for. Therefore those need to be reloaded after the arrival
2366  * of invalidations.
2367  */
2368 static void
2370 {
2371  Assert(relation->rd_isnailed);
2372 
2373  /*
2374  * Redo RelationInitPhysicalAddr in case it is a mapped relation whose
2375  * mapping changed.
2376  */
2377  RelationInitPhysicalAddr(relation);
2378 
2379  /* flag as needing to be revalidated */
2380  relation->rd_isvalid = false;
2381 
2382  /*
2383  * Can only reread catalog contents if in a transaction. If the relation
2384  * is currently open (not counting the nailed refcount), do so
2385  * immediately. Otherwise we've already marked the entry as possibly
2386  * invalid, and it'll be fixed when next opened.
2387  */
2388  if (!IsTransactionState() || relation->rd_refcnt <= 1)
2389  return;
2390 
2391  if (relation->rd_rel->relkind == RELKIND_INDEX)
2392  {
2393  /*
2394  * If it's a nailed-but-not-mapped index, then we need to re-read the
2395  * pg_class row to see if its relfilenumber changed.
2396  */
2397  RelationReloadIndexInfo(relation);
2398  }
2399  else
2400  {
2401  /*
2402  * Reload a non-index entry. We can't easily do so if relcaches
2403  * aren't yet built, but that's fine because at that stage the
2404  * attributes that need to be current (like relfrozenxid) aren't yet
2405  * accessed. To ensure the entry will later be revalidated, we leave
2406  * it in invalid state, but allow use (cf. RelationIdGetRelation()).
2407  */
2409  {
2410  HeapTuple pg_class_tuple;
2411  Form_pg_class relp;
2412 
2413  /*
2414  * NB: Mark the entry as valid before starting to scan, to avoid
2415  * self-recursion when re-building pg_class.
2416  */
2417  relation->rd_isvalid = true;
2418 
2419  pg_class_tuple = ScanPgRelation(RelationGetRelid(relation),
2420  true, false);
2421  relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
2422  memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
2423  heap_freetuple(pg_class_tuple);
2424 
2425  /*
2426  * Again mark as valid, to protect against concurrently arriving
2427  * invalidations.
2428  */
2429  relation->rd_isvalid = true;
2430  }
2431  }
2432 }
2433 
2434 /*
2435  * RelationDestroyRelation
2436  *
2437  * Physically delete a relation cache entry and all subsidiary data.
2438  * Caller must already have unhooked the entry from the hash table.
2439  */
2440 static void
2441 RelationDestroyRelation(Relation relation, bool remember_tupdesc)
2442 {
2444 
2445  /*
2446  * Make sure smgr and lower levels close the relation's files, if they
2447  * weren't closed already. (This was probably done by caller, but let's
2448  * just be real sure.)
2449  */
2450  RelationCloseSmgr(relation);
2451 
2452  /* break mutual link with stats entry */
2453  pgstat_unlink_relation(relation);
2454 
2455  /*
2456  * Free all the subsidiary data structures of the relcache entry, then the
2457  * entry itself.
2458  */
2459  if (relation->rd_rel)
2460  pfree(relation->rd_rel);
2461  /* can't use DecrTupleDescRefCount here */
2462  Assert(relation->rd_att->tdrefcount > 0);
2463  if (--relation->rd_att->tdrefcount == 0)
2464  {
2465  /*
2466  * If we Rebuilt a relcache entry during a transaction then its
2467  * possible we did that because the TupDesc changed as the result of
2468  * an ALTER TABLE that ran at less than AccessExclusiveLock. It's
2469  * possible someone copied that TupDesc, in which case the copy would
2470  * point to free'd memory. So if we rebuild an entry we keep the
2471  * TupDesc around until end of transaction, to be safe.
2472  */
2473  if (remember_tupdesc)
2475  else
2476  FreeTupleDesc(relation->rd_att);
2477  }
2478  FreeTriggerDesc(relation->trigdesc);
2479  list_free_deep(relation->rd_fkeylist);
2480  list_free(relation->rd_indexlist);
2481  list_free(relation->rd_statlist);
2482  bms_free(relation->rd_keyattr);
2483  bms_free(relation->rd_pkattr);
2484  bms_free(relation->rd_idattr);
2485  bms_free(relation->rd_hotblockingattr);
2486  bms_free(relation->rd_summarizedattr);
2487  if (relation->rd_pubdesc)
2488  pfree(relation->rd_pubdesc);
2489  if (relation->rd_options)
2490  pfree(relation->rd_options);
2491  if (relation->rd_indextuple)
2492  pfree(relation->rd_indextuple);
2493  if (relation->rd_amcache)
2494  pfree(relation->rd_amcache);
2495  if (relation->rd_fdwroutine)
2496  pfree(relation->rd_fdwroutine);
2497  if (relation->rd_indexcxt)
2498  MemoryContextDelete(relation->rd_indexcxt);
2499  if (relation->rd_rulescxt)
2500  MemoryContextDelete(relation->rd_rulescxt);
2501  if (relation->rd_rsdesc)
2502  MemoryContextDelete(relation->rd_rsdesc->rscxt);
2503  if (relation->rd_partkeycxt)
2505  if (relation->rd_pdcxt)
2506  MemoryContextDelete(relation->rd_pdcxt);
2507  if (relation->rd_pddcxt)
2508  MemoryContextDelete(relation->rd_pddcxt);
2509  if (relation->rd_partcheckcxt)
2511  pfree(relation);
2512 }
2513 
2514 /*
2515  * RelationInvalidateRelation - mark a relation cache entry as invalid
2516  *
2517  * An entry that's marked as invalid will be reloaded on next access.
2518  */
2519 static void
2521 {
2522  /*
2523  * Make sure smgr and lower levels close the relation's files, if they
2524  * weren't closed already. If the relation is not getting deleted, the
2525  * next smgr access should reopen the files automatically. This ensures
2526  * that the low-level file access state is updated after, say, a vacuum
2527  * truncation.
2528  */
2529  RelationCloseSmgr(relation);
2530 
2531  /* Free AM cached data, if any */
2532  if (relation->rd_amcache)
2533  pfree(relation->rd_amcache);
2534  relation->rd_amcache = NULL;
2535 
2536  relation->rd_isvalid = false;
2537 }
2538 
2539 /*
2540  * RelationClearRelation
2541  *
2542  * Physically blow away a relation cache entry, or reset it and rebuild
2543  * it from scratch (that is, from catalog entries). The latter path is
2544  * used when we are notified of a change to an open relation (one with
2545  * refcount > 0).
2546  *
2547  * NB: when rebuilding, we'd better hold some lock on the relation,
2548  * else the catalog data we need to read could be changing under us.
2549  * Also, a rel to be rebuilt had better have refcnt > 0. This is because
2550  * a sinval reset could happen while we're accessing the catalogs, and
2551  * the rel would get blown away underneath us by RelationCacheInvalidate
2552  * if it has zero refcnt.
2553  *
2554  * The "rebuild" parameter is redundant in current usage because it has
2555  * to match the relation's refcnt status, but we keep it as a crosscheck
2556  * that we're doing what the caller expects.
2557  */
2558 static void
2559 RelationClearRelation(Relation relation, bool rebuild)
2560 {
2561  /*
2562  * As per notes above, a rel to be rebuilt MUST have refcnt > 0; while of
2563  * course it would be an equally bad idea to blow away one with nonzero
2564  * refcnt, since that would leave someone somewhere with a dangling
2565  * pointer. All callers are expected to have verified that this holds.
2566  */
2567  Assert(rebuild ?
2568  !RelationHasReferenceCountZero(relation) :
2569  RelationHasReferenceCountZero(relation));
2570 
2571  /*
2572  * Make sure smgr and lower levels close the relation's files, if they
2573  * weren't closed already. If the relation is not getting deleted, the
2574  * next smgr access should reopen the files automatically. This ensures
2575  * that the low-level file access state is updated after, say, a vacuum
2576  * truncation.
2577  */
2578  RelationCloseSmgr(relation);
2579 
2580  /* Free AM cached data, if any */
2581  if (relation->rd_amcache)
2582  pfree(relation->rd_amcache);
2583  relation->rd_amcache = NULL;
2584 
2585  /*
2586  * Treat nailed-in system relations separately, they always need to be
2587  * accessible, so we can't blow them away.
2588  */
2589  if (relation->rd_isnailed)
2590  {
2591  RelationReloadNailed(relation);
2592  return;
2593  }
2594 
2595  /* Mark it invalid until we've finished rebuild */
2596  relation->rd_isvalid = false;
2597 
2598  /* See RelationForgetRelation(). */
2599  if (relation->rd_droppedSubid != InvalidSubTransactionId)
2600  return;
2601 
2602  /*
2603  * Even non-system indexes should not be blown away if they are open and
2604  * have valid index support information. This avoids problems with active
2605  * use of the index support information. As with nailed indexes, we
2606  * re-read the pg_class row to handle possible physical relocation of the
2607  * index, and we check for pg_index updates too.
2608  */
2609  if ((relation->rd_rel->relkind == RELKIND_INDEX ||
2610  relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
2611  relation->rd_refcnt > 0 &&
2612  relation->rd_indexcxt != NULL)
2613  {
2614  if (IsTransactionState())
2615  RelationReloadIndexInfo(relation);
2616  return;
2617  }
2618 
2619  /*
2620  * If we're really done with the relcache entry, blow it away. But if
2621  * someone is still using it, reconstruct the whole deal without moving
2622  * the physical RelationData record (so that the someone's pointer is
2623  * still valid).
2624  */
2625  if (!rebuild)
2626  {
2627  /* Remove it from the hash table */
2628  RelationCacheDelete(relation);
2629 
2630  /* And release storage */
2631  RelationDestroyRelation(relation, false);
2632  }
2633  else if (!IsTransactionState())
2634  {
2635  /*
2636  * If we're not inside a valid transaction, we can't do any catalog
2637  * access so it's not possible to rebuild yet. Just exit, leaving
2638  * rd_isvalid = false so that the rebuild will occur when the entry is
2639  * next opened.
2640  *
2641  * Note: it's possible that we come here during subtransaction abort,
2642  * and the reason for wanting to rebuild is that the rel is open in
2643  * the outer transaction. In that case it might seem unsafe to not
2644  * rebuild immediately, since whatever code has the rel already open
2645  * will keep on using the relcache entry as-is. However, in such a
2646  * case the outer transaction should be holding a lock that's
2647  * sufficient to prevent any significant change in the rel's schema,
2648  * so the existing entry contents should be good enough for its
2649  * purposes; at worst we might be behind on statistics updates or the
2650  * like. (See also CheckTableNotInUse() and its callers.) These same
2651  * remarks also apply to the cases above where we exit without having
2652  * done RelationReloadIndexInfo() yet.
2653  */
2654  return;
2655  }
2656  else
2657  {
2658  /*
2659  * Our strategy for rebuilding an open relcache entry is to build a
2660  * new entry from scratch, swap its contents with the old entry, and
2661  * finally delete the new entry (along with any infrastructure swapped
2662  * over from the old entry). This is to avoid trouble in case an
2663  * error causes us to lose control partway through. The old entry
2664  * will still be marked !rd_isvalid, so we'll try to rebuild it again
2665  * on next access. Meanwhile it's not any less valid than it was
2666  * before, so any code that might expect to continue accessing it
2667  * isn't hurt by the rebuild failure. (Consider for example a
2668  * subtransaction that ALTERs a table and then gets canceled partway
2669  * through the cache entry rebuild. The outer transaction should
2670  * still see the not-modified cache entry as valid.) The worst
2671  * consequence of an error is leaking the necessarily-unreferenced new
2672  * entry, and this shouldn't happen often enough for that to be a big
2673  * problem.
2674  *
2675  * When rebuilding an open relcache entry, we must preserve ref count,
2676  * rd_*Subid, and rd_toastoid state. Also attempt to preserve the
2677  * pg_class entry (rd_rel), tupledesc, rewrite-rule, partition key,
2678  * and partition descriptor substructures in place, because various
2679  * places assume that these structures won't move while they are
2680  * working with an open relcache entry. (Note: the refcount
2681  * mechanism for tupledescs might someday allow us to remove this hack
2682  * for the tupledesc.)
2683  *
2684  * Note that this process does not touch CurrentResourceOwner; which
2685  * is good because whatever ref counts the entry may have do not
2686  * necessarily belong to that resource owner.
2687  */
2688  Relation newrel;
2689  Oid save_relid = RelationGetRelid(relation);
2690  bool keep_tupdesc;
2691  bool keep_rules;
2692  bool keep_policies;
2693  bool keep_partkey;
2694 
2695  /* Build temporary entry, but don't link it into hashtable */
2696  newrel = RelationBuildDesc(save_relid, false);
2697 
2698  /*
2699  * Between here and the end of the swap, don't add code that does or
2700  * reasonably could read system catalogs. That range must be free
2701  * from invalidation processing. See RelationBuildDesc() manipulation
2702  * of in_progress_list.
2703  */
2704 
2705  if (newrel == NULL)
2706  {
2707  /*
2708  * We can validly get here, if we're using a historic snapshot in
2709  * which a relation, accessed from outside logical decoding, is
2710  * still invisible. In that case it's fine to just mark the
2711  * relation as invalid and return - it'll fully get reloaded by
2712  * the cache reset at the end of logical decoding (or at the next
2713  * access). During normal processing we don't want to ignore this
2714  * case as it shouldn't happen there, as explained below.
2715  */
2716  if (HistoricSnapshotActive())
2717  return;
2718 
2719  /*
2720  * This shouldn't happen as dropping a relation is intended to be
2721  * impossible if still referenced (cf. CheckTableNotInUse()). But
2722  * if we get here anyway, we can't just delete the relcache entry,
2723  * as it possibly could get accessed later (as e.g. the error
2724  * might get trapped and handled via a subtransaction rollback).
2725  */
2726  elog(ERROR, "relation %u deleted while still in use", save_relid);
2727  }
2728 
2729  /*
2730  * If we were to, again, have cases of the relkind of a relcache entry
2731  * changing, we would need to ensure that pgstats does not get
2732  * confused.
2733  */
2734  Assert(relation->rd_rel->relkind == newrel->rd_rel->relkind);
2735 
2736  keep_tupdesc = equalTupleDescs(relation->rd_att, newrel->rd_att);
2737  keep_rules = equalRuleLocks(relation->rd_rules, newrel->rd_rules);
2738  keep_policies = equalRSDesc(relation->rd_rsdesc, newrel->rd_rsdesc);
2739  /* partkey is immutable once set up, so we can always keep it */
2740  keep_partkey = (relation->rd_partkey != NULL);
2741 
2742  /*
2743  * Perform swapping of the relcache entry contents. Within this
2744  * process the old entry is momentarily invalid, so there *must* be no
2745  * possibility of CHECK_FOR_INTERRUPTS within this sequence. Do it in
2746  * all-in-line code for safety.
2747  *
2748  * Since the vast majority of fields should be swapped, our method is
2749  * to swap the whole structures and then re-swap those few fields we
2750  * didn't want swapped.
2751  */
2752 #define SWAPFIELD(fldtype, fldname) \
2753  do { \
2754  fldtype _tmp = newrel->fldname; \
2755  newrel->fldname = relation->fldname; \
2756  relation->fldname = _tmp; \
2757  } while (0)
2758 
2759  /* swap all Relation struct fields */
2760  {
2761  RelationData tmpstruct;
2762 
2763  memcpy(&tmpstruct, newrel, sizeof(RelationData));
2764  memcpy(newrel, relation, sizeof(RelationData));
2765  memcpy(relation, &tmpstruct, sizeof(RelationData));
2766  }
2767 
2768  /* rd_smgr must not be swapped, due to back-links from smgr level */
2769  SWAPFIELD(SMgrRelation, rd_smgr);
2770  /* rd_refcnt must be preserved */
2771  SWAPFIELD(int, rd_refcnt);
2772  /* isnailed shouldn't change */
2773  Assert(newrel->rd_isnailed == relation->rd_isnailed);
2774  /* creation sub-XIDs must be preserved */
2775  SWAPFIELD(SubTransactionId, rd_createSubid);
2776  SWAPFIELD(SubTransactionId, rd_newRelfilelocatorSubid);
2777  SWAPFIELD(SubTransactionId, rd_firstRelfilelocatorSubid);
2778  SWAPFIELD(SubTransactionId, rd_droppedSubid);
2779  /* un-swap rd_rel pointers, swap contents instead */
2780  SWAPFIELD(Form_pg_class, rd_rel);
2781  /* ... but actually, we don't have to update newrel->rd_rel */
2782  memcpy(relation->rd_rel, newrel->rd_rel, CLASS_TUPLE_SIZE);
2783  /* preserve old tupledesc, rules, policies if no logical change */
2784  if (keep_tupdesc)
2785  SWAPFIELD(TupleDesc, rd_att);
2786  if (keep_rules)
2787  {
2788  SWAPFIELD(RuleLock *, rd_rules);
2789  SWAPFIELD(MemoryContext, rd_rulescxt);
2790  }
2791  if (keep_policies)
2792  SWAPFIELD(RowSecurityDesc *, rd_rsdesc);
2793  /* toast OID override must be preserved */
2794  SWAPFIELD(Oid, rd_toastoid);
2795  /* pgstat_info / enabled must be preserved */
2796  SWAPFIELD(struct PgStat_TableStatus *, pgstat_info);
2797  SWAPFIELD(bool, pgstat_enabled);
2798  /* preserve old partition key if we have one */
2799  if (keep_partkey)
2800  {
2801  SWAPFIELD(PartitionKey, rd_partkey);
2802  SWAPFIELD(MemoryContext, rd_partkeycxt);
2803  }
2804  if (newrel->rd_pdcxt != NULL || newrel->rd_pddcxt != NULL)
2805  {
2806  /*
2807  * We are rebuilding a partitioned relation with a non-zero
2808  * reference count, so we must keep the old partition descriptor
2809  * around, in case there's a PartitionDirectory with a pointer to
2810  * it. This means we can't free the old rd_pdcxt yet. (This is
2811  * necessary because RelationGetPartitionDesc hands out direct
2812  * pointers to the relcache's data structure, unlike our usual
2813  * practice which is to hand out copies. We'd have the same
2814  * problem with rd_partkey, except that we always preserve that
2815  * once created.)
2816  *
2817  * To ensure that it's not leaked completely, re-attach it to the
2818  * new reldesc, or make it a child of the new reldesc's rd_pdcxt
2819  * in the unlikely event that there is one already. (Compare hack
2820  * in RelationBuildPartitionDesc.) RelationClose will clean up
2821  * any such contexts once the reference count reaches zero.
2822  *
2823  * In the case where the reference count is zero, this code is not
2824  * reached, which should be OK because in that case there should
2825  * be no PartitionDirectory with a pointer to the old entry.
2826  *
2827  * Note that newrel and relation have already been swapped, so the
2828  * "old" partition descriptor is actually the one hanging off of
2829  * newrel.
2830  */
2831  relation->rd_partdesc = NULL; /* ensure rd_partdesc is invalid */
2832  relation->rd_partdesc_nodetached = NULL;
2834  if (relation->rd_pdcxt != NULL) /* probably never happens */
2835  MemoryContextSetParent(newrel->rd_pdcxt, relation->rd_pdcxt);
2836  else
2837  relation->rd_pdcxt = newrel->rd_pdcxt;
2838  if (relation->rd_pddcxt != NULL)
2839  MemoryContextSetParent(newrel->rd_pddcxt, relation->rd_pddcxt);
2840  else
2841  relation->rd_pddcxt = newrel->rd_pddcxt;
2842  /* drop newrel's pointers so we don't destroy it below */
2843  newrel->rd_partdesc = NULL;
2844  newrel->rd_partdesc_nodetached = NULL;
2846  newrel->rd_pdcxt = NULL;
2847  newrel->rd_pddcxt = NULL;
2848  }
2849 
2850 #undef SWAPFIELD
2851 
2852  /* And now we can throw away the temporary entry */
2853  RelationDestroyRelation(newrel, !keep_tupdesc);
2854  }
2855 }
2856 
2857 /*
2858  * RelationFlushRelation
2859  *
2860  * Rebuild the relation if it is open (refcount > 0), else blow it away.
2861  * This is used when we receive a cache invalidation event for the rel.
2862  */
2863 static void
2865 {
2866  if (relation->rd_createSubid != InvalidSubTransactionId ||
2868  {
2869  /*
2870  * New relcache entries are always rebuilt, not flushed; else we'd
2871  * forget the "new" status of the relation. Ditto for the
2872  * new-relfilenumber status.
2873  */
2875  {
2876  /*
2877  * The rel could have zero refcnt here, so temporarily increment
2878  * the refcnt to ensure it's safe to rebuild it. We can assume
2879  * that the current transaction has some lock on the rel already.
2880  */
2882  RelationClearRelation(relation, true);
2884  }
2885  else
2886  {
2887  /*
2888  * During abort processing, the current resource owner is not
2889  * valid and we cannot hold a refcnt. Without a valid
2890  * transaction, RelationClearRelation() would just mark the rel as
2891  * invalid anyway, so we can do the same directly.
2892  */
2893  RelationInvalidateRelation(relation);
2894  }
2895  }
2896  else
2897  {
2898  /*
2899  * Pre-existing rels can be dropped from the relcache if not open.
2900  */
2901  bool rebuild = !RelationHasReferenceCountZero(relation);
2902 
2903  RelationClearRelation(relation, rebuild);
2904  }
2905 }
2906 
2907 /*
2908  * RelationForgetRelation - caller reports that it dropped the relation
2909  */
2910 void
2912 {
2913  Relation relation;
2914 
2915  RelationIdCacheLookup(rid, relation);
2916 
2917  if (!PointerIsValid(relation))
2918  return; /* not in cache, nothing to do */
2919 
2920  if (!RelationHasReferenceCountZero(relation))
2921  elog(ERROR, "relation %u is still open", rid);
2922 
2924  if (relation->rd_createSubid != InvalidSubTransactionId ||
2926  {
2927  /*
2928  * In the event of subtransaction rollback, we must not forget
2929  * rd_*Subid. Mark the entry "dropped" so RelationClearRelation()
2930  * invalidates it in lieu of destroying it. (If we're in a top
2931  * transaction, we could opt to destroy the entry.)
2932  */
2934  }
2935 
2936  RelationClearRelation(relation, false);
2937 }
2938 
2939 /*
2940  * RelationCacheInvalidateEntry
2941  *
2942  * This routine is invoked for SI cache flush messages.
2943  *
2944  * Any relcache entry matching the relid must be flushed. (Note: caller has
2945  * already determined that the relid belongs to our database or is a shared
2946  * relation.)
2947  *
2948  * We used to skip local relations, on the grounds that they could
2949  * not be targets of cross-backend SI update messages; but it seems
2950  * safer to process them, so that our *own* SI update messages will
2951  * have the same effects during CommandCounterIncrement for both
2952  * local and nonlocal relations.
2953  */
2954 void
2956 {
2957  Relation relation;
2958 
2959  RelationIdCacheLookup(relationId, relation);
2960 
2961  if (PointerIsValid(relation))
2962  {
2964  RelationFlushRelation(relation);
2965  }
2966  else
2967  {
2968  int i;
2969 
2970  for (i = 0; i < in_progress_list_len; i++)
2971  if (in_progress_list[i].reloid == relationId)
2972  in_progress_list[i].invalidated = true;
2973  }
2974 }
2975 
2976 /*
2977  * RelationCacheInvalidate
2978  * Blow away cached relation descriptors that have zero reference counts,
2979  * and rebuild those with positive reference counts. Also reset the smgr
2980  * relation cache and re-read relation mapping data.
2981  *
2982  * Apart from debug_discard_caches, this is currently used only to recover
2983  * from SI message buffer overflow, so we do not touch relations having
2984  * new-in-transaction relfilenumbers; they cannot be targets of cross-backend
2985  * SI updates (and our own updates now go through a separate linked list
2986  * that isn't limited by the SI message buffer size).
2987  *
2988  * We do this in two phases: the first pass deletes deletable items, and
2989  * the second one rebuilds the rebuildable items. This is essential for
2990  * safety, because hash_seq_search only copes with concurrent deletion of
2991  * the element it is currently visiting. If a second SI overflow were to
2992  * occur while we are walking the table, resulting in recursive entry to
2993  * this routine, we could crash because the inner invocation blows away
2994  * the entry next to be visited by the outer scan. But this way is OK,
2995  * because (a) during the first pass we won't process any more SI messages,
2996  * so hash_seq_search will complete safely; (b) during the second pass we
2997  * only hold onto pointers to nondeletable entries.
2998  *
2999  * The two-phase approach also makes it easy to update relfilenumbers for
3000  * mapped relations before we do anything else, and to ensure that the
3001  * second pass processes nailed-in-cache items before other nondeletable
3002  * items. This should ensure that system catalogs are up to date before
3003  * we attempt to use them to reload information about other open relations.
3004  *
3005  * After those two phases of work having immediate effects, we normally
3006  * signal any RelationBuildDesc() on the stack to start over. However, we
3007  * don't do this if called as part of debug_discard_caches. Otherwise,
3008  * RelationBuildDesc() would become an infinite loop.
3009  */
3010 void
3011 RelationCacheInvalidate(bool debug_discard)
3012 {
3013  HASH_SEQ_STATUS status;
3014  RelIdCacheEnt *idhentry;
3015  Relation relation;
3016  List *rebuildFirstList = NIL;
3017  List *rebuildList = NIL;
3018  ListCell *l;
3019  int i;
3020 
3021  /*
3022  * Reload relation mapping data before starting to reconstruct cache.
3023  */
3025 
3026  /* Phase 1 */
3027  hash_seq_init(&status, RelationIdCache);
3028 
3029  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3030  {
3031  relation = idhentry->reldesc;
3032 
3033  /*
3034  * Ignore new relations; no other backend will manipulate them before
3035  * we commit. Likewise, before replacing a relation's relfilelocator,
3036  * we shall have acquired AccessExclusiveLock and drained any
3037  * applicable pending invalidations.
3038  */
3039  if (relation->rd_createSubid != InvalidSubTransactionId ||
3041  continue;
3042 
3044 
3045  if (RelationHasReferenceCountZero(relation))
3046  {
3047  /* Delete this entry immediately */
3048  Assert(!relation->rd_isnailed);
3049  RelationClearRelation(relation, false);
3050  }
3051  else
3052  {
3053  /*
3054  * If it's a mapped relation, immediately update its rd_locator in
3055  * case its relfilenumber changed. We must do this during phase 1
3056  * in case the relation is consulted during rebuild of other
3057  * relcache entries in phase 2. It's safe since consulting the
3058  * map doesn't involve any access to relcache entries.
3059  */
3060  if (RelationIsMapped(relation))
3061  {
3062  RelationCloseSmgr(relation);
3063  RelationInitPhysicalAddr(relation);
3064  }
3065 
3066  /*
3067  * Add this entry to list of stuff to rebuild in second pass.
3068  * pg_class goes to the front of rebuildFirstList while
3069  * pg_class_oid_index goes to the back of rebuildFirstList, so
3070  * they are done first and second respectively. Other nailed
3071  * relations go to the front of rebuildList, so they'll be done
3072  * next in no particular order; and everything else goes to the
3073  * back of rebuildList.
3074  */
3075  if (RelationGetRelid(relation) == RelationRelationId)
3076  rebuildFirstList = lcons(relation, rebuildFirstList);
3077  else if (RelationGetRelid(relation) == ClassOidIndexId)
3078  rebuildFirstList = lappend(rebuildFirstList, relation);
3079  else if (relation->rd_isnailed)
3080  rebuildList = lcons(relation, rebuildList);
3081  else
3082  rebuildList = lappend(rebuildList, relation);
3083  }
3084  }
3085 
3086  /*
3087  * We cannot destroy the SMgrRelations as there might still be references
3088  * to them, but close the underlying file descriptors.
3089  */
3090  smgrreleaseall();
3091 
3092  /* Phase 2: rebuild the items found to need rebuild in phase 1 */
3093  foreach(l, rebuildFirstList)
3094  {
3095  relation = (Relation) lfirst(l);
3096  RelationClearRelation(relation, true);
3097  }
3098  list_free(rebuildFirstList);
3099  foreach(l, rebuildList)
3100  {
3101  relation = (Relation) lfirst(l);
3102  RelationClearRelation(relation, true);
3103  }
3104  list_free(rebuildList);
3105 
3106  if (!debug_discard)
3107  /* Any RelationBuildDesc() on the stack must start over. */
3108  for (i = 0; i < in_progress_list_len; i++)
3109  in_progress_list[i].invalidated = true;
3110 }
3111 
3112 static void
3114 {
3115  if (EOXactTupleDescArray == NULL)
3116  {
3117  MemoryContext oldcxt;
3118 
3120 
3121  EOXactTupleDescArray = (TupleDesc *) palloc(16 * sizeof(TupleDesc));
3124  MemoryContextSwitchTo(oldcxt);
3125  }
3127  {
3128  int32 newlen = EOXactTupleDescArrayLen * 2;
3129 
3131 
3133  newlen * sizeof(TupleDesc));
3134  EOXactTupleDescArrayLen = newlen;
3135  }
3136 
3138 }
3139 
3140 #ifdef USE_ASSERT_CHECKING
3141 static void
3142 AssertPendingSyncConsistency(Relation relation)
3143 {
3144  bool relcache_verdict =
3145  RelationIsPermanent(relation) &&
3146  ((relation->rd_createSubid != InvalidSubTransactionId &&
3147  RELKIND_HAS_STORAGE(relation->rd_rel->relkind)) ||
3149 
3150  Assert(relcache_verdict == RelFileLocatorSkippingWAL(relation->rd_locator));
3151 
3152  if (relation->rd_droppedSubid != InvalidSubTransactionId)
3153  Assert(!relation->rd_isvalid &&
3154  (relation->rd_createSubid != InvalidSubTransactionId ||
3156 }
3157 
3158 /*
3159  * AssertPendingSyncs_RelationCache
3160  *
3161  * Assert that relcache.c and storage.c agree on whether to skip WAL.
3162  */
3163 void
3165 {
3166  HASH_SEQ_STATUS status;
3167  LOCALLOCK *locallock;
3168  Relation *rels;
3169  int maxrels;
3170  int nrels;
3171  RelIdCacheEnt *idhentry;
3172  int i;
3173 
3174  /*
3175  * Open every relation that this transaction has locked. If, for some
3176  * relation, storage.c is skipping WAL and relcache.c is not skipping WAL,
3177  * a CommandCounterIncrement() typically yields a local invalidation
3178  * message that destroys the relcache entry. By recreating such entries
3179  * here, we detect the problem.
3180  */
3182  maxrels = 1;
3183  rels = palloc(maxrels * sizeof(*rels));
3184  nrels = 0;
3185  hash_seq_init(&status, GetLockMethodLocalHash());
3186  while ((locallock = (LOCALLOCK *) hash_seq_search(&status)) != NULL)
3187  {
3188  Oid relid;
3189  Relation r;
3190 
3191  if (locallock->nLocks <= 0)
3192  continue;
3193  if ((LockTagType) locallock->tag.lock.locktag_type !=
3195  continue;
3196  relid = ObjectIdGetDatum(locallock->tag.lock.locktag_field2);
3197  r = RelationIdGetRelation(relid);
3198  if (!RelationIsValid(r))
3199  continue;
3200  if (nrels >= maxrels)
3201  {
3202  maxrels *= 2;
3203  rels = repalloc(rels, maxrels * sizeof(*rels));
3204  }
3205  rels[nrels++] = r;
3206  }
3207 
3208  hash_seq_init(&status, RelationIdCache);
3209  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3210  AssertPendingSyncConsistency(idhentry->reldesc);
3211 
3212  for (i = 0; i < nrels; i++)
3213  RelationClose(rels[i]);
3215 }
3216 #endif
3217 
3218 /*
3219  * AtEOXact_RelationCache
3220  *
3221  * Clean up the relcache at main-transaction commit or abort.
3222  *
3223  * Note: this must be called *before* processing invalidation messages.
3224  * In the case of abort, we don't want to try to rebuild any invalidated
3225  * cache entries (since we can't safely do database accesses). Therefore
3226  * we must reset refcnts before handling pending invalidations.
3227  *
3228  * As of PostgreSQL 8.1, relcache refcnts should get released by the
3229  * ResourceOwner mechanism. This routine just does a debugging
3230  * cross-check that no pins remain. However, we also need to do special
3231  * cleanup when the current transaction created any relations or made use
3232  * of forced index lists.
3233  */
3234 void
3236 {
3237  HASH_SEQ_STATUS status;
3238  RelIdCacheEnt *idhentry;
3239  int i;
3240 
3241  /*
3242  * Forget in_progress_list. This is relevant when we're aborting due to
3243  * an error during RelationBuildDesc().
3244  */
3245  Assert(in_progress_list_len == 0 || !isCommit);
3247 
3248  /*
3249  * Unless the eoxact_list[] overflowed, we only need to examine the rels
3250  * listed in it. Otherwise fall back on a hash_seq_search scan.
3251  *
3252  * For simplicity, eoxact_list[] entries are not deleted till end of
3253  * top-level transaction, even though we could remove them at
3254  * subtransaction end in some cases, or remove relations from the list if
3255  * they are cleared for other reasons. Therefore we should expect the
3256  * case that list entries are not found in the hashtable; if not, there's
3257  * nothing to do for them.
3258  */
3260  {
3261  hash_seq_init(&status, RelationIdCache);
3262  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3263  {
3264  AtEOXact_cleanup(idhentry->reldesc, isCommit);
3265  }
3266  }
3267  else
3268  {
3269  for (i = 0; i < eoxact_list_len; i++)
3270  {
3271  idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
3272  &eoxact_list[i],
3273  HASH_FIND,
3274  NULL);
3275  if (idhentry != NULL)
3276  AtEOXact_cleanup(idhentry->reldesc, isCommit);
3277  }
3278  }
3279 
3280  if (EOXactTupleDescArrayLen > 0)
3281  {
3282  Assert(EOXactTupleDescArray != NULL);
3283  for (i = 0; i < NextEOXactTupleDescNum; i++)
3286  EOXactTupleDescArray = NULL;
3287  }
3288 
3289  /* Now we're out of the transaction and can clear the lists */
3290  eoxact_list_len = 0;
3291  eoxact_list_overflowed = false;
3294 }
3295 
3296 /*
3297  * AtEOXact_cleanup
3298  *
3299  * Clean up a single rel at main-transaction commit or abort
3300  *
3301  * NB: this processing must be idempotent, because EOXactListAdd() doesn't
3302  * bother to prevent duplicate entries in eoxact_list[].
3303  */
3304 static void
3305 AtEOXact_cleanup(Relation relation, bool isCommit)
3306 {
3307  bool clear_relcache = false;
3308 
3309  /*
3310  * The relcache entry's ref count should be back to its normal
3311  * not-in-a-transaction state: 0 unless it's nailed in cache.
3312  *
3313  * In bootstrap mode, this is NOT true, so don't check it --- the
3314  * bootstrap code expects relations to stay open across start/commit
3315  * transaction calls. (That seems bogus, but it's not worth fixing.)
3316  *
3317  * Note: ideally this check would be applied to every relcache entry, not
3318  * just those that have eoxact work to do. But it's not worth forcing a
3319  * scan of the whole relcache just for this. (Moreover, doing so would
3320  * mean that assert-enabled testing never tests the hash_search code path
3321  * above, which seems a bad idea.)
3322  */
3323 #ifdef USE_ASSERT_CHECKING
3325  {
3326  int expected_refcnt;
3327 
3328  expected_refcnt = relation->rd_isnailed ? 1 : 0;
3329  Assert(relation->rd_refcnt == expected_refcnt);
3330  }
3331 #endif
3332 
3333  /*
3334  * Is the relation live after this transaction ends?
3335  *
3336  * During commit, clear the relcache entry if it is preserved after
3337  * relation drop, in order not to orphan the entry. During rollback,
3338  * clear the relcache entry if the relation is created in the current
3339  * transaction since it isn't interesting any longer once we are out of
3340  * the transaction.
3341  */
3342  clear_relcache =
3343  (isCommit ?
3346 
3347  /*
3348  * Since we are now out of the transaction, reset the subids to zero. That
3349  * also lets RelationClearRelation() drop the relcache entry.
3350  */
3355 
3356  if (clear_relcache)
3357  {
3358  if (RelationHasReferenceCountZero(relation))
3359  {
3360  RelationClearRelation(relation, false);
3361  return;
3362  }
3363  else
3364  {
3365  /*
3366  * Hmm, somewhere there's a (leaked?) reference to the relation.
3367  * We daren't remove the entry for fear of dereferencing a
3368  * dangling pointer later. Bleat, and mark it as not belonging to
3369  * the current transaction. Hopefully it'll get cleaned up
3370  * eventually. This must be just a WARNING to avoid
3371  * error-during-error-recovery loops.
3372  */
3373  elog(WARNING, "cannot remove relcache entry for \"%s\" because it has nonzero refcount",
3374  RelationGetRelationName(relation));
3375  }
3376  }
3377 }
3378 
3379 /*
3380  * AtEOSubXact_RelationCache
3381  *
3382  * Clean up the relcache at sub-transaction commit or abort.
3383  *
3384  * Note: this must be called *before* processing invalidation messages.
3385  */
3386 void
3388  SubTransactionId parentSubid)
3389 {
3390  HASH_SEQ_STATUS status;
3391  RelIdCacheEnt *idhentry;
3392  int i;
3393 
3394  /*
3395  * Forget in_progress_list. This is relevant when we're aborting due to
3396  * an error during RelationBuildDesc(). We don't commit subtransactions
3397  * during RelationBuildDesc().
3398  */
3399  Assert(in_progress_list_len == 0 || !isCommit);
3401 
3402  /*
3403  * Unless the eoxact_list[] overflowed, we only need to examine the rels
3404  * listed in it. Otherwise fall back on a hash_seq_search scan. Same
3405  * logic as in AtEOXact_RelationCache.
3406  */
3408  {
3409  hash_seq_init(&status, RelationIdCache);
3410  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
3411  {
3412  AtEOSubXact_cleanup(idhentry->reldesc, isCommit,
3413  mySubid, parentSubid);
3414  }
3415  }
3416  else
3417  {
3418  for (i = 0; i < eoxact_list_len; i++)
3419  {
3420  idhentry = (RelIdCacheEnt *) hash_search(RelationIdCache,
3421  &eoxact_list[i],
3422  HASH_FIND,
3423  NULL);
3424  if (idhentry != NULL)
3425  AtEOSubXact_cleanup(idhentry->reldesc, isCommit,
3426  mySubid, parentSubid);
3427  }
3428  }
3429 
3430  /* Don't reset the list; we still need more cleanup later */
3431 }
3432 
3433 /*
3434  * AtEOSubXact_cleanup
3435  *
3436  * Clean up a single rel at subtransaction commit or abort
3437  *
3438  * NB: this processing must be idempotent, because EOXactListAdd() doesn't
3439  * bother to prevent duplicate entries in eoxact_list[].
3440  */
3441 static void
3442 AtEOSubXact_cleanup(Relation relation, bool isCommit,
3443  SubTransactionId mySubid, SubTransactionId parentSubid)
3444 {
3445  /*
3446  * Is it a relation created in the current subtransaction?
3447  *
3448  * During subcommit, mark it as belonging to the parent, instead, as long
3449  * as it has not been dropped. Otherwise simply delete the relcache entry.
3450  * --- it isn't interesting any longer.
3451  */
3452  if (relation->rd_createSubid == mySubid)
3453  {
3454  /*
3455  * Valid rd_droppedSubid means the corresponding relation is dropped
3456  * but the relcache entry is preserved for at-commit pending sync. We
3457  * need to drop it explicitly here not to make the entry orphan.
3458  */
3459  Assert(relation->rd_droppedSubid == mySubid ||
3461  if (isCommit && relation->rd_droppedSubid == InvalidSubTransactionId)
3462  relation->rd_createSubid = parentSubid;
3463  else if (RelationHasReferenceCountZero(relation))
3464  {
3465  /* allow the entry to be removed */
3470  RelationClearRelation(relation, false);
3471  return;
3472  }
3473  else
3474  {
3475  /*
3476  * Hmm, somewhere there's a (leaked?) reference to the relation.
3477  * We daren't remove the entry for fear of dereferencing a
3478  * dangling pointer later. Bleat, and transfer it to the parent
3479  * subtransaction so we can try again later. This must be just a
3480  * WARNING to avoid error-during-error-recovery loops.
3481  */
3482  relation->rd_createSubid = parentSubid;
3483  elog(WARNING, "cannot remove relcache entry for \"%s\" because it has nonzero refcount",
3484  RelationGetRelationName(relation));
3485  }
3486  }
3487 
3488  /*
3489  * Likewise, update or drop any new-relfilenumber-in-subtransaction record
3490  * or drop record.
3491  */
3492  if (relation->rd_newRelfilelocatorSubid == mySubid)
3493  {
3494  if (isCommit)
3495  relation->rd_newRelfilelocatorSubid = parentSubid;
3496  else
3498  }
3499 
3500  if (relation->rd_firstRelfilelocatorSubid == mySubid)
3501  {
3502  if (isCommit)
3503  relation->rd_firstRelfilelocatorSubid = parentSubid;
3504  else
3506  }
3507 
3508  if (relation->rd_droppedSubid == mySubid)
3509  {
3510  if (isCommit)
3511  relation->rd_droppedSubid = parentSubid;
3512  else
3514  }
3515 }
3516 
3517 
3518 /*
3519  * RelationBuildLocalRelation
3520  * Build a relcache entry for an about-to-be-created relation,
3521  * and enter it into the relcache.
3522  */
3523 Relation
3525  Oid relnamespace,
3526  TupleDesc tupDesc,
3527  Oid relid,
3528  Oid accessmtd,
3529  RelFileNumber relfilenumber,
3530  Oid reltablespace,
3531  bool shared_relation,
3532  bool mapped_relation,
3533  char relpersistence,
3534  char relkind)
3535 {
3536  Relation rel;
3537  MemoryContext oldcxt;
3538  int natts = tupDesc->natts;
3539  int i;
3540  bool has_not_null;
3541  bool nailit;
3542 
3543  Assert(natts >= 0);
3544 
3545  /*
3546  * check for creation of a rel that must be nailed in cache.
3547  *
3548  * XXX this list had better match the relations specially handled in
3549  * RelationCacheInitializePhase2/3.
3550  */
3551  switch (relid)
3552  {
3553  case DatabaseRelationId:
3554  case AuthIdRelationId:
3555  case AuthMemRelationId:
3556  case RelationRelationId:
3557  case AttributeRelationId:
3558  case ProcedureRelationId:
3559  case TypeRelationId:
3560  nailit = true;
3561  break;
3562  default:
3563  nailit = false;
3564  break;
3565  }
3566 
3567  /*
3568  * check that hardwired list of shared rels matches what's in the
3569  * bootstrap .bki file. If you get a failure here during initdb, you
3570  * probably need to fix IsSharedRelation() to match whatever you've done
3571  * to the set of shared relations.
3572  */
3573  if (shared_relation != IsSharedRelation(relid))
3574  elog(ERROR, "shared_relation flag for \"%s\" does not match IsSharedRelation(%u)",
3575  relname, relid);
3576 
3577  /* Shared relations had better be mapped, too */
3578  Assert(mapped_relation || !shared_relation);
3579 
3580  /*
3581  * switch to the cache context to create the relcache entry.
3582  */
3583  if (!CacheMemoryContext)
3585 
3587 
3588  /*
3589  * allocate a new relation descriptor and fill in basic state fields.
3590  */
3591  rel = (Relation) palloc0(sizeof(RelationData));
3592 
3593  /* make sure relation is marked as having no open file yet */
3594  rel->rd_smgr = NULL;
3595 
3596  /* mark it nailed if appropriate */
3597  rel->rd_isnailed = nailit;
3598 
3599  rel->rd_refcnt = nailit ? 1 : 0;
3600 
3601  /* it's being created in this transaction */
3606 
3607  /*
3608  * create a new tuple descriptor from the one passed in. We do this
3609  * partly to copy it into the cache context, and partly because the new
3610  * relation can't have any defaults or constraints yet; they have to be
3611  * added in later steps, because they require additions to multiple system
3612  * catalogs. We can copy attnotnull constraints here, however.
3613  */
3614  rel->rd_att = CreateTupleDescCopy(tupDesc);
3615  rel->rd_att->tdrefcount = 1; /* mark as refcounted */
3616  has_not_null = false;
3617  for (i = 0; i < natts; i++)
3618  {
3619  Form_pg_attribute satt = TupleDescAttr(tupDesc, i);
3620  Form_pg_attribute datt = TupleDescAttr(rel->rd_att, i);
3621 
3622  datt->attidentity = satt->attidentity;
3623  datt->attgenerated = satt->attgenerated;
3624  datt->attnotnull = satt->attnotnull;
3625  has_not_null |= satt->attnotnull;
3626  }
3627 
3628  if (has_not_null)
3629  {
3630  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
3631 
3632  constr->has_not_null = true;
3633  rel->rd_att->constr = constr;
3634  }
3635 
3636  /*
3637  * initialize relation tuple form (caller may add/override data later)
3638  */
3640 
3641  namestrcpy(&rel->rd_rel->relname, relname);
3642  rel->rd_rel->relnamespace = relnamespace;
3643 
3644  rel->rd_rel->relkind = relkind;
3645  rel->rd_rel->relnatts = natts;
3646  rel->rd_rel->reltype = InvalidOid;
3647  /* needed when bootstrapping: */
3648  rel->rd_rel->relowner = BOOTSTRAP_SUPERUSERID;
3649 
3650  /* set up persistence and relcache fields dependent on it */
3651  rel->rd_rel->relpersistence = relpersistence;
3652  switch (relpersistence)
3653  {
3654  case RELPERSISTENCE_UNLOGGED:
3655  case RELPERSISTENCE_PERMANENT:
3657  rel->rd_islocaltemp = false;
3658  break;
3659  case RELPERSISTENCE_TEMP:
3660  Assert(isTempOrTempToastNamespace(relnamespace));
3662  rel->rd_islocaltemp = true;
3663  break;
3664  default:
3665  elog(ERROR, "invalid relpersistence: %c", relpersistence);
3666  break;
3667  }
3668 
3669  /* if it's a materialized view, it's not populated initially */
3670  if (relkind == RELKIND_MATVIEW)
3671  rel->rd_rel->relispopulated = false;
3672  else
3673  rel->rd_rel->relispopulated = true;
3674 
3675  /* set replica identity -- system catalogs and non-tables don't have one */
3676  if (!IsCatalogNamespace(relnamespace) &&
3677  (relkind == RELKIND_RELATION ||
3678  relkind == RELKIND_MATVIEW ||
3679  relkind == RELKIND_PARTITIONED_TABLE))
3680  rel->rd_rel->relreplident = REPLICA_IDENTITY_DEFAULT;
3681  else
3682  rel->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
3683 
3684  /*
3685  * Insert relation physical and logical identifiers (OIDs) into the right
3686  * places. For a mapped relation, we set relfilenumber to zero and rely
3687  * on RelationInitPhysicalAddr to consult the map.
3688  */
3689  rel->rd_rel->relisshared = shared_relation;
3690 
3691  RelationGetRelid(rel) = relid;
3692 
3693  for (i = 0; i < natts; i++)
3694  TupleDescAttr(rel->rd_att, i)->attrelid = relid;
3695 
3696  rel->rd_rel->reltablespace = reltablespace;
3697 
3698  if (mapped_relation)
3699  {
3700  rel->rd_rel->relfilenode = InvalidRelFileNumber;
3701  /* Add it to the active mapping information */
3702  RelationMapUpdateMap(relid, relfilenumber, shared_relation, true);
3703  }
3704  else
3705  rel->rd_rel->relfilenode = relfilenumber;
3706 
3707  RelationInitLockInfo(rel); /* see lmgr.c */
3708 
3710 
3711  rel->rd_rel->relam = accessmtd;
3712 
3713  /*
3714  * RelationInitTableAccessMethod will do syscache lookups, so we mustn't
3715  * run it in CacheMemoryContext. Fortunately, the remaining steps don't
3716  * require a long-lived current context.
3717  */
3718  MemoryContextSwitchTo(oldcxt);
3719 
3720  if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_SEQUENCE)
3722 
3723  /*
3724  * Okay to insert into the relcache hash table.
3725  *
3726  * Ordinarily, there should certainly not be an existing hash entry for
3727  * the same OID; but during bootstrap, when we create a "real" relcache
3728  * entry for one of the bootstrap relations, we'll be overwriting the
3729  * phony one created with formrdesc. So allow that to happen for nailed
3730  * rels.
3731  */
3732  RelationCacheInsert(rel, nailit);
3733 
3734  /*
3735  * Flag relation as needing eoxact cleanup (to clear rd_createSubid). We
3736  * can't do this before storing relid in it.
3737  */
3738  EOXactListAdd(rel);
3739 
3740  /* It's fully valid */
3741  rel->rd_isvalid = true;
3742 
3743  /*
3744  * Caller expects us to pin the returned entry.
3745  */
3747 
3748  return rel;
3749 }
3750 
3751 
3752 /*
3753  * RelationSetNewRelfilenumber
3754  *
3755  * Assign a new relfilenumber (physical file name), and possibly a new
3756  * persistence setting, to the relation.
3757  *
3758  * This allows a full rewrite of the relation to be done with transactional
3759  * safety (since the filenumber assignment can be rolled back). Note however
3760  * that there is no simple way to access the relation's old data for the
3761  * remainder of the current transaction. This limits the usefulness to cases
3762  * such as TRUNCATE or rebuilding an index from scratch.
3763  *
3764  * Caller must already hold exclusive lock on the relation.
3765  */
3766 void
3767 RelationSetNewRelfilenumber(Relation relation, char persistence)
3768 {
3769  RelFileNumber newrelfilenumber;
3770  Relation pg_class;
3771  HeapTuple tuple;
3772  Form_pg_class classform;
3773  MultiXactId minmulti = InvalidMultiXactId;
3774  TransactionId freezeXid = InvalidTransactionId;
3775  RelFileLocator newrlocator;
3776 
3777  if (!IsBinaryUpgrade)
3778  {
3779  /* Allocate a new relfilenumber */
3780  newrelfilenumber = GetNewRelFileNumber(relation->rd_rel->reltablespace,
3781  NULL, persistence);
3782  }
3783  else if (relation->rd_rel->relkind == RELKIND_INDEX)
3784  {
3786  ereport(ERROR,
3787  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3788  errmsg("index relfilenumber value not set when in binary upgrade mode")));
3789 
3792  }
3793  else if (relation->rd_rel->relkind == RELKIND_RELATION)
3794  {
3796  ereport(ERROR,
3797  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3798  errmsg("heap relfilenumber value not set when in binary upgrade mode")));
3799 
3802  }
3803  else
3804  ereport(ERROR,
3805  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3806  errmsg("unexpected request for new relfilenumber in binary upgrade mode")));
3807 
3808  /*
3809  * Get a writable copy of the pg_class tuple for the given relation.
3810  */
3811  pg_class = table_open(RelationRelationId, RowExclusiveLock);
3812 
3813  tuple = SearchSysCacheCopy1(RELOID,
3814  ObjectIdGetDatum(RelationGetRelid(relation)));
3815  if (!HeapTupleIsValid(tuple))
3816  elog(ERROR, "could not find tuple for relation %u",
3817  RelationGetRelid(relation));
3818  classform = (Form_pg_class) GETSTRUCT(tuple);
3819 
3820  /*
3821  * Schedule unlinking of the old storage at transaction commit, except
3822  * when performing a binary upgrade, when we must do it immediately.
3823  */
3824  if (IsBinaryUpgrade)
3825  {
3826  SMgrRelation srel;
3827 
3828  /*
3829  * During a binary upgrade, we use this code path to ensure that
3830  * pg_largeobject and its index have the same relfilenumbers as in the
3831  * old cluster. This is necessary because pg_upgrade treats
3832  * pg_largeobject like a user table, not a system table. It is however
3833  * possible that a table or index may need to end up with the same
3834  * relfilenumber in the new cluster as what it had in the old cluster.
3835  * Hence, we can't wait until commit time to remove the old storage.
3836  *
3837  * In general, this function needs to have transactional semantics,
3838  * and removing the old storage before commit time surely isn't.
3839  * However, it doesn't really matter, because if a binary upgrade
3840  * fails at this stage, the new cluster will need to be recreated
3841  * anyway.
3842  */
3843  srel = smgropen(relation->rd_locator, relation->rd_backend);
3844  smgrdounlinkall(&srel, 1, false);
3845  smgrclose(srel);
3846  }
3847  else
3848  {
3849  /* Not a binary upgrade, so just schedule it to happen later. */
3850  RelationDropStorage(relation);
3851  }
3852 
3853  /*
3854  * Create storage for the main fork of the new relfilenumber. If it's a
3855  * table-like object, call into the table AM to do so, which'll also
3856  * create the table's init fork if needed.
3857  *
3858  * NOTE: If relevant for the AM, any conflict in relfilenumber value will
3859  * be caught here, if GetNewRelFileNumber messes up for any reason.
3860  */
3861  newrlocator = relation->rd_locator;
3862  newrlocator.relNumber = newrelfilenumber;
3863 
3864  if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
3865  {
3866  table_relation_set_new_filelocator(relation, &newrlocator,
3867  persistence,
3868  &freezeXid, &minmulti);
3869  }
3870  else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
3871  {
3872  /* handle these directly, at least for now */
3873  SMgrRelation srel;
3874 
3875  srel = RelationCreateStorage(newrlocator, persistence, true);
3876  smgrclose(srel);
3877  }
3878  else
3879  {
3880  /* we shouldn't be called for anything else */
3881  elog(ERROR, "relation \"%s\" does not have storage",
3882  RelationGetRelationName(relation));
3883  }
3884 
3885  /*
3886  * If we're dealing with a mapped index, pg_class.relfilenode doesn't
3887  * change; instead we have to send the update to the relation mapper.
3888  *
3889  * For mapped indexes, we don't actually change the pg_class entry at all;
3890  * this is essential when reindexing pg_class itself. That leaves us with
3891  * possibly-inaccurate values of relpages etc, but those will be fixed up
3892  * later.
3893  */
3894  if (RelationIsMapped(relation))
3895  {
3896  /* This case is only supported for indexes */
3897  Assert(relation->rd_rel->relkind == RELKIND_INDEX);
3898 
3899  /* Since we're not updating pg_class, these had better not change */
3900  Assert(classform->relfrozenxid == freezeXid);
3901  Assert(classform->relminmxid == minmulti);
3902  Assert(classform->relpersistence == persistence);
3903 
3904  /*
3905  * In some code paths it's possible that the tuple update we'd
3906  * otherwise do here is the only thing that would assign an XID for
3907  * the current transaction. However, we must have an XID to delete
3908  * files, so make sure one is assigned.
3909  */
3910  (void) GetCurrentTransactionId();
3911 
3912  /* Do the deed */
3914  newrelfilenumber,
3915  relation->rd_rel->relisshared,
3916  false);
3917 
3918  /* Since we're not updating pg_class, must trigger inval manually */
3919  CacheInvalidateRelcache(relation);
3920  }
3921  else
3922  {
3923  /* Normal case, update the pg_class entry */
3924  classform->relfilenode = newrelfilenumber;
3925 
3926  /* relpages etc. never change for sequences */
3927  if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
3928  {
3929  classform->relpages = 0; /* it's empty until further notice */
3930  classform->reltuples = -1;
3931  classform->relallvisible = 0;
3932  }
3933  classform->relfrozenxid = freezeXid;
3934  classform->relminmxid = minmulti;
3935  classform->relpersistence = persistence;
3936 
3937  CatalogTupleUpdate(pg_class, &tuple->t_self, tuple);
3938  }
3939 
3940  heap_freetuple(tuple);
3941 
3942  table_close(pg_class, RowExclusiveLock);
3943 
3944  /*
3945  * Make the pg_class row change or relation map change visible. This will
3946  * cause the relcache entry to get updated, too.
3947  */
3949 
3951 }
3952 
3953 /*
3954  * RelationAssumeNewRelfilelocator
3955  *
3956  * Code that modifies pg_class.reltablespace or pg_class.relfilenode must call
3957  * this. The call shall precede any code that might insert WAL records whose
3958  * replay would modify bytes in the new RelFileLocator, and the call shall follow
3959  * any WAL modifying bytes in the prior RelFileLocator. See struct RelationData.
3960  * Ideally, call this as near as possible to the CommandCounterIncrement()
3961  * that makes the pg_class change visible (before it or after it); that
3962  * minimizes the chance of future development adding a forbidden WAL insertion
3963  * between RelationAssumeNewRelfilelocator() and CommandCounterIncrement().
3964  */
3965 void
3967 {
3971 
3972  /* Flag relation as needing eoxact cleanup (to clear these fields) */
3973  EOXactListAdd(relation);
3974 }
3975 
3976 
3977 /*
3978  * RelationCacheInitialize
3979  *
3980  * This initializes the relation descriptor cache. At the time
3981  * that this is invoked, we can't do database access yet (mainly
3982  * because the transaction subsystem is not up); all we are doing
3983  * is making an empty cache hashtable. This must be done before
3984  * starting the initialization transaction, because otherwise
3985  * AtEOXact_RelationCache would crash if that transaction aborts
3986  * before we can get the relcache set up.
3987  */
3988 
3989 #define INITRELCACHESIZE 400
3990 
3991 void
3993 {
3994  HASHCTL ctl;
3995  int allocsize;
3996 
3997  /*
3998  * make sure cache memory context exists
3999  */
4000  if (!CacheMemoryContext)
4002 
4003  /*
4004  * create hashtable that indexes the relcache
4005  */
4006  ctl.keysize = sizeof(Oid);
4007  ctl.entrysize = sizeof(RelIdCacheEnt);
4008  RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE,
4009  &ctl, HASH_ELEM | HASH_BLOBS);
4010 
4011  /*
4012  * reserve enough in_progress_list slots for many cases
4013  */
4014  allocsize = 4;
4017  allocsize * sizeof(*in_progress_list));
4018  in_progress_list_maxlen = allocsize;
4019 
4020  /*
4021  * relation mapper needs to be initialized too
4022  */
4024 }
4025 
4026 /*
4027  * RelationCacheInitializePhase2
4028  *
4029  * This is called to prepare for access to shared catalogs during startup.
4030  * We must at least set up nailed reldescs for pg_database, pg_authid,
4031  * pg_auth_members, and pg_shseclabel. Ideally we'd like to have reldescs
4032  * for their indexes, too. We attempt to load this information from the
4033  * shared relcache init file. If that's missing or broken, just make
4034  * phony entries for the catalogs themselves.
4035  * RelationCacheInitializePhase3 will clean up as needed.
4036  */
4037 void
4039 {
4040  MemoryContext oldcxt;
4041 
4042  /*
4043  * relation mapper needs initialized too
4044  */
4046 
4047  /*
4048  * In bootstrap mode, the shared catalogs aren't there yet anyway, so do
4049  * nothing.
4050  */
4052  return;
4053 
4054  /*
4055  * switch to cache memory context
4056  */
4058 
4059  /*
4060  * Try to load the shared relcache cache file. If unsuccessful, bootstrap
4061  * the cache with pre-made descriptors for the critical shared catalogs.
4062  */
4063  if (!load_relcache_init_file(true))
4064  {
4065  formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true,
4066  Natts_pg_database, Desc_pg_database);
4067  formrdesc("pg_authid", AuthIdRelation_Rowtype_Id, true,
4068  Natts_pg_authid, Desc_pg_authid);
4069  formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id, true,
4070  Natts_pg_auth_members, Desc_pg_auth_members);
4071  formrdesc("pg_shseclabel", SharedSecLabelRelation_Rowtype_Id, true,
4072  Natts_pg_shseclabel, Desc_pg_shseclabel);
4073  formrdesc("pg_subscription", SubscriptionRelation_Rowtype_Id, true,
4074  Natts_pg_subscription, Desc_pg_subscription);
4075 
4076 #define NUM_CRITICAL_SHARED_RELS 5 /* fix if you change list above */
4077  }
4078 
4079  MemoryContextSwitchTo(oldcxt);
4080 }
4081 
4082 /*
4083  * RelationCacheInitializePhase3
4084  *
4085  * This is called as soon as the catcache and transaction system
4086  * are functional and we have determined MyDatabaseId. At this point
4087  * we can actually read data from the database's system catalogs.
4088  * We first try to read pre-computed relcache entries from the local
4089  * relcache init file. If that's missing or broken, make phony entries
4090  * for the minimum set of nailed-in-cache relations. Then (unless
4091  * bootstrapping) make sure we have entries for the critical system
4092  * indexes. Once we've done all this, we have enough infrastructure to
4093  * open any system catalog or use any catcache. The last step is to
4094  * rewrite the cache files if needed.
4095  */
4096 void
4098 {
4099  HASH_SEQ_STATUS status;
4100  RelIdCacheEnt *idhentry;
4101  MemoryContext oldcxt;
4102  bool needNewCacheFile = !criticalSharedRelcachesBuilt;
4103 
4104  /*
4105  * relation mapper needs initialized too
4106  */
4108 
4109  /*
4110  * switch to cache memory context
4111  */
4113 
4114  /*
4115  * Try to load the local relcache cache file. If unsuccessful, bootstrap
4116  * the cache with pre-made descriptors for the critical "nailed-in" system
4117  * catalogs.
4118  */
4119  if (IsBootstrapProcessingMode() ||
4120  !load_relcache_init_file(false))
4121  {
4122  needNewCacheFile = true;
4123 
4124  formrdesc("pg_class", RelationRelation_Rowtype_Id, false,
4125  Natts_pg_class, Desc_pg_class);
4126  formrdesc("pg_attribute", AttributeRelation_Rowtype_Id, false,
4127  Natts_pg_attribute, Desc_pg_attribute);
4128  formrdesc("pg_proc", ProcedureRelation_Rowtype_Id, false,
4129  Natts_pg_proc, Desc_pg_proc);
4130  formrdesc("pg_type", TypeRelation_Rowtype_Id, false,
4131  Natts_pg_type, Desc_pg_type);
4132 
4133 #define NUM_CRITICAL_LOCAL_RELS 4 /* fix if you change list above */
4134  }
4135 
4136  MemoryContextSwitchTo(oldcxt);
4137 
4138  /* In bootstrap mode, the faked-up formrdesc info is all we'll have */
4140  return;
4141 
4142  /*
4143  * If we didn't get the critical system indexes loaded into relcache, do
4144  * so now. These are critical because the catcache and/or opclass cache
4145  * depend on them for fetches done during relcache load. Thus, we have an
4146  * infinite-recursion problem. We can break the recursion by doing
4147  * heapscans instead of indexscans at certain key spots. To avoid hobbling
4148  * performance, we only want to do that until we have the critical indexes
4149  * loaded into relcache. Thus, the flag criticalRelcachesBuilt is used to
4150  * decide whether to do heapscan or indexscan at the key spots, and we set
4151  * it true after we've loaded the critical indexes.
4152  *
4153  * The critical indexes are marked as "nailed in cache", partly to make it
4154  * easy for load_relcache_init_file to count them, but mainly because we
4155  * cannot flush and rebuild them once we've set criticalRelcachesBuilt to
4156  * true. (NOTE: perhaps it would be possible to reload them by
4157  * temporarily setting criticalRelcachesBuilt to false again. For now,
4158  * though, we just nail 'em in.)
4159  *
4160  * RewriteRelRulenameIndexId and TriggerRelidNameIndexId are not critical
4161  * in the same way as the others, because the critical catalogs don't
4162  * (currently) have any rules or triggers, and so these indexes can be
4163  * rebuilt without inducing recursion. However they are used during
4164  * relcache load when a rel does have rules or triggers, so we choose to
4165  * nail them for performance reasons.
4166  */
4168  {
4169  load_critical_index(ClassOidIndexId,
4170  RelationRelationId);
4171  load_critical_index(AttributeRelidNumIndexId,
4172  AttributeRelationId);
4173  load_critical_index(IndexRelidIndexId,
4174  IndexRelationId);
4175  load_critical_index(OpclassOidIndexId,
4176  OperatorClassRelationId);
4177  load_critical_index(AccessMethodProcedureIndexId,
4178  AccessMethodProcedureRelationId);
4179  load_critical_index(RewriteRelRulenameIndexId,
4180  RewriteRelationId);
4181  load_critical_index(TriggerRelidNameIndexId,
4182  TriggerRelationId);
4183 
4184 #define NUM_CRITICAL_LOCAL_INDEXES 7 /* fix if you change list above */
4185 
4186  criticalRelcachesBuilt = true;
4187  }
4188 
4189  /*
4190  * Process critical shared indexes too.
4191  *
4192  * DatabaseNameIndexId isn't critical for relcache loading, but rather for
4193  * initial lookup of MyDatabaseId, without which we'll never find any
4194  * non-shared catalogs at all. Autovacuum calls InitPostgres with a
4195  * database OID, so it instead depends on DatabaseOidIndexId. We also
4196  * need to nail up some indexes on pg_authid and pg_auth_members for use
4197  * during client authentication. SharedSecLabelObjectIndexId isn't
4198  * critical for the core system, but authentication hooks might be
4199  * interested in it.
4200  */
4202  {
4203  load_critical_index(DatabaseNameIndexId,
4204  DatabaseRelationId);
4205  load_critical_index(DatabaseOidIndexId,
4206  DatabaseRelationId);
4207  load_critical_index(AuthIdRolnameIndexId,
4208  AuthIdRelationId);
4209  load_critical_index(AuthIdOidIndexId,
4210  AuthIdRelationId);
4211  load_critical_index(AuthMemMemRoleIndexId,
4212  AuthMemRelationId);
4213  load_critical_index(SharedSecLabelObjectIndexId,
4214  SharedSecLabelRelationId);
4215 
4216 #define NUM_CRITICAL_SHARED_INDEXES 6 /* fix if you change list above */
4217 
4219  }
4220 
4221  /*
4222  * Now, scan all the relcache entries and update anything that might be
4223  * wrong in the results from formrdesc or the relcache cache file. If we
4224  * faked up relcache entries using formrdesc, then read the real pg_class
4225  * rows and replace the fake entries with them. Also, if any of the
4226  * relcache entries have rules, triggers, or security policies, load that
4227  * info the hard way since it isn't recorded in the cache file.
4228  *
4229  * Whenever we access the catalogs to read data, there is a possibility of
4230  * a shared-inval cache flush causing relcache entries to be removed.
4231  * Since hash_seq_search only guarantees to still work after the *current*
4232  * entry is removed, it's unsafe to continue the hashtable scan afterward.
4233  * We handle this by restarting the scan from scratch after each access.
4234  * This is theoretically O(N^2), but the number of entries that actually
4235  * need to be fixed is small enough that it doesn't matter.
4236  */
4237  hash_seq_init(&status, RelationIdCache);
4238 
4239  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
4240  {
4241  Relation relation = idhentry->reldesc;
4242  bool restart = false;
4243 
4244  /*
4245  * Make sure *this* entry doesn't get flushed while we work with it.
4246  */
4248 
4249  /*
4250  * If it's a faked-up entry, read the real pg_class tuple.
4251  */
4252  if (relation->rd_rel->relowner == InvalidOid)
4253  {
4254  HeapTuple htup;
4255  Form_pg_class relp;
4256 
4257  htup = SearchSysCache1(RELOID,
4258  ObjectIdGetDatum(RelationGetRelid(relation)));
4259  if (!HeapTupleIsValid(htup))
4260  ereport(FATAL,
4261  errcode(ERRCODE_UNDEFINED_OBJECT),
4262  errmsg_internal("cache lookup failed for relation %u",
4263  RelationGetRelid(relation)));
4264  relp = (Form_pg_class) GETSTRUCT(htup);
4265 
4266  /*
4267  * Copy tuple to relation->rd_rel. (See notes in
4268  * AllocateRelationDesc())
4269  */
4270  memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
4271 
4272  /* Update rd_options while we have the tuple */
4273  if (relation->rd_options)
4274  pfree(relation->rd_options);
4275  RelationParseRelOptions(relation, htup);
4276 
4277  /*
4278  * Check the values in rd_att were set up correctly. (We cannot
4279  * just copy them over now: formrdesc must have set up the rd_att
4280  * data correctly to start with, because it may already have been
4281  * copied into one or more catcache entries.)
4282  */
4283  Assert(relation->rd_att->tdtypeid == relp->reltype);
4284  Assert(relation->rd_att->tdtypmod == -1);
4285 
4286  ReleaseSysCache(htup);
4287 
4288  /* relowner had better be OK now, else we'll loop forever */
4289  if (relation->rd_rel->relowner == InvalidOid)
4290  elog(ERROR, "invalid relowner in pg_class entry for \"%s\"",
4291  RelationGetRelationName(relation));
4292 
4293  restart = true;
4294  }
4295 
4296  /*
4297  * Fix data that isn't saved in relcache cache file.
4298  *
4299  * relhasrules or relhastriggers could possibly be wrong or out of
4300  * date. If we don't actually find any rules or triggers, clear the
4301  * local copy of the flag so that we don't get into an infinite loop
4302  * here. We don't make any attempt to fix the pg_class entry, though.
4303  */
4304  if (relation->rd_rel->relhasrules && relation->rd_rules == NULL)
4305  {
4306  RelationBuildRuleLock(relation);
4307  if (relation->rd_rules == NULL)
4308  relation->rd_rel->relhasrules = false;
4309  restart = true;
4310  }
4311  if (relation->rd_rel->relhastriggers && relation->trigdesc == NULL)
4312  {
4313  RelationBuildTriggers(relation);
4314  if (relation->trigdesc == NULL)
4315  relation->rd_rel->relhastriggers = false;
4316  restart = true;
4317  }
4318 
4319  /*
4320  * Re-load the row security policies if the relation has them, since
4321  * they are not preserved in the cache. Note that we can never NOT
4322  * have a policy while relrowsecurity is true,
4323  * RelationBuildRowSecurity will create a single default-deny policy
4324  * if there is no policy defined in pg_policy.
4325  */
4326  if (relation->rd_rel->relrowsecurity && relation->rd_rsdesc == NULL)
4327  {
4328  RelationBuildRowSecurity(relation);
4329 
4330  Assert(relation->rd_rsdesc != NULL);
4331  restart = true;
4332  }
4333 
4334  /* Reload tableam data if needed */
4335  if (relation->rd_tableam == NULL &&
4336  (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind) || relation->rd_rel->relkind == RELKIND_SEQUENCE))
4337  {
4339  Assert(relation->rd_tableam != NULL);
4340 
4341  restart = true;
4342  }
4343 
4344  /* Release hold on the relation */
4346 
4347  /* Now, restart the hashtable scan if needed */
4348  if (restart)
4349  {
4350  hash_seq_term(&status);
4351  hash_seq_init(&status, RelationIdCache);
4352  }
4353  }
4354 
4355  /*
4356  * Lastly, write out new relcache cache files if needed. We don't bother
4357  * to distinguish cases where only one of the two needs an update.
4358  */
4359  if (needNewCacheFile)
4360  {
4361  /*
4362  * Force all the catcaches to finish initializing and thereby open the
4363  * catalogs and indexes they use. This will preload the relcache with
4364  * entries for all the most important system catalogs and indexes, so
4365  * that the init files will be most useful for future backends.
4366  */
4368 
4369  /* now write the files */
4371  write_relcache_init_file(false);
4372  }
4373 }
4374 
4375 /*
4376  * Load one critical system index into the relcache
4377  *
4378  * indexoid is the OID of the target index, heapoid is the OID of the catalog
4379  * it belongs to.
4380  */
4381 static void
4382 load_critical_index(Oid indexoid, Oid heapoid)
4383 {
4384  Relation ird;
4385 
4386  /*
4387  * We must lock the underlying catalog before locking the index to avoid
4388  * deadlock, since RelationBuildDesc might well need to read the catalog,
4389  * and if anyone else is exclusive-locking this catalog and index they'll
4390  * be doing it in that order.
4391  */
4392  LockRelationOid(heapoid, AccessShareLock);
4393  LockRelationOid(indexoid, AccessShareLock);
4394  ird = RelationBuildDesc(indexoid, true);
4395  if (ird == NULL)
4396  ereport(PANIC,
4398  errmsg_internal("could not open critical system index %u", indexoid));
4399  ird->rd_isnailed = true;
4400  ird->rd_refcnt = 1;
4403 
4404  (void) RelationGetIndexAttOptions(ird, false);
4405 }
4406 
4407 /*
4408  * GetPgClassDescriptor -- get a predefined tuple descriptor for pg_class
4409  * GetPgIndexDescriptor -- get a predefined tuple descriptor for pg_index
4410  *
4411  * We need this kluge because we have to be able to access non-fixed-width
4412  * fields of pg_class and pg_index before we have the standard catalog caches
4413  * available. We use predefined data that's set up in just the same way as
4414  * the bootstrapped reldescs used by formrdesc(). The resulting tupdesc is
4415  * not 100% kosher: it does not have the correct rowtype OID in tdtypeid, nor
4416  * does it have a TupleConstr field. But it's good enough for the purpose of
4417  * extracting fields.
4418  */
4419 static TupleDesc
4421 {
4422  TupleDesc result;
4423  MemoryContext oldcxt;
4424  int i;
4425 
4427 
4428  result = CreateTemplateTupleDesc(natts);
4429  result->tdtypeid = RECORDOID; /* not right, but we don't care */
4430  result->tdtypmod = -1;
4431 
4432  for (i = 0; i < natts; i++)
4433  {
4434  memcpy(TupleDescAttr(result, i), &attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
4435  /* make sure attcacheoff is valid */
4436  TupleDescAttr(result, i)->attcacheoff = -1;
4437  }
4438 
4439  /* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
4440  TupleDescAttr(result, 0)->attcacheoff = 0;
4441 
4442  /* Note: we don't bother to set up a TupleConstr entry */
4443 
4444  MemoryContextSwitchTo(oldcxt);
4445 
4446  return result;
4447 }
4448 
4449 static TupleDesc
4451 {
4452  static TupleDesc pgclassdesc = NULL;
4453 
4454  /* Already done? */
4455  if (pgclassdesc == NULL)
4456  pgclassdesc = BuildHardcodedDescriptor(Natts_pg_class,
4457  Desc_pg_class);
4458 
4459  return pgclassdesc;
4460 }
4461 
4462 static TupleDesc
4464 {
4465  static TupleDesc pgindexdesc = NULL;
4466 
4467  /* Already done? */
4468  if (pgindexdesc == NULL)
4469  pgindexdesc = BuildHardcodedDescriptor(Natts_pg_index,
4470  Desc_pg_index);
4471 
4472  return pgindexdesc;
4473 }
4474 
4475 /*
4476  * Load any default attribute value definitions for the relation.
4477  *
4478  * ndef is the number of attributes that were marked atthasdef.
4479  *
4480  * Note: we don't make it a hard error to be missing some pg_attrdef records.
4481  * We can limp along as long as nothing needs to use the default value. Code
4482  * that fails to find an expected AttrDefault record should throw an error.
4483  */
4484 static void
4485 AttrDefaultFetch(Relation relation, int ndef)
4486 {
4487  AttrDefault *attrdef;
4488  Relation adrel;
4489  SysScanDesc adscan;
4490  ScanKeyData skey;
4491  HeapTuple htup;
4492  int found = 0;
4493 
4494  /* Allocate array with room for as many entries as expected */
4495  attrdef = (AttrDefault *)
4497  ndef * sizeof(AttrDefault));
4498 
4499  /* Search pg_attrdef for relevant entries */
4500  ScanKeyInit(&skey,
4501  Anum_pg_attrdef_adrelid,
4502  BTEqualStrategyNumber, F_OIDEQ,
4503  ObjectIdGetDatum(RelationGetRelid(relation)));
4504 
4505  adrel = table_open(AttrDefaultRelationId, AccessShareLock);
4506  adscan = systable_beginscan(adrel, AttrDefaultIndexId, true,
4507  NULL, 1, &skey);
4508 
4509  while (HeapTupleIsValid(htup = systable_getnext(adscan)))
4510  {
4511  Form_pg_attrdef adform = (Form_pg_attrdef) GETSTRUCT(htup);
4512  Datum val;
4513  bool isnull;
4514 
4515  /* protect limited size of array */
4516  if (found >= ndef)
4517  {
4518  elog(WARNING, "unexpected pg_attrdef record found for attribute %d of relation \"%s\"",
4519  adform->adnum, RelationGetRelationName(relation));
4520  break;
4521  }
4522 
4523  val = fastgetattr(htup,
4524  Anum_pg_attrdef_adbin,
4525  adrel->rd_att, &isnull);
4526  if (isnull)
4527  elog(WARNING, "null adbin for attribute %d of relation \"%s\"",
4528  adform->adnum, RelationGetRelationName(relation));
4529  else
4530  {
4531  /* detoast and convert to cstring in caller's context */
4532  char *s = TextDatumGetCString(val);
4533 
4534  attrdef[found].adnum = adform->adnum;
4535  attrdef[found].adbin = MemoryContextStrdup(CacheMemoryContext, s);
4536  pfree(s);
4537  found++;
4538  }
4539  }
4540 
4541  systable_endscan(adscan);
4542  table_close(adrel, AccessShareLock);
4543 
4544  if (found != ndef)
4545  elog(WARNING, "%d pg_attrdef record(s) missing for relation \"%s\"",
4546  ndef - found, RelationGetRelationName(relation));
4547 
4548  /*
4549  * Sort the AttrDefault entries by adnum, for the convenience of
4550  * equalTupleDescs(). (Usually, they already will be in order, but this
4551  * might not be so if systable_getnext isn't using an index.)
4552  */
4553  if (found > 1)
4554  qsort(attrdef, found, sizeof(AttrDefault), AttrDefaultCmp);
4555 
4556  /* Install array only after it's fully valid */
4557  relation->rd_att->constr->defval = attrdef;
4558  relation->rd_att->constr->num_defval = found;
4559 }
4560 
4561 /*
4562  * qsort comparator to sort AttrDefault entries by adnum
4563  */
4564 static int
4565 AttrDefaultCmp(const void *a, const void *b)
4566 {
4567  const AttrDefault *ada = (const AttrDefault *) a;
4568  const AttrDefault *adb = (const AttrDefault *) b;
4569 
4570  return pg_cmp_s16(ada->adnum, adb->adnum);
4571 }
4572 
4573 /*
4574  * Load any check constraints for the relation.
4575  *
4576  * As with defaults, if we don't find the expected number of them, just warn
4577  * here. The executor should throw an error if an INSERT/UPDATE is attempted.
4578  */
4579 static void
4581 {
4582  ConstrCheck *check;
4583  int ncheck = relation->rd_rel->relchecks;
4584  Relation conrel;
4585  SysScanDesc conscan;
4586  ScanKeyData skey[1];
4587  HeapTuple htup;
4588  int found = 0;
4589 
4590  /* Allocate array with room for as many entries as expected */
4591  check = (ConstrCheck *)
4593  ncheck * sizeof(ConstrCheck));
4594 
4595  /* Search pg_constraint for relevant entries */
4596  ScanKeyInit(&skey[0],
4597  Anum_pg_constraint_conrelid,
4598  BTEqualStrategyNumber, F_OIDEQ,
4599  ObjectIdGetDatum(RelationGetRelid(relation)));
4600 
4601  conrel = table_open(ConstraintRelationId, AccessShareLock);
4602  conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true,
4603  NULL, 1, skey);
4604 
4605  while (HeapTupleIsValid(htup = systable_getnext(conscan)))
4606  {
4608  Datum val;
4609  bool isnull;
4610 
4611  /* We want check constraints only */
4612  if (conform->contype != CONSTRAINT_CHECK)
4613  continue;
4614 
4615  /* protect limited size of array */
4616  if (found >= ncheck)
4617  {
4618  elog(WARNING, "unexpected pg_constraint record found for relation \"%s\"",
4619  RelationGetRelationName(relation));
4620  break;
4621  }
4622 
4623  check[found].ccvalid = conform->convalidated;
4624  check[found].ccnoinherit = conform->connoinherit;
4626  NameStr(conform->conname));
4627 
4628  /* Grab and test conbin is actually set */
4629  val = fastgetattr(htup,
4630  Anum_pg_constraint_conbin,
4631  conrel->rd_att, &isnull);
4632  if (isnull)
4633  elog(WARNING, "null conbin for relation \"%s\"",
4634  RelationGetRelationName(relation));
4635  else
4636  {
4637  /* detoast and convert to cstring in caller's context */
4638  char *s = TextDatumGetCString(val);
4639 
4640  check[found].ccbin = MemoryContextStrdup(CacheMemoryContext, s);
4641  pfree(s);
4642  found++;
4643  }
4644  }
4645 
4646  systable_endscan(conscan);
4647  table_close(conrel, AccessShareLock);
4648 
4649  if (found != ncheck)
4650  elog(WARNING, "%d pg_constraint record(s) missing for relation \"%s\"",
4651  ncheck - found, RelationGetRelationName(relation));
4652 
4653  /*
4654  * Sort the records by name. This ensures that CHECKs are applied in a
4655  * deterministic order, and it also makes equalTupleDescs() faster.
4656  */
4657  if (found > 1)
4658  qsort(check, found, sizeof(ConstrCheck), CheckConstraintCmp);
4659 
4660  /* Install array only after it's fully valid */
4661  relation->rd_att->constr->check = check;
4662  relation->rd_att->constr->num_check = found;
4663 }
4664 
4665 /*
4666  * qsort comparator to sort ConstrCheck entries by name
4667  */
4668 static int
4669 CheckConstraintCmp(const void *a, const void *b)
4670 {
4671  const ConstrCheck *ca = (const ConstrCheck *) a;
4672  const ConstrCheck *cb = (const ConstrCheck *) b;
4673 
4674  return strcmp(ca->ccname, cb->ccname);
4675 }
4676 
4677 /*
4678  * RelationGetFKeyList -- get a list of foreign key info for the relation
4679  *
4680  * Returns a list of ForeignKeyCacheInfo structs, one per FK constraining
4681  * the given relation. This data is a direct copy of relevant fields from
4682  * pg_constraint. The list items are in no particular order.
4683  *
4684  * CAUTION: the returned list is part of the relcache's data, and could
4685  * vanish in a relcache entry reset. Callers must inspect or copy it
4686  * before doing anything that might trigger a cache flush, such as
4687  * system catalog accesses. copyObject() can be used if desired.
4688  * (We define it this way because current callers want to filter and
4689  * modify the list entries anyway, so copying would be a waste of time.)
4690  */
4691 List *
4693 {
4694  List *result;
4695  Relation conrel;
4696  SysScanDesc conscan;
4697  ScanKeyData skey;
4698  HeapTuple htup;
4699  List *oldlist;
4700  MemoryContext oldcxt;
4701 
4702  /* Quick exit if we already computed the list. */
4703  if (relation->rd_fkeyvalid)
4704  return relation->rd_fkeylist;
4705 
4706  /* Fast path: non-partitioned tables without triggers can't have FKs */
4707  if (!relation->rd_rel->relhastriggers &&
4708  relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
4709  return NIL;
4710 
4711  /*
4712  * We build the list we intend to return (in the caller's context) while
4713  * doing the scan. After successfully completing the scan, we copy that
4714  * list into the relcache entry. This avoids cache-context memory leakage
4715  * if we get some sort of error partway through.
4716  */
4717  result = NIL;
4718 
4719  /* Prepare to scan pg_constraint for entries having conrelid = this rel. */
4720  ScanKeyInit(&skey,
4721  Anum_pg_constraint_conrelid,
4722  BTEqualStrategyNumber, F_OIDEQ,
4723  ObjectIdGetDatum(RelationGetRelid(relation)));
4724 
4725  conrel = table_open(ConstraintRelationId, AccessShareLock);
4726  conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true,
4727  NULL, 1, &skey);
4728 
4729  while (HeapTupleIsValid(htup = systable_getnext(conscan)))
4730  {
4731  Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup);
4732  ForeignKeyCacheInfo *info;
4733 
4734  /* consider only foreign keys */
4735  if (constraint->contype != CONSTRAINT_FOREIGN)
4736  continue;
4737 
4738  info = makeNode(ForeignKeyCacheInfo);
4739  info->conoid = constraint->oid;
4740  info->conrelid = constraint->conrelid;
4741  info->confrelid = constraint->confrelid;
4742 
4743  DeconstructFkConstraintRow(htup, &info->nkeys,
4744  info->conkey,
4745  info->confkey,
4746  info->conpfeqop,
4747  NULL, NULL, NULL, NULL);
4748 
4749  /* Add FK's node to the result list */
4750  result = lappend(result, info);
4751  }
4752 
4753  systable_endscan(conscan);
4754  table_close(conrel, AccessShareLock);
4755 
4756  /* Now save a copy of the completed list in the relcache entry. */
4758  oldlist = relation->rd_fkeylist;
4759  relation->rd_fkeylist = copyObject(result);
4760  relation->rd_fkeyvalid = true;
4761  MemoryContextSwitchTo(oldcxt);
4762 
4763  /* Don't leak the old list, if there is one */
4764  list_free_deep(oldlist);
4765 
4766  return result;
4767 }
4768 
4769 /*
4770  * RelationGetIndexList -- get a list of OIDs of indexes on this relation
4771  *
4772  * The index list is created only if someone requests it. We scan pg_index
4773  * to find relevant indexes, and add the list to the relcache entry so that
4774  * we won't have to compute it again. Note that shared cache inval of a
4775  * relcache entry will delete the old list and set rd_indexvalid to false,
4776  * so that we must recompute the index list on next request. This handles
4777  * creation or deletion of an index.
4778  *
4779  * Indexes that are marked not indislive are omitted from the returned list.
4780  * Such indexes are expected to be dropped momentarily, and should not be
4781  * touched at all by any caller of this function.
4782  *
4783  * The returned list is guaranteed to be sorted in order by OID. This is
4784  * needed by the executor, since for index types that we obtain exclusive
4785  * locks on when updating the index, all backends must lock the indexes in
4786  * the same order or we will get deadlocks (see ExecOpenIndices()). Any
4787  * consistent ordering would do, but ordering by OID is easy.
4788  *
4789  * Since shared cache inval causes the relcache's copy of the list to go away,
4790  * we return a copy of the list palloc'd in the caller's context. The caller
4791  * may list_free() the returned list after scanning it. This is necessary
4792  * since the caller will typically be doing syscache lookups on the relevant
4793  * indexes, and syscache lookup could cause SI messages to be processed!
4794  *
4795  * In exactly the same way, we update rd_pkindex, which is the OID of the
4796  * relation's primary key index if any, else InvalidOid; and rd_replidindex,
4797  * which is the pg_class OID of an index to be used as the relation's
4798  * replication identity index, or InvalidOid if there is no such index.
4799  */
4800 List *
4802 {
4803  Relation indrel;
4804  SysScanDesc indscan;
4805  ScanKeyData skey;
4806  HeapTuple htup;
4807  List *result;
4808  List *oldlist;
4809  char replident = relation->rd_rel->relreplident;
4810  Oid pkeyIndex = InvalidOid;
4811  Oid candidateIndex = InvalidOid;
4812  bool pkdeferrable = false;
4813  MemoryContext oldcxt;
4814 
4815  /* Quick exit if we already computed the list. */
4816  if (relation->rd_indexvalid)
4817  return list_copy(relation->rd_indexlist);
4818 
4819  /*
4820  * We build the list we intend to return (in the caller's context) while
4821  * doing the scan. After successfully completing the scan, we copy that
4822  * list into the relcache entry. This avoids cache-context memory leakage
4823  * if we get some sort of error partway through.
4824  */
4825  result = NIL;
4826 
4827  /* Prepare to scan pg_index for entries having indrelid = this rel. */
4828  ScanKeyInit(&skey,
4829  Anum_pg_index_indrelid,
4830  BTEqualStrategyNumber, F_OIDEQ,
4831  ObjectIdGetDatum(RelationGetRelid(relation)));
4832 
4833  indrel = table_open(IndexRelationId, AccessShareLock);
4834  indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true,
4835  NULL, 1, &skey);
4836 
4837  while (HeapTupleIsValid(htup = systable_getnext(indscan)))
4838  {
4840 
4841  /*
4842  * Ignore any indexes that are currently being dropped. This will
4843  * prevent them from being searched, inserted into, or considered in
4844  * HOT-safety decisions. It's unsafe to touch such an index at all
4845  * since its catalog entries could disappear at any instant.
4846  */
4847  if (!index->indislive)
4848  continue;
4849 
4850  /* add index's OID to result list */
4851  result = lappend_oid(result, index->indexrelid);
4852 
4853  /*
4854  * Invalid, non-unique, non-immediate or predicate indexes aren't
4855  * interesting for either oid indexes or replication identity indexes,
4856  * so don't check them.
4857  */
4858  if (!index->indisvalid || !index->indisunique ||
4859  !index->indimmediate ||
4860  !heap_attisnull(htup, Anum_pg_index_indpred, NULL))
4861  continue;
4862 
4863  /* remember primary key index if any */
4864  if (index->indisprimary)
4865  pkeyIndex = index->indexrelid;
4866 
4867  /* remember explicitly chosen replica index */
4868  if (index->indisreplident)
4869  candidateIndex = index->indexrelid;
4870  }
4871 
4872  systable_endscan(indscan);
4873 
4874  table_close(indrel, AccessShareLock);
4875 
4876  /* Sort the result list into OID order, per API spec. */
4877  list_sort(result, list_oid_cmp);
4878 
4879  /* Now save a copy of the completed list in the relcache entry. */
4881  oldlist = relation->rd_indexlist;
4882  relation->rd_indexlist = list_copy(result);
4883  relation->rd_pkindex = pkeyIndex;
4884  relation->rd_ispkdeferrable = pkdeferrable;
4885  if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
4886  relation->rd_replidindex = pkeyIndex;
4887  else if (replident == REPLICA_IDENTITY_INDEX && OidIsValid(candidateIndex))
4888  relation->rd_replidindex = candidateIndex;
4889  else
4890  relation->rd_replidindex = InvalidOid;
4891  relation->rd_indexvalid = true;
4892  MemoryContextSwitchTo(oldcxt);
4893 
4894  /* Don't leak the old list, if there is one */
4895  list_free(oldlist);
4896 
4897  return result;
4898 }
4899 
4900 /*
4901  * RelationGetStatExtList
4902  * get a list of OIDs of statistics objects on this relation
4903  *
4904  * The statistics list is created only if someone requests it, in a way
4905  * similar to RelationGetIndexList(). We scan pg_statistic_ext to find
4906  * relevant statistics, and add the list to the relcache entry so that we
4907  * won't have to compute it again. Note that shared cache inval of a
4908  * relcache entry will delete the old list and set rd_statvalid to 0,
4909  * so that we must recompute the statistics list on next request. This
4910  * handles creation or deletion of a statistics object.
4911  *
4912  * The returned list is guaranteed to be sorted in order by OID, although
4913  * this is not currently needed.
4914  *
4915  * Since shared cache inval causes the relcache's copy of the list to go away,
4916  * we return a copy of the list palloc'd in the caller's context. The caller
4917  * may list_free() the returned list after scanning it. This is necessary
4918  * since the caller will typically be doing syscache lookups on the relevant
4919  * statistics, and syscache lookup could cause SI messages to be processed!
4920  */
4921 List *
4923 {
4924  Relation indrel;
4925  SysScanDesc indscan;
4926  ScanKeyData skey;
4927  HeapTuple htup;
4928  List *result;
4929  List *oldlist;
4930  MemoryContext oldcxt;
4931 
4932  /* Quick exit if we already computed the list. */
4933  if (relation->rd_statvalid != 0)
4934  return list_copy(relation->rd_statlist);
4935 
4936  /*
4937  * We build the list we intend to return (in the caller's context) while
4938  * doing the scan. After successfully completing the scan, we copy that
4939  * list into the relcache entry. This avoids cache-context memory leakage
4940  * if we get some sort of error partway through.
4941  */
4942  result = NIL;
4943 
4944  /*
4945  * Prepare to scan pg_statistic_ext for entries having stxrelid = this
4946  * rel.
4947  */
4948  ScanKeyInit(&skey,
4949  Anum_pg_statistic_ext_stxrelid,
4950  BTEqualStrategyNumber, F_OIDEQ,
4951  ObjectIdGetDatum(RelationGetRelid(relation)));
4952 
4953  indrel = table_open(StatisticExtRelationId, AccessShareLock);
4954  indscan = systable_beginscan(indrel, StatisticExtRelidIndexId, true,
4955  NULL, 1, &skey);
4956 
4957  while (HeapTupleIsValid(htup = systable_getnext(indscan)))
4958  {
4959  Oid oid = ((Form_pg_statistic_ext) GETSTRUCT(htup))->oid;
4960 
4961  result = lappend_oid(result, oid);
4962  }
4963 
4964  systable_endscan(indscan);
4965 
4966  table_close(indrel, AccessShareLock);
4967 
4968  /* Sort the result list into OID order, per API spec. */
4969  list_sort(result, list_oid_cmp);
4970 
4971  /* Now save a copy of the completed list in the relcache entry. */
4973  oldlist = relation->rd_statlist;
4974  relation->rd_statlist = list_copy(result);
4975 
4976  relation->rd_statvalid = true;
4977  MemoryContextSwitchTo(oldcxt);
4978 
4979  /* Don't leak the old list, if there is one */
4980  list_free(oldlist);
4981 
4982  return result;
4983 }
4984 
4985 /*
4986  * RelationGetPrimaryKeyIndex -- get OID of the relation's primary key index
4987  *
4988  * Returns InvalidOid if there is no such index, or if the primary key is
4989  * DEFERRABLE.
4990  */
4991 Oid
4993 {
4994  List *ilist;
4995 
4996  if (!relation->rd_indexvalid)
4997  {
4998  /* RelationGetIndexList does the heavy lifting. */
4999  ilist = RelationGetIndexList(relation);
5000  list_free(ilist);
5001  Assert(relation->rd_indexvalid);
5002  }
5003 
5004  return relation->rd_ispkdeferrable ? InvalidOid : relation->rd_pkindex;
5005 }
5006 
5007 /*
5008  * RelationGetReplicaIndex -- get OID of the relation's replica identity index
5009  *
5010  * Returns InvalidOid if there is no such index.
5011  */
5012 Oid
5014 {
5015  List *ilist;
5016 
5017  if (!relation->rd_indexvalid)
5018  {
5019  /* RelationGetIndexList does the heavy lifting. */
5020  ilist = RelationGetIndexList(relation);
5021  list_free(ilist);
5022  Assert(relation->rd_indexvalid);
5023  }
5024 
5025  return relation->rd_replidindex;
5026 }
5027 
5028 /*
5029  * RelationGetIndexExpressions -- get the index expressions for an index
5030  *
5031  * We cache the result of transforming pg_index.indexprs into a node tree.
5032  * If the rel is not an index or has no expressional columns, we return NIL.
5033  * Otherwise, the returned tree is copied into the caller's memory context.
5034  * (We don't want to return a pointer to the relcache copy, since it could
5035  * disappear due to relcache invalidation.)
5036  */
5037 List *
5039 {
5040  List *result;
5041  Datum exprsDatum;
5042  bool isnull;
5043  char *exprsString;
5044  MemoryContext oldcxt;
5045 
5046  /* Quick exit if we already computed the result. */
5047  if (relation->rd_indexprs)
5048  return copyObject(relation->rd_indexprs);
5049 
5050  /* Quick exit if there is nothing to do. */
5051  if (relation->rd_indextuple == NULL ||
5052  heap_attisnull(relation->rd_indextuple, Anum_pg_index_indexprs, NULL))
5053  return NIL;
5054 
5055  /*
5056  * We build the tree we intend to return in the caller's context. After
5057  * successfully completing the work, we copy it into the relcache entry.
5058  * This avoids problems if we get some sort of error partway through.
5059  */
5060  exprsDatum = heap_getattr(relation->rd_indextuple,
5061  Anum_pg_index_indexprs,
5063  &isnull);
5064  Assert(!isnull);
5065  exprsString = TextDatumGetCString(exprsDatum);
5066  result = (List *) stringToNode(exprsString);
5067  pfree(exprsString);
5068 
5069  /*
5070  * Run the expressions through eval_const_expressions. This is not just an
5071  * optimization, but is necessary, because the planner will be comparing
5072  * them to similarly-processed qual clauses, and may fail to detect valid
5073  * matches without this. We must not use canonicalize_qual, however,
5074  * since these aren't qual expressions.
5075  */
5076  result = (List *) eval_const_expressions(NULL, (Node *) result);
5077 
5078  /* May as well fix opfuncids too */
5079  fix_opfuncids((Node *) result);
5080 
5081  /* Now save a copy of the completed tree in the relcache entry. */
5082  oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt);
5083  relation->rd_indexprs = copyObject(result);
5084  MemoryContextSwitchTo(oldcxt);
5085 
5086  return result;
5087 }
5088 
5089 /*
5090  * RelationGetDummyIndexExpressions -- get dummy expressions for an index
5091  *
5092  * Return a list of dummy expressions (just Const nodes) with the same
5093  * types/typmods/collations as the index's real expressions. This is
5094  * useful in situations where we don't want to run any user-defined code.
5095  */
5096 List *
5098 {
5099  List *result;
5100  Datum exprsDatum;
5101  bool isnull;
5102  char *exprsString;
5103  List *rawExprs;
5104  ListCell *lc;
5105 
5106  /* Quick exit if there is nothing to do. */
5107  if (relation->rd_indextuple == NULL ||
5108  heap_attisnull(relation->rd_indextuple, Anum_pg_index_indexprs, NULL))
5109  return NIL;
5110 
5111  /* Extract raw node tree(s) from index tuple. */
5112  exprsDatum = heap_getattr(relation->rd_indextuple,
5113  Anum_pg_index_indexprs,
5115  &isnull);
5116  Assert(!isnull);
5117  exprsString = TextDatumGetCString(exprsDatum);
5118  rawExprs = (List *) stringToNode(exprsString);
5119  pfree(exprsString);
5120 
5121  /* Construct null Consts; the typlen and typbyval are arbitrary. */
5122  result = NIL;
5123  foreach(lc, rawExprs)
5124  {
5125  Node *rawExpr = (Node *) lfirst(lc);
5126 
5127  result = lappend(result,
5128  makeConst(exprType(rawExpr),
5129  exprTypmod(rawExpr),
5130  exprCollation(rawExpr),
5131  1,
5132  (Datum) 0,
5133  true,
5134  true));
5135  }
5136 
5137  return result;
5138 }
5139 
5140 /*
5141  * RelationGetIndexPredicate -- get the index predicate for an index
5142  *
5143  * We cache the result of transforming pg_index.indpred into an implicit-AND
5144  * node tree (suitable for use in planning).
5145  * If the rel is not an index or has no predicate, we return NIL.
5146  * Otherwise, the returned tree is copied into the caller's memory context.
5147  * (We don't want to return a pointer to the relcache copy, since it could
5148  * disappear due to relcache invalidation.)
5149  */
5150 List *
5152 {
5153  List *result;
5154  Datum predDatum;
5155  bool isnull;
5156  char *predString;
5157  MemoryContext oldcxt;
5158 
5159  /* Quick exit if we already computed the result. */
5160  if (relation->rd_indpred)
5161  return copyObject(relation->rd_indpred);
5162 
5163  /* Quick exit if there is nothing to do. */
5164  if (relation->rd_indextuple == NULL ||
5165  heap_attisnull(relation->rd_indextuple, Anum_pg_index_indpred, NULL))
5166  return NIL;
5167 
5168  /*
5169  * We build the tree we intend to return in the caller's context. After
5170  * successfully completing the work, we copy it into the relcache entry.
5171  * This avoids problems if we get some sort of error partway through.
5172  */
5173  predDatum = heap_getattr(relation->rd_indextuple,
5174  Anum_pg_index_indpred,
5176  &isnull);
5177  Assert(!isnull);
5178  predString = TextDatumGetCString(predDatum);
5179  result = (List *) stringToNode(predString);
5180  pfree(predString);
5181 
5182  /*
5183  * Run the expression through const-simplification and canonicalization.
5184  * This is not just an optimization, but is necessary, because the planner
5185  * will be comparing it to similarly-processed qual clauses, and may fail
5186  * to detect valid matches without this. This must match the processing
5187  * done to qual clauses in preprocess_expression()! (We can skip the
5188  * stuff involving subqueries, however, since we don't allow any in index
5189  * predicates.)
5190  */
5191  result = (List *) eval_const_expressions(NULL, (Node *) result);
5192 
5193  result = (List *) canonicalize_qual((Expr *) result, false);
5194 
5195  /* Also convert to implicit-AND format */
5196  result = make_ands_implicit((Expr *) result);
5197 
5198  /* May as well fix opfuncids too */
5199  fix_opfuncids((Node *) result);
5200 
5201  /* Now save a copy of the completed tree in the relcache entry. */
5202  oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt);
5203  relation->rd_indpred = copyObject(result);
5204  MemoryContextSwitchTo(oldcxt);
5205 
5206  return result;
5207 }
5208 
5209 /*
5210  * RelationGetIndexAttrBitmap -- get a bitmap of index attribute numbers
5211  *
5212  * The result has a bit set for each attribute used anywhere in the index
5213  * definitions of all the indexes on this relation. (This includes not only
5214  * simple index keys, but attributes used in expressions and partial-index
5215  * predicates.)
5216  *
5217  * Depending on attrKind, a bitmap covering attnums for certain columns is
5218  * returned:
5219  * INDEX_ATTR_BITMAP_KEY Columns in non-partial unique indexes not
5220  * in expressions (i.e., usable for FKs)
5221  * INDEX_ATTR_BITMAP_PRIMARY_KEY Columns in the table's primary key
5222  * (beware: even if PK is deferrable!)
5223  * INDEX_ATTR_BITMAP_IDENTITY_KEY Columns in the table's replica identity
5224  * index (empty if FULL)
5225  * INDEX_ATTR_BITMAP_HOT_BLOCKING Columns that block updates from being HOT
5226  * INDEX_ATTR_BITMAP_SUMMARIZED Columns included in summarizing indexes
5227  *
5228  * Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that
5229  * we can include system attributes (e.g., OID) in the bitmap representation.
5230  *
5231  * Deferred indexes are considered for the primary key, but not for replica
5232  * identity.
5233  *
5234  * Caller had better hold at least RowExclusiveLock on the target relation
5235  * to ensure it is safe (deadlock-free) for us to take locks on the relation's
5236  * indexes. Note that since the introduction of CREATE INDEX CONCURRENTLY,
5237  * that lock level doesn't guarantee a stable set of indexes, so we have to
5238  * be prepared to retry here in case of a change in the set of indexes.
5239  *
5240  * The returned result is palloc'd in the caller's memory context and should
5241  * be bms_free'd when not needed anymore.
5242  */
5243 Bitmapset *
5245 {
5246  Bitmapset *uindexattrs; /* columns in unique indexes */
5247  Bitmapset *pkindexattrs; /* columns in the primary index */
5248  Bitmapset *idindexattrs; /* columns in the replica identity */
5249  Bitmapset *hotblockingattrs; /* columns with HOT blocking indexes */
5250  Bitmapset *summarizedattrs; /* columns with summarizing indexes */
5251  List *indexoidlist;
5252  List *newindexoidlist;
5253  Oid relpkindex;
5254  Oid relreplindex;
5255  ListCell *l;
5256  MemoryContext oldcxt;
5257 
5258  /* Quick exit if we already computed the result. */
5259  if (relation->rd_attrsvalid)
5260  {
5261  switch (attrKind)
5262  {
5263  case INDEX_ATTR_BITMAP_KEY:
5264  return bms_copy(relation->rd_keyattr);
5266  return bms_copy(relation->rd_pkattr);
5268  return bms_copy(relation->rd_idattr);
5270  return bms_copy(relation->rd_hotblockingattr);
5272  return bms_copy(relation->rd_summarizedattr);
5273  default:
5274  elog(ERROR, "unknown attrKind %u", attrKind);
5275  }
5276  }
5277 
5278  /* Fast path if definitely no indexes */
5279  if (!RelationGetForm(relation)->relhasindex)
5280  return NULL;
5281 
5282  /*
5283  * Get cached list of index OIDs. If we have to start over, we do so here.
5284  */
5285 restart:
5286  indexoidlist = RelationGetIndexList(relation);
5287 
5288  /* Fall out if no indexes (but relhasindex was set) */
5289  if (indexoidlist == NIL)
5290  return NULL;
5291 
5292  /*
5293  * Copy the rd_pkindex and rd_replidindex values computed by
5294  * RelationGetIndexList before proceeding. This is needed because a
5295  * relcache flush could occur inside index_open below, resetting the
5296  * fields managed by RelationGetIndexList. We need to do the work with
5297  * stable values of these fields.
5298  */
5299  relpkindex = relation->rd_pkindex;
5300  relreplindex = relation->rd_replidindex;
5301 
5302  /*
5303  * For each index, add referenced attributes to indexattrs.
5304  *
5305  * Note: we consider all indexes returned by RelationGetIndexList, even if
5306  * they are not indisready or indisvalid. This is important because an
5307  * index for which CREATE INDEX CONCURRENTLY has just started must be
5308  * included in HOT-safety decisions (see README.HOT). If a DROP INDEX
5309  * CONCURRENTLY is far enough along that we should ignore the index, it
5310  * won't be returned at all by RelationGetIndexList.
5311  */
5312  uindexattrs = NULL;
5313  pkindexattrs = NULL;
5314  idindexattrs = NULL;
5315  hotblockingattrs = NULL;
5316  summarizedattrs = NULL;
5317  foreach(l, indexoidlist)
5318  {
5319  Oid indexOid = lfirst_oid(l);
5320  Relation indexDesc;
5321  Datum datum;
5322  bool isnull;
5323  Node *indexExpressions;
5324  Node *indexPredicate;
5325  int i;
5326  bool isKey; /* candidate key */
5327  bool isPK; /* primary key */
5328  bool isIDKey; /* replica identity index */
5329  Bitmapset **attrs;
5330 
5331  indexDesc = index_open(indexOid, AccessShareLock);
5332 
5333  /*
5334  * Extract index expressions and index predicate. Note: Don't use
5335  * RelationGetIndexExpressions()/RelationGetIndexPredicate(), because
5336  * those might run constant expressions evaluation, which needs a
5337  * snapshot, which we might not have here. (Also, it's probably more
5338  * sound to collect the bitmaps before any transformations that might
5339  * eliminate columns, but the practical impact of this is limited.)
5340  */
5341 
5342  datum = heap_getattr(indexDesc->rd_indextuple, Anum_pg_index_indexprs,
5343  GetPgIndexDescriptor(), &isnull);
5344  if (!isnull)
5345  indexExpressions = stringToNode(TextDatumGetCString(datum));
5346  else
5347  indexExpressions = NULL;
5348 
5349  datum = heap_getattr(indexDesc->rd_indextuple, Anum_pg_index_indpred,
5350  GetPgIndexDescriptor(), &isnull);
5351  if (!isnull)
5352  indexPredicate = stringToNode(TextDatumGetCString(datum));
5353  else
5354  indexPredicate = NULL;
5355 
5356  /* Can this index be referenced by a foreign key? */
5357  isKey = indexDesc->rd_index->indisunique &&
5358  indexExpressions == NULL &&
5359  indexPredicate == NULL;
5360 
5361  /* Is this a primary key? */
5362  isPK = (indexOid == relpkindex);
5363 
5364  /* Is this index the configured (or default) replica identity? */
5365  isIDKey = (indexOid == relreplindex);
5366 
5367  /*
5368  * If the index is summarizing, it doesn't block HOT updates, but we
5369  * may still need to update it (if the attributes were modified). So
5370  * decide which bitmap we'll update in the following loop.
5371  */
5372  if (indexDesc->rd_indam->amsummarizing)
5373  attrs = &summarizedattrs;
5374  else
5375  attrs = &hotblockingattrs;
5376 
5377  /* Collect simple attribute references */
5378  for (i = 0; i < indexDesc->rd_index->indnatts; i++)
5379  {
5380  int attrnum = indexDesc->rd_index->indkey.values[i];
5381 
5382  /*
5383  * Since we have covering indexes with non-key columns, we must
5384  * handle them accurately here. non-key columns must be added into
5385  * hotblockingattrs or summarizedattrs, since they are in index,
5386  * and update shouldn't miss them.
5387  *
5388  * Summarizing indexes do not block HOT, but do need to be updated
5389  * when the column value changes, thus require a separate
5390  * attribute bitmapset.
5391  *
5392  * Obviously, non-key columns couldn't be referenced by foreign
5393  * key or identity key. Hence we do not include them into
5394  * uindexattrs, pkindexattrs and idindexattrs bitmaps.
5395  */
5396  if (attrnum != 0)
5397  {
5398  *attrs = bms_add_member(*attrs,
5400 
5401  if (isKey && i < indexDesc->rd_index->indnkeyatts)
5402  uindexattrs = bms_add_member(uindexattrs,
5404 
5405  if (isPK && i < indexDesc->rd_index->indnkeyatts)
5406  pkindexattrs = bms_add_member(pkindexattrs,
5408 
5409  if (isIDKey && i < indexDesc->rd_index->indnkeyatts)
5410  idindexattrs = bms_add_member(idindexattrs,
5412  }
5413  }
5414 
5415  /* Collect all attributes used in expressions, too */
5416  pull_varattnos(indexExpressions, 1, attrs);
5417 
5418  /* Collect all attributes in the index predicate, too */
5419  pull_varattnos(indexPredicate, 1, attrs);
5420 
5421  index_close(indexDesc, AccessShareLock);
5422  }
5423 
5424  /*
5425  * During one of the index_opens in the above loop, we might have received
5426  * a relcache flush event on this relcache entry, which might have been
5427  * signaling a change in the rel's index list. If so, we'd better start
5428  * over to ensure we deliver up-to-date attribute bitmaps.
5429  */
5430  newindexoidlist = RelationGetIndexList(relation);
5431  if (equal(indexoidlist, newindexoidlist) &&
5432  relpkindex == relation->rd_pkindex &&
5433  relreplindex == relation->rd_replidindex)
5434  {
5435  /* Still the same index set, so proceed */
5436  list_free(newindexoidlist);
5437  list_free(indexoidlist);
5438  }
5439  else
5440  {
5441  /* Gotta do it over ... might as well not leak memory */
5442  list_free(newindexoidlist);
5443  list_free(indexoidlist);
5444  bms_free(uindexattrs);
5445  bms_free(pkindexattrs);
5446  bms_free(idindexattrs);
5447  bms_free(hotblockingattrs);
5448  bms_free(summarizedattrs);
5449 
5450  goto restart;
5451  }
5452 
5453  /* Don't leak the old values of these bitmaps, if any */
5454  relation->rd_attrsvalid = false;
5455  bms_free(relation->rd_keyattr);
5456  relation->rd_keyattr = NULL;
5457  bms_free(relation->rd_pkattr);
5458  relation->rd_pkattr = NULL;
5459  bms_free(relation->rd_idattr);
5460  relation->rd_idattr = NULL;
5461  bms_free(relation->rd_hotblockingattr);
5462  relation->rd_hotblockingattr = NULL;
5463  bms_free(relation->rd_summarizedattr);
5464  relation->rd_summarizedattr = NULL;
5465 
5466  /*
5467  * Now save copies of the bitmaps in the relcache entry. We intentionally
5468  * set rd_attrsvalid last, because that's the one that signals validity of
5469  * the values; if we run out of memory before making that copy, we won't
5470  * leave the relcache entry looking like the other ones are valid but
5471  * empty.
5472  */
5474  relation->rd_keyattr = bms_copy(uindexattrs);
5475  relation->rd_pkattr = bms_copy(pkindexattrs);
5476  relation->rd_idattr = bms_copy(idindexattrs);
5477  relation->rd_hotblockingattr = bms_copy(hotblockingattrs);
5478  relation->rd_summarizedattr = bms_copy(summarizedattrs);
5479  relation->rd_attrsvalid = true;
5480  MemoryContextSwitchTo(oldcxt);
5481 
5482  /* We return our original working copy for caller to play with */
5483  switch (attrKind)
5484  {
5485  case INDEX_ATTR_BITMAP_KEY:
5486  return uindexattrs;
5488  return pkindexattrs;
5490  return idindexattrs;
5492  return hotblockingattrs;
5494  return summarizedattrs;
5495  default:
5496  elog(ERROR, "unknown attrKind %u", attrKind);
5497  return NULL;
5498  }
5499 }
5500 
5501 /*
5502  * RelationGetIdentityKeyBitmap -- get a bitmap of replica identity attribute
5503  * numbers
5504  *
5505  * A bitmap of index attribute numbers for the configured replica identity
5506  * index is returned.
5507  *
5508  * See also comments of RelationGetIndexAttrBitmap().
5509  *
5510  * This is a special purpose function used during logical replication. Here,
5511  * unlike RelationGetIndexAttrBitmap(), we don't acquire a lock on the required
5512  * index as we build the cache entry using a historic snapshot and all the
5513  * later changes are absorbed while decoding WAL. Due to this reason, we don't
5514  * need to retry here in case of a change in the set of indexes.
5515  */
5516 Bitmapset *
5518 {
5519  Bitmapset *idindexattrs = NULL; /* columns in the replica identity */
5520  Relation indexDesc;
5521  int i;
5522  Oid replidindex;
5523  MemoryContext oldcxt;
5524 
5525  /* Quick exit if we already computed the result */
5526  if (relation->rd_idattr != NULL)
5527  return bms_copy(relation->rd_idattr);
5528 
5529  /* Fast path if definitely no indexes */
5530  if (!RelationGetForm(relation)->relhasindex)
5531  return NULL;
5532 
5533  /* Historic snapshot must be set. */
5535 
5536  replidindex = RelationGetReplicaIndex(relation);
5537 
5538  /* Fall out if there is no replica identity index */
5539  if (!OidIsValid(replidindex))
5540  return NULL;
5541 
5542  /* Look up the description for the replica identity index */
5543  indexDesc = RelationIdGetRelation(replidindex);
5544 
5545  if (!RelationIsValid(indexDesc))
5546  elog(ERROR, "could not open relation with OID %u",
5547  relation->rd_replidindex);
5548 
5549  /* Add referenced attributes to idindexattrs */
5550  for (i = 0; i < indexDesc->rd_index->indnatts; i++)
5551  {
5552  int attrnum = indexDesc->rd_index->indkey.values[i];
5553 
5554  /*
5555  * We don't include non-key columns into idindexattrs bitmaps. See
5556  * RelationGetIndexAttrBitmap.
5557  */
5558  if (attrnum != 0)
5559  {
5560  if (i < indexDesc->rd_index->indnkeyatts)
5561  idindexattrs = bms_add_member(idindexattrs,
5563  }
5564  }
5565 
5566  RelationClose(indexDesc);
5567 
5568  /* Don't leak the old values of these bitmaps, if any */
5569  bms_free(relation->rd_idattr);
5570  relation->rd_idattr = NULL;
5571 
5572  /* Now save copy of the bitmap in the relcache entry */
5574  relation->rd_idattr = bms_copy(idindexattrs);
5575  MemoryContextSwitchTo(oldcxt);
5576 
5577  /* We return our original working copy for caller to play with */
5578  return idindexattrs;
5579 }
5580 
5581 /*
5582  * RelationGetExclusionInfo -- get info about index's exclusion constraint
5583  *
5584  * This should be called only for an index that is known to have an
5585  * associated exclusion constraint. It returns arrays (palloc'd in caller's
5586  * context) of the exclusion operator OIDs, their underlying functions'
5587  * OIDs, and their strategy numbers in the index's opclasses. We cache
5588  * all this information since it requires a fair amount of work to get.
5589  */
5590 void
5592  Oid **operators,
5593  Oid **procs,
5594  uint16 **strategies)
5595 {
5596  int indnkeyatts;
5597  Oid *ops;
5598  Oid *funcs;
5599  uint16 *strats;
5600  Relation conrel;
5601  SysScanDesc conscan;
5602  ScanKeyData skey[1];
5603  HeapTuple htup;
5604  bool found;
5605  MemoryContext oldcxt;
5606  int i;
5607 
5608  indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
5609 
5610  /* Allocate result space in caller context */
5611  *operators = ops = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
5612  *procs = funcs = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
5613  *strategies = strats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts);
5614 
5615  /* Quick exit if we have the data cached already */
5616  if (indexRelation->rd_exclstrats != NULL)
5617  {
5618  memcpy(ops, indexRelation->rd_exclops, sizeof(Oid) * indnkeyatts);
5619  memcpy(funcs, indexRelation->rd_exclprocs, sizeof(Oid) * indnkeyatts);
5620  memcpy(strats, indexRelation->rd_exclstrats, sizeof(uint16) * indnkeyatts);
5621  return;
5622  }
5623 
5624  /*
5625  * Search pg_constraint for the constraint associated with the index. To
5626  * make this not too painfully slow, we use the index on conrelid; that
5627  * will hold the parent relation's OID not the index's own OID.
5628  *
5629  * Note: if we wanted to rely on the constraint name matching the index's
5630  * name, we could just do a direct lookup using pg_constraint's unique
5631  * index. For the moment it doesn't seem worth requiring that.
5632  */
5633  ScanKeyInit(&skey[0],
5634  Anum_pg_constraint_conrelid,
5635  BTEqualStrategyNumber, F_OIDEQ,
5636  ObjectIdGetDatum(indexRelation->rd_index->indrelid));
5637 
5638  conrel = table_open(ConstraintRelationId, AccessShareLock);
5639  conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true,
5640  NULL, 1, skey);
5641  found = false;
5642 
5643  while (HeapTupleIsValid(htup = systable_getnext(conscan)))
5644  {
5646  Datum val;
5647  bool isnull;
5648  ArrayType *arr;
5649  int nelem;
5650 
5651  /* We want the exclusion constraint owning the index */
5652  if (conform->contype != CONSTRAINT_EXCLUSION ||
5653  conform->conindid != RelationGetRelid(indexRelation))
5654  continue;
5655 
5656  /* There should be only one */
5657  if (found)
5658  elog(ERROR, "unexpected exclusion constraint record found for rel %s",
5659  RelationGetRelationName(indexRelation));
5660  found = true;
5661 
5662  /* Extract the operator OIDS from conexclop */
5663  val = fastgetattr(htup,
5664  Anum_pg_constraint_conexclop,
5665  conrel->rd_att, &isnull);
5666  if (isnull)
5667  elog(ERROR, "null conexclop for rel %s",
5668  RelationGetRelationName(indexRelation));
5669 
5670  arr = DatumGetArrayTypeP(val); /* ensure not toasted */
5671  nelem = ARR_DIMS(arr)[0];
5672  if (ARR_NDIM(arr) != 1 ||
5673  nelem != indnkeyatts ||
5674  ARR_HASNULL(arr) ||
5675  ARR_ELEMTYPE(arr) != OIDOID)
5676  elog(ERROR, "conexclop is not a 1-D Oid array");
5677 
5678  memcpy(ops, ARR_DATA_PTR(arr), sizeof(Oid) * indnkeyatts);
5679  }
5680 
5681  systable_endscan(conscan);
5682  table_close(conrel, AccessShareLock);
5683 
5684  if (!found)
5685  elog(ERROR, "exclusion constraint record missing for rel %s",
5686  RelationGetRelationName(indexRelation));
5687 
5688  /* We need the func OIDs and strategy numbers too */
5689  for (i = 0; i < indnkeyatts; i++)
5690  {
5691  funcs[i] = get_opcode(ops[i]);
5692  strats[i] = get_op_opfamily_strategy(ops[i],
5693  indexRelation->rd_opfamily[i]);
5694  /* shouldn't fail, since it was checked at index creation */
5695  if (strats[i] == InvalidStrategy)
5696  elog(ERROR, "could not find strategy for operator %u in family %u",
5697  ops[i], indexRelation->rd_opfamily[i]);
5698  }
5699 
5700  /* Save a copy of the results in the relcache entry. */
5701  oldcxt = MemoryContextSwitchTo(indexRelation->rd_indexcxt);
5702  indexRelation->rd_exclops = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
5703  indexRelation->rd_exclprocs = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
5704  indexRelation->rd_exclstrats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts);
5705  memcpy(indexRelation->rd_exclops, ops, sizeof(Oid) * indnkeyatts);
5706  memcpy(indexRelation->rd_exclprocs, funcs, sizeof(Oid) * indnkeyatts);
5707  memcpy(indexRelation->rd_exclstrats, strats, sizeof(uint16) * indnkeyatts);
5708  MemoryContextSwitchTo(oldcxt);
5709 }
5710 
5711 /*
5712  * Get the publication information for the given relation.
5713  *
5714  * Traverse all the publications which the relation is in to get the
5715  * publication actions and validate the row filter expressions for such
5716  * publications if any. We consider the row filter expression as invalid if it
5717  * references any column which is not part of REPLICA IDENTITY.
5718  *
5719  * To avoid fetching the publication information repeatedly, we cache the
5720  * publication actions and row filter validation information.
5721  */
5722 void
5724 {
5725  List *puboids;
5726  ListCell *lc;
5727  MemoryContext oldcxt;
5728  Oid schemaid;
5729  List *ancestors = NIL;
5730  Oid relid = RelationGetRelid(relation);
5731 
5732  /*
5733  * If not publishable, it publishes no actions. (pgoutput_change() will
5734  * ignore it.)
5735  */
5736  if (!is_publishable_relation(relation))
5737  {
5738  memset(pubdesc, 0, sizeof(PublicationDesc));
5739  pubdesc->rf_valid_for_update = true;
5740  pubdesc->rf_valid_for_delete = true;
5741  pubdesc->cols_valid_for_update = true;
5742  pubdesc->cols_valid_for_delete = true;
5743  return;
5744  }
5745 
5746  if (relation->rd_pubdesc)
5747  {
5748  memcpy(pubdesc, relation->rd_pubdesc, sizeof(PublicationDesc));
5749  return;
5750  }
5751 
5752  memset(pubdesc, 0, sizeof(PublicationDesc));
5753  pubdesc->rf_valid_for_update = true;
5754  pubdesc->rf_valid_for_delete = true;
5755  pubdesc->cols_valid_for_update = true;
5756  pubdesc->cols_valid_for_delete = true;
5757 
5758  /* Fetch the publication membership info. */
5759  puboids = GetRelationPublications(relid);
5760  schemaid = RelationGetNamespace(relation);
5761  puboids = list_concat_unique_oid(puboids, GetSchemaPublications(schemaid));
5762 
5763  if (relation->rd_rel->relispartition)
5764  {
5765  /* Add publications that the ancestors are in too. */
5766  ancestors = get_partition_ancestors(relid);
5767 
5768  foreach(lc, ancestors)
5769  {
5770  Oid ancestor = lfirst_oid(lc);
5771 
5772  puboids = list_concat_unique_oid(puboids,
5773  GetRelationPublications(ancestor));
5774  schemaid = get_rel_namespace(ancestor);
5775  puboids = list_concat_unique_oid(puboids,
5776  GetSchemaPublications(schemaid));
5777  }
5778  }
5779  puboids = list_concat_unique_oid(puboids, GetAllTablesPublications());
5780 
5781  foreach(lc, puboids)
5782  {
5783  Oid pubid = lfirst_oid(lc);
5784  HeapTuple tup;
5785  Form_pg_publication pubform;
5786 
5787  tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
5788 
5789  if (!HeapTupleIsValid(tup))
5790  elog(ERROR, "cache lookup failed for publication %u", pubid);
5791 
5792  pubform = (Form_pg_publication) GETSTRUCT(tup);
5793 
5794  pubdesc->pubactions.pubinsert |= pubform->pubinsert;
5795  pubdesc->pubactions.pubupdate |= pubform->pubupdate;
5796  pubdesc->pubactions.pubdelete |= pubform->pubdelete;
5797  pubdesc->pubactions.pubtruncate |= pubform->pubtruncate;
5798 
5799  /*
5800  * Check if all columns referenced in the filter expression are part
5801  * of the REPLICA IDENTITY index or not.
5802  *
5803  * If the publication is FOR ALL TABLES then it means the table has no
5804  * row filters and we can skip the validation.
5805  */
5806  if (!pubform->puballtables &&
5807  (pubform->pubupdate || pubform->pubdelete) &&
5808  pub_rf_contains_invalid_column(pubid, relation, ancestors,
5809  pubform->pubviaroot))
5810  {
5811  if (pubform->pubupdate)
5812  pubdesc->rf_valid_for_update = false;
5813  if (pubform->pubdelete)
5814  pubdesc->rf_valid_for_delete = false;
5815  }
5816 
5817  /*
5818  * Check if all columns are part of the REPLICA IDENTITY index or not.
5819  *
5820  * If the publication is FOR ALL TABLES then it means the table has no
5821  * column list and we can skip the validation.
5822  */
5823  if (!pubform->puballtables &&
5824  (pubform->pubupdate || pubform->pubdelete) &&
5825  pub_collist_contains_invalid_column(pubid, relation, ancestors,
5826  pubform->pubviaroot))
5827  {
5828  if (pubform->pubupdate)
5829  pubdesc->cols_valid_for_update = false;
5830  if (pubform->pubdelete)
5831  pubdesc->cols_valid_for_delete = false;
5832  }
5833 
5834  ReleaseSysCache(tup);
5835 
5836  /*
5837  * If we know everything is replicated and the row filter is invalid
5838  * for update and delete, there is no point to check for other
5839  * publications.
5840  */
5841  if (pubdesc->pubactions.pubinsert && pubdesc->pubactions.pubupdate &&
5842  pubdesc->pubactions.pubdelete && pubdesc->pubactions.pubtruncate &&
5843  !pubdesc->rf_valid_for_update && !pubdesc->rf_valid_for_delete)
5844  break;
5845 
5846  /*
5847  * If we know everything is replicated and the column list is invalid
5848  * for update and delete, there is no point to check for other
5849  * publications.
5850  */
5851  if (pubdesc->pubactions.pubinsert && pubdesc->pubactions.pubupdate &&
5852  pubdesc->pubactions.pubdelete && pubdesc->pubactions.pubtruncate &&
5853  !pubdesc->cols_valid_for_update && !pubdesc->cols_valid_for_delete)
5854  break;
5855  }
5856 
5857  if (relation->rd_pubdesc)
5858  {
5859  pfree(relation->rd_pubdesc);
5860  relation->rd_pubdesc = NULL;
5861  }
5862 
5863  /* Now save copy of the descriptor in the relcache entry. */
5865  relation->rd_pubdesc = palloc(sizeof(PublicationDesc));
5866  memcpy(relation->rd_pubdesc, pubdesc, sizeof(PublicationDesc));
5867  MemoryContextSwitchTo(oldcxt);
5868 }
5869 
5870 static bytea **
5871 CopyIndexAttOptions(bytea **srcopts, int natts)
5872 {
5873  bytea **opts = palloc(sizeof(*opts) * natts);
5874 
5875  for (int i = 0; i < natts; i++)
5876  {
5877  bytea *opt = srcopts[i];
5878 
5879  opts[i] = !opt ? NULL : (bytea *)
5880  DatumGetPointer(datumCopy(PointerGetDatum(opt), false, -1));
5881  }
5882 
5883  return opts;
5884 }
5885 
5886 /*
5887  * RelationGetIndexAttOptions
5888  * get AM/opclass-specific options for an index parsed into a binary form
5889  */
5890 bytea **
5892 {
5893  MemoryContext oldcxt;
5894  bytea **opts = relation->rd_opcoptions;
5895  Oid relid = RelationGetRelid(relation);
5896  int natts = RelationGetNumberOfAttributes(relation); /* XXX
5897  * IndexRelationGetNumberOfKeyAttributes */
5898  int i;
5899 
5900  /* Try to copy cached options. */
5901  if (opts)
5902  return copy ? CopyIndexAttOptions(opts, natts) : opts;
5903 
5904  /* Get and parse opclass options. */
5905  opts = palloc0(sizeof(*opts) * natts);
5906 
5907  for (i = 0; i < natts; i++)
5908  {
5909  if (criticalRelcachesBuilt && relid != AttributeRelidNumIndexId)
5910  {
5911  Datum attoptions = get_attoptions(relid, i + 1);
5912 
5913  opts[i] = index_opclass_options(relation, i + 1, attoptions, false);
5914 
5915  if (attoptions != (Datum) 0)
5916  pfree(DatumGetPointer(attoptions));
5917  }
5918  }
5919 
5920  /* Copy parsed options to the cache. */
5921  oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt);
5922  relation->rd_opcoptions = CopyIndexAttOptions(opts, natts);
5923  MemoryContextSwitchTo(oldcxt);
5924 
5925  if (copy)
5926  return opts;
5927 
5928  for (i = 0; i < natts; i++)
5929  {
5930  if (opts[i])
5931  pfree(opts[i]);
5932  }
5933 
5934  pfree(opts);
5935 
5936  return relation->rd_opcoptions;
5937 }
5938 
5939 /*
5940  * Routines to support ereport() reports of relation-related errors
5941  *
5942  * These could have been put into elog.c, but it seems like a module layering
5943  * violation to have elog.c calling relcache or syscache stuff --- and we
5944  * definitely don't want elog.h including rel.h. So we put them here.
5945  */
5946 
5947 /*
5948  * errtable --- stores schema_name and table_name of a table
5949  * within the current errordata.
5950  */
5951 int
5953 {
5957 
5958  return 0; /* return value does not matter */
5959 }
5960 
5961 /*
5962  * errtablecol --- stores schema_name, table_name and column_name
5963  * of a table column within the current errordata.
5964  *
5965  * The column is specified by attribute number --- for most callers, this is
5966  * easier and less error-prone than getting the column name for themselves.
5967  */
5968 int
5970 {
5971  TupleDesc reldesc = RelationGetDescr(rel);
5972  const char *colname;
5973 
5974  /* Use reldesc if it's a user attribute, else consult the catalogs */
5975  if (attnum > 0 && attnum <= reldesc->natts)
5976  colname = NameStr(TupleDescAttr(reldesc, attnum - 1)->attname);
5977  else
5978  colname = get_attname(RelationGetRelid(rel), attnum, false);
5979 
5980  return errtablecolname(rel, colname);
5981 }
5982 
5983 /*
5984  * errtablecolname --- stores schema_name, table_name and column_name
5985  * of a table column within the current errordata, where the column name is
5986  * given directly rather than extracted from the relation's catalog data.
5987  *
5988  * Don't use this directly unless errtablecol() is inconvenient for some
5989  * reason. This might possibly be needed during intermediate states in ALTER
5990  * TABLE, for instance.
5991  */
5992 int
5993 errtablecolname(Relation rel, const char *colname)
5994 {
5995  errtable(rel);
5997 
5998  return 0; /* return value does not matter */
5999 }
6000 
6001 /*
6002  * errtableconstraint --- stores schema_name, table_name and constraint_name
6003  * of a table-related constraint within the current errordata.
6004  */
6005 int
6006 errtableconstraint(Relation rel, const char *conname)
6007 {
6008  errtable(rel);
6010 
6011  return 0; /* return value does not matter */
6012 }
6013 
6014 
6015 /*
6016  * load_relcache_init_file, write_relcache_init_file
6017  *
6018  * In late 1992, we started regularly having databases with more than
6019  * a thousand classes in them. With this number of classes, it became
6020  * critical to do indexed lookups on the system catalogs.
6021  *
6022  * Bootstrapping these lookups is very hard. We want to be able to
6023  * use an index on pg_attribute, for example, but in order to do so,
6024  * we must have read pg_attribute for the attributes in the index,
6025  * which implies that we need to use the index.
6026  *
6027  * In order to get around the problem, we do the following:
6028  *
6029  * + When the database system is initialized (at initdb time), we
6030  * don't use indexes. We do sequential scans.
6031  *
6032  * + When the backend is started up in normal mode, we load an image
6033  * of the appropriate relation descriptors, in internal format,
6034  * from an initialization file in the data/base/... directory.
6035  *
6036  * + If the initialization file isn't there, then we create the
6037  * relation descriptors using sequential scans and write 'em to
6038  * the initialization file for use by subsequent backends.
6039  *
6040  * As of Postgres 9.0, there is one local initialization file in each
6041  * database, plus one shared initialization file for shared catalogs.
6042  *
6043  * We could dispense with the initialization files and just build the
6044  * critical reldescs the hard way on every backend startup, but that
6045  * slows down backend startup noticeably.
6046  *
6047  * We can in fact go further, and save more relcache entries than
6048  * just the ones that are absolutely critical; this allows us to speed
6049  * up backend startup by not having to build such entries the hard way.
6050  * Presently, all the catalog and index entries that are referred to
6051  * by catcaches are stored in the initialization files.
6052  *
6053  * The same mechanism that detects when catcache and relcache entries
6054  * need to be invalidated (due to catalog updates) also arranges to
6055  * unlink the initialization files when the contents may be out of date.
6056  * The files will then be rebuilt during the next backend startup.
6057  */
6058 
6059 /*
6060  * load_relcache_init_file -- attempt to load cache from the shared
6061  * or local cache init file
6062  *
6063  * If successful, return true and set criticalRelcachesBuilt or
6064  * criticalSharedRelcachesBuilt to true.
6065  * If not successful, return false.
6066  *
6067  * NOTE: we assume we are already switched into CacheMemoryContext.
6068  */
6069 static bool
6071 {
6072  FILE *fp;
6073  char initfilename[MAXPGPATH];
6074  Relation *rels;
6075  int relno,
6076  num_rels,
6077  max_rels,
6078  nailed_rels,
6079  nailed_indexes,
6080  magic;
6081  int i;
6082 
6083  if (shared)
6084  snprintf(initfilename, sizeof(initfilename), "global/%s",
6086  else
6087  snprintf(initfilename, sizeof(initfilename), "%s/%s",
6089 
6090  fp = AllocateFile(initfilename, PG_BINARY_R);
6091  if (fp == NULL)
6092  return false;
6093 
6094  /*
6095  * Read the index relcache entries from the file. Note we will not enter
6096  * any of them into the cache if the read fails partway through; this
6097  * helps to guard against broken init files.
6098  */
6099  max_rels = 100;
6100  rels = (Relation *) palloc(max_rels * sizeof(Relation));
6101  num_rels = 0;
6102  nailed_rels = nailed_indexes = 0;
6103 
6104  /* check for correct magic number (compatible version) */
6105  if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
6106  goto read_failed;
6107  if (magic != RELCACHE_INIT_FILEMAGIC)
6108  goto read_failed;
6109 
6110  for (relno = 0;; relno++)
6111  {
6112  Size len;
6113  size_t nread;
6114  Relation rel;
6115  Form_pg_class relform;
6116  bool has_not_null;
6117 
6118  /* first read the relation descriptor length */
6119  nread = fread(&len, 1, sizeof(len), fp);
6120  if (nread != sizeof(len))
6121  {
6122  if (nread == 0)
6123  break; /* end of file */
6124  goto read_failed;
6125  }
6126 
6127  /* safety check for incompatible relcache layout */
6128  if (len != sizeof(RelationData))
6129  goto read_failed;
6130 
6131  /* allocate another relcache header */
6132  if (num_rels >= max_rels)
6133  {
6134  max_rels *= 2;
6135  rels = (Relation *) repalloc(rels, max_rels * sizeof(Relation));
6136  }
6137 
6138  rel = rels[num_rels++] = (Relation) palloc(len);
6139 
6140  /* then, read the Relation structure */
6141  if (fread(rel, 1, len, fp) != len)
6142  goto read_failed;
6143 
6144  /* next read the relation tuple form */
6145  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6146  goto read_failed;
6147 
6148  relform = (Form_pg_class) palloc(len);
6149  if (fread(relform, 1, len, fp) != len)
6150  goto read_failed;
6151 
6152  rel->rd_rel = relform;
6153 
6154  /* initialize attribute tuple forms */
6155  rel->rd_att = CreateTemplateTupleDesc(relform->relnatts);
6156  rel->rd_att->tdrefcount = 1; /* mark as refcounted */
6157 
6158  rel->rd_att->tdtypeid = relform->reltype ? relform->reltype : RECORDOID;
6159  rel->rd_att->tdtypmod = -1; /* just to be sure */
6160 
6161  /* next read all the attribute tuple form data entries */
6162  has_not_null = false;
6163  for (i = 0; i < relform->relnatts; i++)
6164  {
6165  Form_pg_attribute attr = TupleDescAttr(rel->rd_att, i);
6166 
6167  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6168  goto read_failed;
6170  goto read_failed;
6171  if (fread(attr, 1, len, fp) != len)
6172  goto read_failed;
6173 
6174  has_not_null |= attr->attnotnull;
6175  }
6176 
6177  /* next read the access method specific field */
6178  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6179  goto read_failed;
6180  if (len > 0)
6181  {
6182  rel->rd_options = palloc(len);
6183  if (fread(rel->rd_options, 1, len, fp) != len)
6184  goto read_failed;
6185  if (len != VARSIZE(rel->rd_options))
6186  goto read_failed; /* sanity check */
6187  }
6188  else
6189  {
6190  rel->rd_options = NULL;
6191  }
6192 
6193  /* mark not-null status */
6194  if (has_not_null)
6195  {
6196  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
6197 
6198  constr->has_not_null = true;
6199  rel->rd_att->constr = constr;
6200  }
6201 
6202  /*
6203  * If it's an index, there's more to do. Note we explicitly ignore
6204  * partitioned indexes here.
6205  */
6206  if (rel->rd_rel->relkind == RELKIND_INDEX)
6207  {
6208  MemoryContext indexcxt;
6209  Oid *opfamily;
6210  Oid *opcintype;
6211  RegProcedure *support;
6212  int nsupport;
6213  int16 *indoption;
6214  Oid *indcollation;
6215 
6216  /* Count nailed indexes to ensure we have 'em all */
6217  if (rel->rd_isnailed)
6218  nailed_indexes++;
6219 
6220  /* read the pg_index tuple */
6221  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6222  goto read_failed;
6223 
6224  rel->rd_indextuple = (HeapTuple) palloc(len);
6225  if (fread(rel->rd_indextuple, 1, len, fp) != len)
6226  goto read_failed;
6227 
6228  /* Fix up internal pointers in the tuple -- see heap_copytuple */
6229  rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE);
6231 
6232  /*
6233  * prepare index info context --- parameters should match
6234  * RelationInitIndexAccessInfo
6235  */
6237  "index info",
6239  rel->rd_indexcxt = indexcxt;
6242 
6243  /*
6244  * Now we can fetch the index AM's API struct. (We can't store
6245  * that in the init file, since it contains function pointers that
6246  * might vary across server executions. Fortunately, it should be
6247  * safe to call the amhandler even while bootstrapping indexes.)
6248  */
6249  InitIndexAmRoutine(rel);
6250 
6251  /* read the vector of opfamily OIDs */
6252  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6253  goto read_failed;
6254 
6255  opfamily = (Oid *) MemoryContextAlloc(indexcxt, len);
6256  if (fread(opfamily, 1, len, fp) != len)
6257  goto read_failed;
6258 
6259  rel->rd_opfamily = opfamily;
6260 
6261  /* read the vector of opcintype OIDs */
6262  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6263  goto read_failed;
6264 
6265  opcintype = (Oid *) MemoryContextAlloc(indexcxt, len);
6266  if (fread(opcintype, 1, len, fp) != len)
6267  goto read_failed;
6268 
6269  rel->rd_opcintype = opcintype;
6270 
6271  /* read the vector of support procedure OIDs */
6272  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6273  goto read_failed;
6274  support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
6275  if (fread(support, 1, len, fp) != len)
6276  goto read_failed;
6277 
6278  rel->rd_support = support;
6279 
6280  /* read the vector of collation OIDs */
6281  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6282  goto read_failed;
6283 
6284  indcollation = (Oid *) MemoryContextAlloc(indexcxt, len);
6285  if (fread(indcollation, 1, len, fp) != len)
6286  goto read_failed;
6287 
6288  rel->rd_indcollation = indcollation;
6289 
6290  /* read the vector of indoption values */
6291  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6292  goto read_failed;
6293 
6294  indoption = (int16 *) MemoryContextAlloc(indexcxt, len);
6295  if (fread(indoption, 1, len, fp) != len)
6296  goto read_failed;
6297 
6298  rel->rd_indoption = indoption;
6299 
6300  /* read the vector of opcoptions values */
6301  rel->rd_opcoptions = (bytea **)
6302  MemoryContextAllocZero(indexcxt, sizeof(*rel->rd_opcoptions) * relform->relnatts);
6303 
6304  for (i = 0; i < relform->relnatts; i++)
6305  {
6306  if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
6307  goto read_failed;
6308 
6309  if (len > 0)
6310  {
6311  rel->rd_opcoptions[i] = (bytea *) MemoryContextAlloc(indexcxt, len);
6312  if (fread(rel->rd_opcoptions[i], 1, len, fp) != len)
6313  goto read_failed;
6314  }
6315  }
6316 
6317  /* set up zeroed fmgr-info vector */
6318  nsupport = relform->relnatts * rel->rd_indam->amsupport;
6319  rel->rd_supportinfo = (FmgrInfo *)
6320  MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
6321  }
6322  else
6323  {
6324  /* Count nailed rels to ensure we have 'em all */
6325  if (rel->rd_isnailed)
6326  nailed_rels++;
6327 
6328  /* Load table AM data */
6329  if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind) || rel->rd_rel->relkind == RELKIND_SEQUENCE)
6331 
6332  Assert(rel->rd_index == NULL);
6333  Assert(rel->rd_indextuple == NULL);
6334  Assert(rel->rd_indexcxt == NULL);
6335  Assert(rel->rd_indam == NULL);
6336  Assert(rel->rd_opfamily == NULL);
6337  Assert(rel->rd_opcintype == NULL);
6338  Assert(rel->rd_support == NULL);
6339  Assert(rel->rd_supportinfo == NULL);
6340  Assert(rel->rd_indoption == NULL);
6341  Assert(rel->rd_indcollation == NULL);
6342  Assert(rel->rd_opcoptions == NULL);
6343  }
6344 
6345  /*
6346  * Rules and triggers are not saved (mainly because the internal
6347  * format is complex and subject to change). They must be rebuilt if
6348  * needed by RelationCacheInitializePhase3. This is not expected to
6349  * be a big performance hit since few system catalogs have such. Ditto
6350  * for RLS policy data, partition info, index expressions, predicates,
6351  * exclusion info, and FDW info.
6352  */
6353  rel->rd_rules = NULL;
6354  rel->rd_rulescxt = NULL;
6355  rel->trigdesc = NULL;
6356  rel->rd_rsdesc = NULL;
6357  rel->rd_partkey = NULL;
6358  rel->rd_partkeycxt = NULL;
6359  rel->rd_partdesc = NULL;
6360  rel->rd_partdesc_nodetached = NULL;
6362  rel->rd_pdcxt = NULL;
6363  rel->rd_pddcxt = NULL;
6364  rel->rd_partcheck = NIL;
6365  rel->rd_partcheckvalid = false;
6366  rel->rd_partcheckcxt = NULL;
6367  rel->rd_indexprs = NIL;
6368  rel->rd_indpred = NIL;
6369  rel->rd_exclops = NULL;
6370  rel->rd_exclprocs = NULL;
6371  rel->rd_exclstrats = NULL;
6372  rel->rd_fdwroutine = NULL;
6373 
6374  /*
6375  * Reset transient-state fields in the relcache entry
6376  */
6377  rel->rd_smgr = NULL;
6378  if (rel->rd_isnailed)
6379  rel->rd_refcnt = 1;
6380  else
6381  rel->rd_refcnt = 0;
6382  rel->rd_indexvalid = false;
6383  rel->rd_indexlist = NIL;
6384  rel->rd_pkindex = InvalidOid;
6385  rel->rd_replidindex = InvalidOid;
6386  rel->rd_attrsvalid = false;
6387  rel->rd_keyattr = NULL;
6388  rel->rd_pkattr = NULL;
6389  rel->rd_idattr = NULL;
6390  rel->rd_pubdesc = NULL;
6391  rel->rd_statvalid = false;
6392  rel->rd_statlist = NIL;
6393  rel->rd_fkeyvalid = false;
6394  rel->rd_fkeylist = NIL;
6399  rel->rd_amcache = NULL;
6400  rel->pgstat_info = NULL;
6401 
6402  /*
6403  * Recompute lock and physical addressing info. This is needed in
6404  * case the pg_internal.init file was copied from some other database
6405  * by CREATE DATABASE.
6406  */
6407  RelationInitLockInfo(rel);
6409  }
6410 
6411  /*
6412  * We reached the end of the init file without apparent problem. Did we
6413  * get the right number of nailed items? This is a useful crosscheck in
6414  * case the set of critical rels or indexes changes. However, that should
6415  * not happen in a normally-running system, so let's bleat if it does.
6416  *
6417  * For the shared init file, we're called before client authentication is
6418  * done, which means that elog(WARNING) will go only to the postmaster
6419  * log, where it's easily missed. To ensure that developers notice bad
6420  * values of NUM_CRITICAL_SHARED_RELS/NUM_CRITICAL_SHARED_INDEXES, we put
6421  * an Assert(false) there.
6422  */
6423  if (shared)
6424  {
6425  if (nailed_rels != NUM_CRITICAL_SHARED_RELS ||
6426  nailed_indexes != NUM_CRITICAL_SHARED_INDEXES)
6427  {
6428  elog(WARNING, "found %d nailed shared rels and %d nailed shared indexes in init file, but expected %d and %d respectively",
6429  nailed_rels, nailed_indexes,
6431  /* Make sure we get developers' attention about this */
6432  Assert(false);
6433  /* In production builds, recover by bootstrapping the relcache */
6434  goto read_failed;
6435  }
6436  }
6437  else
6438  {
6439  if (nailed_rels != NUM_CRITICAL_LOCAL_RELS ||
6440  nailed_indexes != NUM_CRITICAL_LOCAL_INDEXES)
6441  {
6442  elog(WARNING, "found %d nailed rels and %d nailed indexes in init file, but expected %d and %d respectively",
6443  nailed_rels, nailed_indexes,
6445  /* We don't need an Assert() in this case */
6446  goto read_failed;
6447  }
6448  }
6449 
6450  /*
6451  * OK, all appears well.
6452  *
6453  * Now insert all the new relcache entries into the cache.
6454  */
6455  for (relno = 0; relno < num_rels; relno++)
6456  {
6457  RelationCacheInsert(rels[relno], false);
6458  }
6459 
6460  pfree(rels);
6461  FreeFile(fp);
6462 
6463  if (shared)
6465  else
6466  criticalRelcachesBuilt = true;
6467  return true;
6468 
6469  /*
6470  * init file is broken, so do it the hard way. We don't bother trying to
6471  * free the clutter we just allocated; it's not in the relcache so it
6472  * won't hurt.
6473  */
6474 read_failed:
6475  pfree(rels);
6476  FreeFile(fp);
6477 
6478  return false;
6479 }
6480 
6481 /*
6482  * Write out a new initialization file with the current contents
6483  * of the relcache (either shared rels or local rels, as indicated).
6484  */
6485 static void
6487 {
6488  FILE *fp;
6489  char tempfilename[MAXPGPATH];
6490  char finalfilename[MAXPGPATH];
6491  int magic;
6492  HASH_SEQ_STATUS status;
6493  RelIdCacheEnt *idhentry;
6494  int i;
6495 
6496  /*
6497  * If we have already received any relcache inval events, there's no
6498  * chance of succeeding so we may as well skip the whole thing.
6499  */
6500  if (relcacheInvalsReceived != 0L)
6501  return;
6502 
6503  /*
6504  * We must write a temporary file and rename it into place. Otherwise,
6505  * another backend starting at about the same time might crash trying to
6506  * read the partially-complete file.
6507  */
6508  if (shared)
6509  {
6510  snprintf(tempfilename, sizeof(tempfilename), "global/%s.%d",
6512  snprintf(finalfilename, sizeof(finalfilename), "global/%s",
6514  }
6515  else
6516  {
6517  snprintf(tempfilename, sizeof(tempfilename), "%s/%s.%d",
6519  snprintf(finalfilename, sizeof(finalfilename), "%s/%s",
6521  }
6522 
6523  unlink(tempfilename); /* in case it exists w/wrong permissions */
6524 
6525  fp = AllocateFile(tempfilename, PG_BINARY_W);
6526  if (fp == NULL)
6527  {
6528  /*
6529  * We used to consider this a fatal error, but we might as well
6530  * continue with backend startup ...
6531  */
6532  ereport(WARNING,
6534  errmsg("could not create relation-cache initialization file \"%s\": %m",
6535  tempfilename),
6536  errdetail("Continuing anyway, but there's something wrong.")));
6537  return;
6538  }
6539 
6540  /*
6541  * Write a magic number to serve as a file version identifier. We can
6542  * change the magic number whenever the relcache layout changes.
6543  */
6544  magic = RELCACHE_INIT_FILEMAGIC;
6545  if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
6546  ereport(FATAL,
6548  errmsg_internal("could not write init file: %m"));
6549 
6550  /*
6551  * Write all the appropriate reldescs (in no particular order).
6552  */
6553  hash_seq_init(&status, RelationIdCache);
6554 
6555  while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
6556  {
6557  Relation rel = idhentry->reldesc;
6558  Form_pg_class relform = rel->rd_rel;
6559 
6560  /* ignore if not correct group */
6561  if (relform->relisshared != shared)
6562  continue;
6563 
6564  /*
6565  * Ignore if not supposed to be in init file. We can allow any shared
6566  * relation that's been loaded so far to be in the shared init file,
6567  * but unshared relations must be ones that should be in the local
6568  * file per RelationIdIsInInitFile. (Note: if you want to change the
6569  * criterion for rels to be kept in the init file, see also inval.c.
6570  * The reason for filtering here is to be sure that we don't put
6571  * anything into the local init file for which a relcache inval would
6572  * not cause invalidation of that init file.)
6573  */
6574  if (!shared && !RelationIdIsInInitFile(RelationGetRelid(rel)))
6575  {
6576  /* Nailed rels had better get stored. */
6577  Assert(!rel->rd_isnailed);
6578  continue;
6579  }
6580 
6581  /* first write the relcache entry proper */
6582  write_item(rel, sizeof(RelationData), fp);
6583 
6584  /* next write the relation tuple form */
6585  write_item(relform, CLASS_TUPLE_SIZE, fp);
6586 
6587  /* next, do all the attribute tuple form data entries */
6588  for (i = 0; i < relform->relnatts; i++)
6589  {
6592  }
6593 
6594  /* next, do the access method specific field */
6595  write_item(rel->rd_options,
6596  (rel->rd_options ? VARSIZE(rel->rd_options) : 0),
6597  fp);
6598 
6599  /*
6600  * If it's an index, there's more to do. Note we explicitly ignore
6601  * partitioned indexes here.
6602  */
6603  if (rel->rd_rel->relkind == RELKIND_INDEX)
6604  {
6605  /* write the pg_index tuple */
6606  /* we assume this was created by heap_copytuple! */
6609  fp);
6610 
6611  /* write the vector of opfamily OIDs */
6612  write_item(rel->rd_opfamily,
6613  relform->relnatts * sizeof(Oid),
6614  fp);
6615 
6616  /* write the vector of opcintype OIDs */
6617  write_item(rel->rd_opcintype,
6618  relform->relnatts * sizeof(Oid),
6619  fp);
6620 
6621  /* write the vector of support procedure OIDs */
6622  write_item(rel->rd_support,
6623  relform->relnatts * (rel->rd_indam->amsupport * sizeof(RegProcedure)),
6624  fp);
6625 
6626  /* write the vector of collation OIDs */
6628  relform->relnatts * sizeof(Oid),
6629  fp);
6630 
6631  /* write the vector of indoption values */
6632  write_item(rel->rd_indoption,
6633  relform->relnatts * sizeof(int16),
6634  fp);
6635 
6636  Assert(rel->rd_opcoptions);
6637 
6638  /* write the vector of opcoptions values */
6639  for (i = 0; i < relform->relnatts; i++)
6640  {
6641  bytea *opt = rel->rd_opcoptions[i];
6642 
6643  write_item(opt, opt ? VARSIZE(opt) : 0, fp);
6644  }
6645  }
6646  }
6647 
6648  if (FreeFile(fp))
6649  ereport(FATAL,
6651  errmsg_internal("could not write init file: %m"));
6652 
6653  /*
6654  * Now we have to check whether the data we've so painstakingly
6655  * accumulated is already obsolete due to someone else's just-committed
6656  * catalog changes. If so, we just delete the temp file and leave it to
6657  * the next backend to try again. (Our own relcache entries will be
6658  * updated by SI message processing, but we can't be sure whether what we
6659  * wrote out was up-to-date.)
6660  *
6661  * This mustn't run concurrently with the code that unlinks an init file
6662  * and sends SI messages, so grab a serialization lock for the duration.
6663  */
6664  LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
6665 
6666  /* Make sure we have seen all incoming SI messages */
6668 
6669  /*
6670  * If we have received any SI relcache invals since backend start, assume
6671  * we may have written out-of-date data.
6672  */
6673  if (relcacheInvalsReceived == 0L)
6674  {
6675  /*
6676  * OK, rename the temp file to its final name, deleting any
6677  * previously-existing init file.
6678  *
6679  * Note: a failure here is possible under Cygwin, if some other
6680  * backend is holding open an unlinked-but-not-yet-gone init file. So
6681  * treat this as a noncritical failure; just remove the useless temp
6682  * file on failure.
6683  */
6684  if (rename(tempfilename, finalfilename) < 0)
6685  unlink(tempfilename);
6686  }
6687  else
6688  {
6689  /* Delete the already-obsolete temp file */
6690  unlink(tempfilename);
6691  }
6692 
6693  LWLockRelease(RelCacheInitLock);
6694 }
6695 
6696 /* write a chunk of data preceded by its length */
6697 static void
6698 write_item(const void *data, Size len, FILE *fp)
6699 {
6700  if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
6701  ereport(FATAL,
6703  errmsg_internal("could not write init file: %m"));
6704  if (len > 0 && fwrite(data, 1, len, fp) != len)
6705  ereport(FATAL,
6707  errmsg_internal("could not write init file: %m"));
6708 }
6709 
6710 /*
6711  * Determine whether a given relation (identified by OID) is one of the ones
6712  * we should store in a relcache init file.
6713  *
6714  * We must cache all nailed rels, and for efficiency we should cache every rel
6715  * that supports a syscache. The former set is almost but not quite a subset
6716  * of the latter. The special cases are relations where
6717  * RelationCacheInitializePhase2/3 chooses to nail for efficiency reasons, but
6718  * which do not support any syscache.
6719  */
6720 bool
6722 {
6723  if (relationId == SharedSecLabelRelationId ||
6724  relationId == TriggerRelidNameIndexId ||
6725  relationId == DatabaseNameIndexId ||
6726  relationId == SharedSecLabelObjectIndexId)
6727  {
6728  /*
6729  * If this Assert fails, we don't need the applicable special case
6730  * anymore.
6731  */
6732  Assert(!RelationSupportsSysCache(relationId));
6733  return true;
6734  }
6735  return RelationSupportsSysCache(relationId);
6736 }
6737 
6738 /*
6739  * Invalidate (remove) the init file during commit of a transaction that
6740  * changed one or more of the relation cache entries that are kept in the
6741  * local init file.
6742  *
6743  * To be safe against concurrent inspection or rewriting of the init file,
6744  * we must take RelCacheInitLock, then remove the old init file, then send
6745  * the SI messages that include relcache inval for such relations, and then
6746  * release RelCacheInitLock. This serializes the whole affair against
6747  * write_relcache_init_file, so that we can be sure that any other process
6748  * that's concurrently trying to create a new init file won't move an
6749  * already-stale version into place after we unlink. Also, because we unlink
6750  * before sending the SI messages, a backend that's currently starting cannot
6751  * read the now-obsolete init file and then miss the SI messages that will
6752  * force it to update its relcache entries. (This works because the backend
6753  * startup sequence gets into the sinval array before trying to load the init
6754  * file.)
6755  *
6756  * We take the lock and do the unlink in RelationCacheInitFilePreInvalidate,
6757  * then release the lock in RelationCacheInitFilePostInvalidate. Caller must
6758  * send any pending SI messages between those calls.
6759  */
6760 void
6762 {
6763  char localinitfname[MAXPGPATH];
6764  char sharedinitfname[MAXPGPATH];
6765 
6766  if (DatabasePath)
6767  snprintf(localinitfname, sizeof(localinitfname), "%s/%s",
6769  snprintf(sharedinitfname, sizeof(sharedinitfname), "global/%s",
6771 
6772  LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
6773 
6774  /*
6775  * The files might not be there if no backend has been started since the
6776  * last removal. But complain about failures other than ENOENT with
6777  * ERROR. Fortunately, it's not too late to abort the transaction if we
6778  * can't get rid of the would-be-obsolete init file.
6779  */
6780  if (DatabasePath)
6781  unlink_initfile(localinitfname, ERROR);
6782  unlink_initfile(sharedinitfname, ERROR);
6783 }
6784 
6785 void
6787 {
6788  LWLockRelease(RelCacheInitLock);
6789 }
6790 
6791 /*
6792  * Remove the init files during postmaster startup.
6793  *
6794  * We used to keep the init files across restarts, but that is unsafe in PITR
6795  * scenarios, and even in simple crash-recovery cases there are windows for
6796  * the init files to become out-of-sync with the database. So now we just
6797  * remove them during startup and expect the first backend launch to rebuild
6798  * them. Of course, this has to happen in each database of the cluster.
6799  */
6800 void
6802 {
6803  const char *tblspcdir = "pg_tblspc";
6804  DIR *dir;
6805  struct dirent *de;
6806  char path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY)];
6807 
6808  snprintf(path, sizeof(path), "global/%s",
6810  unlink_initfile(path, LOG);
6811 
6812  /* Scan everything in the default tablespace */
6814 
6815  /* Scan the tablespace link directory to find non-default tablespaces */
6816  dir = AllocateDir(tblspcdir);
6817 
6818  while ((de = ReadDirExtended(dir, tblspcdir, LOG)) != NULL)
6819  {
6820  if (strspn(de->d_name, "0123456789") == strlen(de->d_name))
6821  {
6822  /* Scan the tablespace dir for per-database dirs */
6823  snprintf(path, sizeof(path), "%s/%s/%s",
6824  tblspcdir, de->d_name, TABLESPACE_VERSION_DIRECTORY);
6826  }
6827  }
6828 
6829  FreeDir(dir);
6830 }
6831 
6832 /* Process one per-tablespace directory for RelationCacheInitFileRemove */
6833 static void
6834 RelationCacheInitFileRemoveInDir(const char *tblspcpath)
6835 {
6836  DIR *dir;
6837  struct dirent *de;
6838  char initfilename[MAXPGPATH * 2];
6839 
6840  /* Scan the tablespace directory to find per-database directories */
6841  dir = AllocateDir(tblspcpath);
6842 
6843  while ((de = ReadDirExtended(dir, tblspcpath, LOG)) != NULL)
6844  {
6845  if (strspn(de->d_name, "0123456789") == strlen(de->d_name))
6846  {
6847  /* Try to remove the init file in each database */
6848  snprintf(initfilename, sizeof(initfilename), "%s/%s/%s",
6849  tblspcpath, de->d_name, RELCACHE_INIT_FILENAME);
6850  unlink_initfile(initfilename, LOG);
6851  }
6852  }
6853 
6854  FreeDir(dir);
6855 }
6856 
6857 static void
6858 unlink_initfile(const char *initfilename, int elevel)
6859 {
6860  if (unlink(initfilename) < 0)
6861  {
6862  /* It might not be there, but log any error other than ENOENT */
6863  if (errno != ENOENT)
6864  ereport(elevel,
6866  errmsg("could not remove cache file \"%s\": %m",
6867  initfilename)));
6868  }
6869 }
6870 
6871 /*
6872  * ResourceOwner callbacks
6873  */
6874 static char *
6876 {
6878 
6879  return psprintf("relation \"%s\"", RelationGetRelationName(rel));
6880 }
6881 
6882 static void
6884 {
6886 
6887  /*
6888  * This reference has already been removed from the resource owner, so
6889  * just decrement reference count without calling
6890  * ResourceOwnerForgetRelationRef.
6891  */
6892  Assert(rel->rd_refcnt > 0);
6893  rel->rd_refcnt -= 1;
6894 
6896 }
IndexAmRoutine * GetIndexAmRoutine(Oid amhandler)
Definition: amapi.c:33
bytea *(* amoptions_function)(Datum reloptions, bool validate)
Definition: amapi.h:144
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Definition: arrayfuncs.c:1820
int16 AttrNumber
Definition: attnum.h:21
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
Bitmapset * bms_copy(const Bitmapset *a)
Definition: bitmapset.c:122
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:746
#define TopSubTransactionId
Definition: c.h:659
unsigned short uint16
Definition: c.h:505
#define PG_BINARY_R
Definition: c.h:1275
signed short int16
Definition: c.h:493
uint32 SubTransactionId
Definition: c.h:656
signed int int32
Definition: c.h:494
#define InvalidSubTransactionId
Definition: c.h:658
#define Assert(condition)
Definition: c.h:858
TransactionId MultiXactId
Definition: c.h:662
#define PointerIsValid(pointer)
Definition: c.h:763
regproc RegProcedure
Definition: c.h:650
#define PG_BINARY_W
Definition: c.h:1276
uint32 TransactionId
Definition: c.h:652
#define OidIsValid(objectId)
Definition: c.h:775
size_t Size
Definition: c.h:605
bool IsSystemRelation(Relation relation)
Definition: catalog.c:73
RelFileNumber GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
Definition: catalog.c:521
bool IsCatalogNamespace(Oid namespaceId)
Definition: catalog.c:203
bool IsCatalogRelation(Relation relation)
Definition: catalog.c:103
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:264
void CreateCacheMemoryContext(void)
Definition: catcache.c:680
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2254
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
void hash_seq_term(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1471
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1395
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1385
int err_generic_string(int field, const char *str)
Definition: elog.c:1512
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errcode_for_file_access(void)
Definition: elog.c:876
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define WARNING
Definition: elog.h:36
#define PANIC
Definition: elog.h:42
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
int FreeDir(DIR *dir)
Definition: fd.c:2961
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2583
int FreeFile(FILE *file)
Definition: fd.c:2781
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2924
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2843
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
bool IsBinaryUpgrade
Definition: globals.c:119
int MyProcPid
Definition: globals.c:46
Oid MyDatabaseTableSpace
Definition: globals.c:94
char * DatabasePath
Definition: globals.c:102
Oid MyDatabaseId
Definition: globals.c:92
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber
Definition: heap.c:82
const TableAmRoutine * GetHeapamTableAmRoutine(void)
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:455
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
#define HEAPTUPLESIZE
Definition: htup.h:73
HeapTupleData * HeapTuple
Definition: htup.h:71
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHeaderSetXmin(tup, xid)
Definition: htup_details.h:315
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:309
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:749
#define IsParallelWorker()
Definition: parallel.h:60
RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber
Definition: index.c:85
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:133
bytea * index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions, bool validate)
Definition: indexam.c:996
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
long val
Definition: informix.c:670
static int pg_cmp_s16(int16 a, int16 b)
Definition: int.h:471
void AcceptInvalidationMessages(void)
Definition: inval.c:806
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1360
int debug_discard_caches
Definition: inval.c:240
int b
Definition: isn.c:70
int a
Definition: isn.c:69
int i
Definition: isn.c:73
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1674
List * list_concat_unique_oid(List *list1, const List *list2)
Definition: list.c:1469
List * lappend(List *list, void *datum)
Definition: list.c:339
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
List * list_copy(const List *oldlist)
Definition: list.c:1573
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
Definition: list.c:1703
void list_free(List *list)
Definition: list.c:1546
List * lcons(void *datum, List *list)
Definition: list.c:495
void list_free_deep(List *list)
Definition: list.c:1560
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:227
void RelationInitLockInfo(Relation relation)
Definition: lmgr.c:71
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
LockTagType
Definition: lock.h:136
@ LOCKTAG_RELATION
Definition: lock.h:137
#define AccessShareLock
Definition: lockdefs.h:36
#define RowExclusiveLock
Definition: lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
Datum get_attoptions(Oid relid, int16 attnum)
Definition: lsyscache.c:970
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1952
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1285
int get_op_opfamily_strategy(Oid opno, Oid opfamily)
Definition: lsyscache.c:83
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:827
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:114
List * make_ands_implicit(Expr *clause)
Definition: makefuncs.c:737
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:301
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:637
void pfree(void *pointer)
Definition: mcxt.c:1521
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:539
void * palloc0(Size size)
Definition: mcxt.c:1347
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1683
MemoryContext CacheMemoryContext
Definition: mcxt.c:152
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void * palloc(Size size)
Definition: mcxt.c:1317
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170
#define MemoryContextCopyAndSetIdentifier(cxt, id)
Definition: memutils.h:101
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:454
#define InvalidMultiXactId
Definition: multixact.h:24
void namestrcpy(Name name, const char *str)
Definition: name.c:233
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3658
ProcNumber GetTempNamespaceProcNumber(Oid namespaceId)
Definition: namespace.c:3751
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:298
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:816
void fix_opfuncids(Node *node)
Definition: nodeFuncs.c:1831
#define copyObject(obj)
Definition: nodes.h:224
@ CMD_SELECT
Definition: nodes.h:265
#define makeNode(_type_)
Definition: nodes.h:155
List * get_partition_ancestors(Oid relid)
Definition: partition.c:134
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
static AmcheckOptions opts
Definition: pg_amcheck.c:111
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:49
FormData_pg_attribute
Definition: pg_attribute.h:193
NameData attname
Definition: pg_attribute.h:41
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:201
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
NameData relname
Definition: pg_class.h:38
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define CLASS_TUPLE_SIZE
Definition: pg_class.h:145
#define MAXPGPATH
void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, AttrNumber *conkey, AttrNumber *confkey, Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs, int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
FormData_pg_constraint * Form_pg_constraint
const void size_t len
const void * data
FormData_pg_index * Form_pg_index
Definition: pg_index.h:70
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
#define lfirst_oid(lc)
Definition: pg_list.h:174
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
List * GetSchemaPublications(Oid schemaid)
List * GetRelationPublications(Oid relid)
List * GetAllTablesPublications(void)
bool is_publishable_relation(Relation rel)
FormData_pg_publication * Form_pg_publication
static char ** options
FormData_pg_rewrite * Form_pg_rewrite
Definition: pg_rewrite.h:52
FormData_pg_statistic_ext * Form_pg_statistic_ext
void pgstat_unlink_relation(Relation rel)
void RelationBuildRowSecurity(Relation relation)
Definition: policy.c:193
#define snprintf
Definition: port.h:238
#define qsort(a, b, c, d)
Definition: port.h:453
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:64
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:68
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:66
Expr * canonicalize_qual(Expr *qual, bool is_check)
Definition: prepqual.c:293
#define ProcNumberForTempRelations()
Definition: proc.h:319
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool pub_rf_contains_invalid_column(Oid pubid, Relation relation, List *ancestors, bool pubviaroot)
bool pub_collist_contains_invalid_column(Oid pubid, Relation relation, List *ancestors, bool pubviaroot)
MemoryContextSwitchTo(old_ctx)
tree ctl
Definition: radixtree.h:1853
void * stringToNode(const char *str)
Definition: read.c:90
#define RelationGetForm(relation)
Definition: rel.h:499
#define RelationHasReferenceCountZero(relation)
Definition: rel.h:489
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationHasSecurityInvoker(relation)
Definition: rel.h:436
#define RelationGetDescr(relation)
Definition: rel.h:531
#define RelationIsMapped(relation)
Definition: rel.h:554
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:511
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define RelationIsAccessibleInLogicalDecoding(relation)
Definition: rel.h:684
#define RelationIsValid(relation)
Definition: rel.h:478
#define RelationGetNamespace(relation)
Definition: rel.h:546
#define IndexRelationGetNumberOfAttributes(relation)
Definition: rel.h:517
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:524
#define RelationIsPermanent(relation)
Definition: rel.h:617
static void RelationCloseSmgr(Relation relation)
Definition: rel.h:582
#define RECOVER_RELATION_BUILD_MEMORY
Definition: relcache.c:102
static int NextEOXactTupleDescNum
Definition: relcache.c:203
static bool load_relcache_init_file(bool shared)
Definition: relcache.c:6070
void RelationBuildPublicationDesc(Relation relation, PublicationDesc *pubdesc)
Definition: relcache.c:5723
static void RelationParseRelOptions(Relation relation, HeapTuple tuple)
Definition: relcache.c:464
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4801
void RelationCacheInvalidate(bool debug_discard)
Definition: relcache.c:3011
#define NUM_CRITICAL_LOCAL_RELS
#define NUM_CRITICAL_SHARED_INDEXES
#define RelationCacheInsert(RELATION, replace_allowed)
Definition: relcache.c:209
void RelationDecrementReferenceCount(Relation rel)
Definition: relcache.c:2172
static Relation RelationBuildDesc(Oid targetRelId, bool insertIt)
Definition: relcache.c:1038
bool criticalRelcachesBuilt
Definition: relcache.c:140
static TupleDesc BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs)
Definition: relcache.c:4420
static const FormData_pg_attribute Desc_pg_shseclabel[Natts_pg_shseclabel]
Definition: relcache.c:119
bool criticalSharedRelcachesBuilt
Definition: relcache.c:146
static Oid eoxact_list[MAX_EOXACT_LIST]
Definition: relcache.c:185
static void formrdesc(const char *relationName, Oid relationReltype, bool isshared, int natts, const FormData_pg_attribute *attrs)
Definition: relcache.c:1873
Oid RelationGetPrimaryKeyIndex(Relation relation)
Definition: relcache.c:4992
static void ResOwnerReleaseRelation(Datum res)
Definition: relcache.c:6883
static Relation AllocateRelationDesc(Form_pg_class relp)
Definition: relcache.c:409
static const FormData_pg_attribute Desc_pg_database[Natts_pg_database]
Definition: relcache.c:115
static void unlink_initfile(const char *initfilename, int elevel)
Definition: relcache.c:6858
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:6006
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5969
void RelationInitIndexAccessInfo(Relation relation)
Definition: relcache.c:1424
static void InitIndexAmRoutine(Relation relation)
Definition: relcache.c:1400
static void write_item(const void *data, Size len, FILE *fp)
Definition: relcache.c:6698
List * RelationGetIndexPredicate(Relation relation)
Definition: relcache.c:5151
static const FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute]
Definition: relcache.c:112
List * RelationGetStatExtList(Relation relation)
Definition: relcache.c:4922
static bool equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
Definition: relcache.c:906
static int in_progress_list_maxlen
Definition: relcache.c:172
#define INITRELCACHESIZE
Definition: relcache.c:3989
static int CheckConstraintCmp(const void *a, const void *b)
Definition: relcache.c:4669
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3387
static void ResourceOwnerRememberRelationRef(ResourceOwner owner, Relation rel)
Definition: relcache.c:2140
static const FormData_pg_attribute Desc_pg_class[Natts_pg_class]
Definition: relcache.c:111
static void RelationReloadNailed(Relation relation)
Definition: relcache.c:2369
static const FormData_pg_attribute Desc_pg_authid[Natts_pg_authid]
Definition: relcache.c:116
static TupleDesc GetPgClassDescriptor(void)
Definition: relcache.c:4450
static void AttrDefaultFetch(Relation relation, int ndef)
Definition: relcache.c:4485
static HTAB * OpClassCache
Definition: relcache.c:271
static const ResourceOwnerDesc relref_resowner_desc
Definition: relcache.c:2129
static void IndexSupportInitialize(oidvector *indclass, RegProcedure *indexSupport, Oid *opFamily, Oid *opcInType, StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber)
Definition: relcache.c:1595
void RelationIncrementReferenceCount(Relation rel)
Definition: relcache.c:2159
#define RelationCacheDelete(RELATION)
Definition: relcache.c:243
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6786
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:5244
void RelationCacheInitializePhase3(void)
Definition: relcache.c:4097
#define NUM_CRITICAL_SHARED_RELS
List * RelationGetDummyIndexExpressions(Relation relation)
Definition: relcache.c:5097
static void RelationDestroyRelation(Relation relation, bool remember_tupdesc)
Definition: relcache.c:2441
static void RelationClearRelation(Relation relation, bool rebuild)
Definition: relcache.c:2559
List * RelationGetFKeyList(Relation relation)
Definition: relcache.c:4692
#define EOXactListAdd(rel)
Definition: relcache.c:189
#define RelationIdCacheLookup(ID, RELATION)
Definition: relcache.c:231
void RelationInitTableAccessMethod(Relation relation)
Definition: relcache.c:1808
static const FormData_pg_attribute Desc_pg_subscription[Natts_pg_subscription]
Definition: relcache.c:120
static void RelationFlushRelation(Relation relation)
Definition: relcache.c:2864
static void RelationBuildRuleLock(Relation relation)
Definition: relcache.c:731
static void ResourceOwnerForgetRelationRef(ResourceOwner owner, Relation rel)
Definition: relcache.c:2145
static int in_progress_list_len
Definition: relcache.c:171
static const FormData_pg_attribute Desc_pg_proc[Natts_pg_proc]
Definition: relcache.c:113
void RelationSetNewRelfilenumber(Relation relation, char persistence)
Definition: relcache.c:3767
static const FormData_pg_attribute Desc_pg_index[Natts_pg_index]
Definition: relcache.c:118
static int EOXactTupleDescArrayLen
Definition: relcache.c:204
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:5013
Relation RelationIdGetRelation(Oid relationId)
Definition: relcache.c:2061
static TupleDesc GetPgIndexDescriptor(void)
Definition: relcache.c:4463
static void RelationCloseCleanup(Relation relation)
Definition: relcache.c:2201
#define NUM_CRITICAL_LOCAL_INDEXES
static const FormData_pg_attribute Desc_pg_auth_members[Natts_pg_auth_members]
Definition: relcache.c:117
static void RelationCacheInitFileRemoveInDir(const char *tblspcpath)
Definition: relcache.c:6834
static char * ResOwnerPrintRelCache(Datum res)
Definition: relcache.c:6875
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3235
static void CheckConstraintFetch(Relation relation)
Definition: relcache.c:4580
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2911
static void AtEOSubXact_cleanup(Relation relation, bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3442
void RelationCacheInitialize(void)
Definition: relcache.c:3992
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6761
static bytea ** CopyIndexAttOptions(bytea **srcopts, int natts)
Definition: relcache.c:5871
static void write_relcache_init_file(bool shared)
Definition: relcache.c:6486
Relation RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid accessmtd, RelFileNumber relfilenumber, Oid reltablespace, bool shared_relation, bool mapped_relation, char relpersistence, char relkind)
Definition: relcache.c:3524
void RelationAssumeNewRelfilelocator(Relation relation)
Definition: relcache.c:3966
static void RememberToFreeTupleDescAtEOX(TupleDesc td)
Definition: relcache.c:3113
static HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
Definition: relcache.c:339
static void RelationInitPhysicalAddr(Relation relation)
Definition: relcache.c:1318
static void RelationBuildTupleDesc(Relation relation)
Definition: relcache.c:521
static bool equalRSDesc(RowSecurityDesc *rsdesc1, RowSecurityDesc *rsdesc2)
Definition: relcache.c:997
void RelationCacheInitFileRemove(void)
Definition: relcache.c:6801
static void AtEOXact_cleanup(Relation relation, bool isCommit)
Definition: relcache.c:3305
int errtablecolname(Relation rel, const char *colname)
Definition: relcache.c:5993
struct relidcacheent RelIdCacheEnt
static const FormData_pg_attribute Desc_pg_type[Natts_pg_type]
Definition: relcache.c:114
void RelationCacheInitializePhase2(void)
Definition: relcache.c:4038
static InProgressEnt * in_progress_list
Definition: relcache.c:170
bool RelationIdIsInInitFile(Oid relationId)
Definition: relcache.c:6721
static void RelationReloadIndexInfo(Relation relation)
Definition: relcache.c:2255
static long relcacheInvalsReceived
Definition: relcache.c:154
static void load_critical_index(Oid indexoid, Oid heapoid)
Definition: relcache.c:4382
static void InitTableAmRoutine(Relation relation)
Definition: relcache.c:1799
int errtable(Relation rel)
Definition: relcache.c:5952
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2955
static bool equalPolicy(RowSecurityPolicy *policy1, RowSecurityPolicy *policy2)
Definition: relcache.c:951
#define MAX_EOXACT_LIST
Definition: relcache.c:184
bytea ** RelationGetIndexAttOptions(Relation relation, bool copy)
Definition: relcache.c:5891
Bitmapset * RelationGetIdentityKeyBitmap(Relation relation)
Definition: relcache.c:5517
static int eoxact_list_len
Definition: relcache.c:186
struct opclasscacheent OpClassCacheEnt
static OpClassCacheEnt * LookupOpclassInfo(Oid operatorClassOid, StrategyNumber numSupport)
Definition: relcache.c:1646
static TupleDesc * EOXactTupleDescArray
Definition: relcache.c:202
static bool eoxact_list_overflowed
Definition: relcache.c:187
void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, uint16 **strategies)
Definition: relcache.c:5591
static int AttrDefaultCmp(const void *a, const void *b)
Definition: relcache.c:4565
#define SWAPFIELD(fldtype, fldname)
#define RELCACHE_INIT_FILEMAGIC
Definition: relcache.c:93
List * RelationGetIndexExpressions(Relation relation)
Definition: relcache.c:5038
static HTAB * RelationIdCache
Definition: relcache.c:134
struct inprogressent InProgressEnt
static void RelationInvalidateRelation(Relation relation)
Definition: relcache.c:2520
void RelationClose(Relation relation)
Definition: relcache.c:2192
struct RelationData * Relation
Definition: relcache.h:27
#define RELCACHE_INIT_FILENAME
Definition: relcache.h:25
IndexAttrBitmapKind
Definition: relcache.h:60
@ INDEX_ATTR_BITMAP_KEY
Definition: relcache.h:61
@ INDEX_ATTR_BITMAP_HOT_BLOCKING
Definition: relcache.h:64
@ INDEX_ATTR_BITMAP_PRIMARY_KEY
Definition: relcache.h:62
@ INDEX_ATTR_BITMAP_SUMMARIZED
Definition: relcache.h:65
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
Definition: relcache.h:63
#define AssertPendingSyncs_RelationCache()
Definition: relcache.h:135
void RelationMapInvalidateAll(void)
Definition: relmapper.c:490
void RelationMapInitialize(void)
Definition: relmapper.c:651
void RelationMapInitializePhase2(void)
Definition: relmapper.c:671
RelFileNumber RelationMapOidToFilenumber(Oid relationId, bool shared)
Definition: relmapper.c:165
void RelationMapUpdateMap(Oid relationId, RelFileNumber fileNumber, bool shared, bool immediate)
Definition: relmapper.c:325
void RelationMapInitializePhase3(void)
Definition: relmapper.c:692
bytea * extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, amoptions_function amoptions)
Definition: reloptions.c:1379
Oid RelFileNumber
Definition: relpath.h:25
#define InvalidRelFileNumber
Definition: relpath.h:26
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
#define RELEASE_PRIO_RELCACHE_REFS
Definition: resowner.h:64
void setRuleCheckAsUser(Node *node, Oid userid)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
Definition: smgr.c:198
void smgrreleaseall(void)
Definition: smgr.c:353
void smgrclose(SMgrRelation reln)
Definition: smgr.c:320
void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
Definition: smgr.c:462
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:216
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:648
bool HistoricSnapshotActive(void)
Definition: snapmgr.c:1672
void PopActiveSnapshot(void)
Definition: snapmgr.c:743
Snapshot GetNonHistoricCatalogSnapshot(Oid relid)
Definition: snapmgr.c:374
bool RelFileLocatorSkippingWAL(RelFileLocator rlocator)
Definition: storage.c:532
SMgrRelation RelationCreateStorage(RelFileLocator rlocator, char relpersistence, bool register_delete)
Definition: storage.c:121
void RelationDropStorage(Relation rel)
Definition: storage.c:206
uint16 StrategyNumber
Definition: stratnum.h:22
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define InvalidStrategy
Definition: stratnum.h:24
#define BTEqualStrategyNumber
Definition: stratnum.h:31
AttrNumber adnum
Definition: tupdesc.h:24
char * adbin
Definition: tupdesc.h:25
char * ccname
Definition: tupdesc.h:30
bool ccnoinherit
Definition: tupdesc.h:33
bool ccvalid
Definition: tupdesc.h:32
char * ccbin
Definition: tupdesc.h:31
Definition: dirent.c:26
Definition: fmgr.h:57
Definition: dynahash.c:220
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
amoptions_function amoptions
Definition: amapi.h:275
uint16 amsupport
Definition: amapi.h:220
bool amsummarizing
Definition: amapi.h:254
LOCKTAG lock
Definition: lock.h:410
int64 nLocks
Definition: lock.h:435
LOCALLOCKTAG tag
Definition: lock.h:429
uint8 locktag_type
Definition: lock.h:170
uint32 locktag_field2
Definition: lock.h:167
Definition: pg_list.h:54
MemoryContext firstchild
Definition: memnodes.h:128
Definition: nodes.h:129
PublicationActions pubactions
bool cols_valid_for_delete
bool cols_valid_for_update
RelFileNumber relNumber
List * rd_partcheck
Definition: rel.h:147
Bitmapset * rd_keyattr
Definition: rel.h:162
ProcNumber rd_backend
Definition: rel.h:60
bool rd_ispkdeferrable
Definition: rel.h:154
bool rd_partcheckvalid
Definition: rel.h:148
MemoryContext rd_pdcxt
Definition: rel.h:131
MemoryContext rd_partkeycxt
Definition: rel.h:127
const struct TableAmRoutine * rd_tableam
Definition: rel.h:189
TransactionId rd_partdesc_nodetached_xmin
Definition: rel.h:144
bool rd_indexvalid
Definition: rel.h:64
List * rd_indpred
Definition: rel.h:213
struct IndexAmRoutine * rd_indam
Definition: rel.h:206
List * rd_fkeylist
Definition: rel.h:122
Oid * rd_exclprocs
Definition: rel.h:215
SubTransactionId rd_firstRelfilelocatorSubid
Definition: rel.h:106
uint16 * rd_exclstrats
Definition: rel.h:216
List * rd_indexlist
Definition: rel.h:152
struct RowSecurityDesc * rd_rsdesc
Definition: rel.h:119
PartitionDesc rd_partdesc
Definition: rel.h:130
Oid rd_replidindex
Definition: rel.h:155
int rd_refcnt
Definition: rel.h:59
RegProcedure * rd_support
Definition: rel.h:209
PartitionDesc rd_partdesc_nodetached
Definition: rel.h:134
bytea ** rd_opcoptions
Definition: rel.h:218
PublicationDesc * rd_pubdesc
Definition: rel.h:168
struct FdwRoutine * rd_fdwroutine
Definition: rel.h:240
TriggerDesc * trigdesc
Definition: rel.h:117
Bitmapset * rd_idattr
Definition: rel.h:164
bool rd_isvalid
Definition: rel.h:63
bool rd_islocaltemp
Definition: rel.h:61
List * rd_indexprs
Definition: rel.h:212
bool rd_attrsvalid
Definition: rel.h:161
Oid * rd_exclops
Definition: rel.h:214
Oid * rd_opcintype
Definition: rel.h:208
struct HeapTupleData * rd_indextuple
Definition: rel.h:194
MemoryContext rd_partcheckcxt
Definition: rel.h:149
int16 * rd_indoption
Definition: rel.h:211
TupleDesc rd_att
Definition: rel.h:112
Form_pg_index rd_index
Definition: rel.h:192
Bitmapset * rd_hotblockingattr
Definition: rel.h:165
void * rd_amcache
Definition: rel.h:229
bool rd_isnailed
Definition: rel.h:62
Oid rd_id
Definition: rel.h:113
Oid rd_pkindex
Definition: rel.h:153
SubTransactionId rd_newRelfilelocatorSubid
Definition: rel.h:104
bool rd_fkeyvalid
Definition: rel.h:123
Oid rd_amhandler
Definition: rel.h:184
SMgrRelation rd_smgr
Definition: rel.h:58
SubTransactionId rd_createSubid
Definition: rel.h:103
bool rd_statvalid
Definition: rel.h:66
MemoryContext rd_indexcxt
Definition: rel.h:204
List * rd_statlist
Definition: rel.h:158
MemoryContext rd_pddcxt
Definition: rel.h:135
RelFileLocator rd_locator
Definition: rel.h:57
RuleLock * rd_rules
Definition: rel.h:115
struct FmgrInfo * rd_supportinfo
Definition: rel.h:210
Oid * rd_opfamily
Definition: rel.h:207
SubTransactionId rd_droppedSubid
Definition: rel.h:109
MemoryContext rd_rulescxt
Definition: rel.h:116
Bitmapset * rd_summarizedattr
Definition: rel.h:166
Bitmapset * rd_pkattr
Definition: rel.h:163
PartitionKey rd_partkey
Definition: rel.h:126
bytea * rd_options
Definition: rel.h:175
Oid * rd_indcollation
Definition: rel.h:217
Form_pg_class rd_rel
Definition: rel.h:111
struct PgStat_TableStatus * pgstat_info
Definition: rel.h:255
const char * name
Definition: resowner.h:93
Oid ruleId
Definition: prs2lock.h:26
CmdType event
Definition: prs2lock.h:27
List * actions
Definition: prs2lock.h:29
bool isInstead
Definition: prs2lock.h:31
Node * qual
Definition: prs2lock.h:28
char enabled
Definition: prs2lock.h:30
MemoryContext rscxt
Definition: rowsecurity.h:33
ArrayType * roles
Definition: rowsecurity.h:24
Expr * with_check_qual
Definition: rowsecurity.h:27
RewriteRule ** rules
Definition: prs2lock.h:43
int numLocks
Definition: prs2lock.h:42
bool has_not_null
Definition: tupdesc.h:44
AttrDefault * defval
Definition: tupdesc.h:39
bool has_generated_stored
Definition: tupdesc.h:45
struct AttrMissing * missing
Definition: tupdesc.h:41
ConstrCheck * check
Definition: tupdesc.h:40
uint16 num_defval
Definition: tupdesc.h:42
uint16 num_check
Definition: tupdesc.h:43
int tdrefcount
Definition: tupdesc.h:84
TupleConstr * constr
Definition: tupdesc.h:85
int32 tdtypmod
Definition: tupdesc.h:83
Oid tdtypeid
Definition: tupdesc.h:82
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
Definition: type.h:95
bool invalidated
Definition: relcache.c:167
Definition: c.h:715
int16 values[FLEXIBLE_ARRAY_MEMBER]
Definition: c.h:722
Definition: c.h:726
Oid values[FLEXIBLE_ARRAY_MEMBER]
Definition: c.h:733
StrategyNumber numSupport
Definition: relcache.c:265
RegProcedure * supportProcs
Definition: relcache.c:268
Relation reldesc
Definition: relcache.c:131
Definition: localtime.c:73
Definition: c.h:687
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
bool RelationSupportsSysCache(Oid relid)
Definition: syscache.c:649
void InitCatalogCachePhase2(void)
Definition: syscache.c:177
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
static void table_relation_set_new_filelocator(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition: tableam.h:1621
const TableAmRoutine * GetTableAmRoutine(Oid amhandler)
Definition: tableamapi.c:28
#define InvalidTransactionId
Definition: transam.h:31
void FreeTriggerDesc(TriggerDesc *trigdesc)
Definition: trigger.c:2140
void RelationBuildTriggers(Relation relation)
Definition: trigger.c:1856
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:331
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:67
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:133
bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
Definition: tupdesc.c:419
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition: var.c:291
#define VARSIZE(PTR)
Definition: varatt.h:279
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:789
bool IsTransactionState(void)
Definition: xact.c:385
void CommandCounterIncrement(void)
Definition: xact.c:1098
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:452
static struct rule * rules
Definition: zic.c:283