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