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