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