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