PostgreSQL Source Code git master
Loading...
Searching...
No Matches
catalog.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * catalog.c
4 * routines concerned with catalog naming conventions and other
5 * bits of hard-wired knowledge
6 *
7 *
8 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 *
12 * IDENTIFICATION
13 * src/backend/catalog/catalog.c
14 *
15 *-------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20#include <fcntl.h>
21#include <unistd.h>
22
23#include "access/genam.h"
24#include "access/htup_details.h"
25#include "access/table.h"
26#include "access/transam.h"
27#include "catalog/catalog.h"
28#include "catalog/namespace.h"
30#include "catalog/pg_authid.h"
31#include "catalog/pg_database.h"
37#include "catalog/pg_seclabel.h"
38#include "catalog/pg_shdepend.h"
43#include "catalog/pg_type.h"
44#include "miscadmin.h"
45#include "utils/fmgroids.h"
46#include "utils/fmgrprotos.h"
47#include "utils/rel.h"
48#include "utils/snapmgr.h"
49#include "utils/syscache.h"
50
51/*
52 * Parameters to determine when to emit a log message in
53 * GetNewOidWithIndex()
54 */
55#define GETNEWOID_LOG_THRESHOLD 1000000
56#define GETNEWOID_LOG_MAX_INTERVAL 128000000
57
58/*
59 * IsSystemRelation
60 * True iff the relation is either a system catalog or a toast table.
61 * See IsCatalogRelation for the exact definition of a system catalog.
62 *
63 * We treat toast tables of user relations as "system relations" for
64 * protection purposes, e.g. you can't change their schemas without
65 * special permissions. Therefore, most uses of this function are
66 * checking whether allow_system_table_mods restrictions apply.
67 * For other purposes, consider whether you shouldn't be using
68 * IsCatalogRelation instead.
69 *
70 * This function does not perform any catalog accesses.
71 * Some callers rely on that!
72 */
73bool
75{
76 return IsSystemClass(RelationGetRelid(relation), relation->rd_rel);
77}
78
79/*
80 * IsSystemClass
81 * Like the above, but takes a Form_pg_class as argument.
82 * Used when we do not want to open the relation and have to
83 * search pg_class directly.
84 */
85bool
87{
88 /* IsCatalogRelationOid is a bit faster, so test that first */
89 return (IsCatalogRelationOid(relid) ||
92}
93
94/*
95 * IsCatalogRelation
96 * True iff the relation is a system catalog.
97 *
98 * By a system catalog, we mean one that is created during the bootstrap
99 * phase of initdb. That includes not just the catalogs per se, but
100 * also their indexes, and TOAST tables and indexes if any.
101 *
102 * This function does not perform any catalog accesses.
103 * Some callers rely on that!
104 */
105bool
107{
108 return IsCatalogRelationOid(RelationGetRelid(relation));
109}
110
111/*
112 * IsCatalogRelationOid
113 * True iff the relation identified by this OID is a system catalog.
114 *
115 * By a system catalog, we mean one that is created during the bootstrap
116 * phase of initdb. That includes not just the catalogs per se, but
117 * also their indexes, and TOAST tables and indexes if any.
118 *
119 * This function does not perform any catalog accesses.
120 * Some callers rely on that!
121 */
122bool
124{
125 /*
126 * We consider a relation to be a system catalog if it has a pinned OID.
127 * This includes all the defined catalogs, their indexes, and their TOAST
128 * tables and indexes.
129 *
130 * This rule excludes the relations in information_schema, which are not
131 * integral to the system and can be treated the same as user relations.
132 * (Since it's valid to drop and recreate information_schema, any rule
133 * that did not act this way would be wrong.)
134 *
135 * This test is reliable since an OID wraparound will skip this range of
136 * OIDs; see GetNewObjectId().
137 */
138 return (relid < (Oid) FirstUnpinnedObjectId);
139}
140
141/*
142 * IsCatalogTextUniqueIndexOid
143 * True iff the relation identified by this OID is a catalog UNIQUE index
144 * having a column of type "text".
145 *
146 * The relcache must not use these indexes. Inserting into any UNIQUE
147 * index compares index keys while holding BUFFER_LOCK_EXCLUSIVE.
148 * bttextcmp() can search the COLLOID catcache. Depending on concurrent
149 * invalidation traffic, catcache can reach relcache builds. A backend
150 * would self-deadlock on LWLocks if the relcache build read the
151 * exclusive-locked buffer.
152 *
153 * To avoid being itself the cause of self-deadlock, this doesn't read
154 * catalogs. Instead, it uses a hard-coded list with a supporting
155 * regression test.
156 */
157bool
159{
160 switch (relid)
161 {
166 return true;
167 }
168 return false;
169}
170
171/*
172 * IsInplaceUpdateRelation
173 * True iff core code performs inplace updates on the relation.
174 *
175 * This is used for assertions and for making the executor follow the
176 * locking protocol described at README.tuplock section "Locking to write
177 * inplace-updated tables". Extensions may inplace-update other heap
178 * tables, but concurrent SQL UPDATE on the same table may overwrite
179 * those modifications.
180 *
181 * The executor can assume these are not partitions or partitioned and
182 * have no triggers.
183 */
184bool
186{
187 return IsInplaceUpdateOid(RelationGetRelid(relation));
188}
189
190/*
191 * IsInplaceUpdateOid
192 * Like the above, but takes an OID as argument.
193 */
194bool
196{
197 return (relid == RelationRelationId ||
198 relid == DatabaseRelationId);
199}
200
201/*
202 * IsToastRelation
203 * True iff relation is a TOAST support relation (or index).
204 *
205 * Does not perform any catalog accesses.
206 */
207bool
209{
210 /*
211 * What we actually check is whether the relation belongs to a pg_toast
212 * namespace. This should be equivalent because of restrictions that are
213 * enforced elsewhere against creating user relations in, or moving
214 * relations into/out of, a pg_toast namespace. Notice also that this
215 * will not say "true" for toast tables belonging to other sessions' temp
216 * tables; we expect that other mechanisms will prevent access to those.
217 */
218 return IsToastNamespace(RelationGetNamespace(relation));
219}
220
221/*
222 * IsToastClass
223 * Like the above, but takes a Form_pg_class as argument.
224 * Used when we do not want to open the relation and have to
225 * search pg_class directly.
226 */
227bool
229{
230 Oid relnamespace = reltuple->relnamespace;
231
232 return IsToastNamespace(relnamespace);
233}
234
235/*
236 * IsConflictLogTableClass
237 * True iff pg_class tuple represents a Conflict Log Table.
238 *
239 * Does not perform any catalog accesses.
240 */
241bool
243{
244 Oid relnamespace = reltuple->relnamespace;
245
246 return IsConflictLogTableNamespace(relnamespace);
247}
248
249/*
250 * IsCatalogNamespace
251 * True iff namespace is pg_catalog.
252 *
253 * Does not perform any catalog accesses.
254 *
255 * NOTE: the reason this isn't a macro is to avoid having to include
256 * catalog/pg_namespace.h in a lot of places.
257 */
258bool
263
264/*
265 * IsToastNamespace
266 * True iff namespace is pg_toast or my temporary-toast-table namespace.
267 *
268 * Does not perform any catalog accesses.
269 *
270 * Note: this will return false for temporary-toast-table namespaces belonging
271 * to other backends. Those are treated the same as other backends' regular
272 * temp table namespaces, and access is prevented where appropriate.
273 * If you need to check for those, you may be able to use isAnyTempNamespace,
274 * but beware that that does involve a catalog access.
275 */
276bool
282
283/*
284 * IsConflictLogTableNamespace
285 * True iff namespace is pg_conflict.
286 *
287 * Does not perform any catalog accesses.
288 */
289bool
294
295/*
296 * IsReservedName
297 * True iff name starts with the pg_ prefix.
298 *
299 * For some classes of objects, the prefix pg_ is reserved for
300 * system objects only. As of 8.0, this was only true for
301 * schema and tablespace names. With 9.6, this is also true
302 * for roles.
303 */
304bool
306{
307 /* ugly coding for speed */
308 return (name[0] == 'p' &&
309 name[1] == 'g' &&
310 name[2] == '_');
311}
312
313
314/*
315 * IsSharedRelation
316 * Given the OID of a relation, determine whether it's supposed to be
317 * shared across an entire database cluster.
318 *
319 * In older releases, this had to be hard-wired so that we could compute the
320 * locktag for a relation and lock it before examining its catalog entry.
321 * Since we now have MVCC catalog access, the race conditions that made that
322 * a hard requirement are gone, so we could look at relaxing this restriction.
323 * However, if we scanned the pg_class entry to find relisshared, and only
324 * then locked the relation, pg_class could get updated in the meantime,
325 * forcing us to scan the relation again, which would definitely be complex
326 * and might have undesirable performance consequences. Fortunately, the set
327 * of shared relations is fairly static, so a hand-maintained list of their
328 * OIDs isn't completely impractical.
329 */
330bool
332{
333 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
345 return true;
346 /* These are their indexes */
368 return true;
369 /* These are their toast tables and toast indexes */
384 return true;
385 return false;
386}
387
388/*
389 * IsPinnedObject
390 * Given the class + OID identity of a database object, report whether
391 * it is "pinned", that is not droppable because the system requires it.
392 *
393 * We used to represent this explicitly in pg_depend, but that proved to be
394 * an undesirable amount of overhead, so now we rely on an OID range test.
395 */
396bool
397IsPinnedObject(Oid classId, Oid objectId)
398{
399 /*
400 * Objects with OIDs above FirstUnpinnedObjectId are never pinned. Since
401 * the OID generator skips this range when wrapping around, this check
402 * guarantees that user-defined objects are never considered pinned.
403 */
404 if (objectId >= FirstUnpinnedObjectId)
405 return false;
406
407 /*
408 * Large objects are never pinned. We need this special case because
409 * their OIDs can be user-assigned.
410 */
411 if (classId == LargeObjectRelationId)
412 return false;
413
414 /*
415 * There are a few objects defined in the catalog .dat files that, as a
416 * matter of policy, we prefer not to treat as pinned. We used to handle
417 * that by excluding them from pg_depend, but it's just as easy to
418 * hard-wire their OIDs here. (If the user does indeed drop and recreate
419 * them, they'll have new but certainly-unpinned OIDs, so no problem.)
420 *
421 * Checking both classId and objectId is overkill, since OIDs below
422 * FirstGenbkiObjectId should be globally unique, but do it anyway for
423 * robustness.
424 */
425
426 /* the public namespace is not pinned */
427 if (classId == NamespaceRelationId &&
428 objectId == PG_PUBLIC_NAMESPACE)
429 return false;
430
431 /*
432 * Databases are never pinned. It might seem that it'd be prudent to pin
433 * at least template0; but we do this intentionally so that template0 and
434 * template1 can be rebuilt from each other, thus letting them serve as
435 * mutual backups (as long as you've not modified template1, anyway).
436 */
437 if (classId == DatabaseRelationId)
438 return false;
439
440 /*
441 * All other initdb-created objects are pinned. This is overkill (the
442 * system doesn't really depend on having every last weird datatype, for
443 * instance) but generating only the minimum required set of dependencies
444 * seems hard, and enforcing an accurate list would be much more expensive
445 * than the simple range test used here.
446 */
447 return true;
448}
449
450
451/*
452 * GetNewOidWithIndex
453 * Generate a new OID that is unique within the system relation.
454 *
455 * Since the OID is not immediately inserted into the table, there is a
456 * race condition here; but a problem could occur only if someone else
457 * managed to cycle through 2^32 OIDs and generate the same OID before we
458 * finish inserting our row. This seems unlikely to be a problem. Note
459 * that if we had to *commit* the row to end the race condition, the risk
460 * would be rather higher; therefore we use SnapshotAny in the test, so that
461 * we will see uncommitted rows. (We used to use SnapshotDirty, but that has
462 * the disadvantage that it ignores recently-deleted rows, creating a risk
463 * of transient conflicts for as long as our own MVCC snapshots think a
464 * recently-deleted row is live. The risk is far higher when selecting TOAST
465 * OIDs, because SnapshotToast considers dead rows as active indefinitely.)
466 *
467 * Note that we are effectively assuming that the table has a relatively small
468 * number of entries (much less than 2^32) and there aren't very long runs of
469 * consecutive existing OIDs. This is a mostly reasonable assumption for
470 * system catalogs.
471 *
472 * Caller must have a suitable lock on the relation.
473 */
474Oid
476{
477 Oid newOid;
478 SysScanDesc scan;
479 ScanKeyData key;
480 bool collides;
481 uint64 retries = 0;
483
484 /* Only system relations are supported */
485 Assert(IsSystemRelation(relation));
486
487 /* In bootstrap mode, we don't have any indexes to use */
489 return GetNewObjectId();
490
491 /*
492 * We should never be asked to generate a new pg_type OID during
493 * pg_upgrade; doing so would risk collisions with the OIDs it wants to
494 * assign. Hitting this assert means there's some path where we failed to
495 * ensure that a type OID is determined by commands in the dump script.
496 */
498
499 /* Generate new OIDs until we find one not in the table */
500 do
501 {
503
505
506 ScanKeyInit(&key,
507 oidcolumn,
510
511 /* see notes above about using SnapshotAny */
512 scan = systable_beginscan(relation, indexId, true,
513 SnapshotAny, 1, &key);
514
516
517 systable_endscan(scan);
518
519 /*
520 * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not
521 * yet found OID unused in the relation. Then repeat logging with
522 * exponentially increasing intervals until we iterate more than
523 * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every
524 * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This
525 * logic is necessary not to fill up the server log with the similar
526 * messages.
527 */
528 if (retries >= retries_before_log)
529 {
530 ereport(LOG,
531 (errmsg("still searching for an unused OID in relation \"%s\"",
532 RelationGetRelationName(relation)),
533 errdetail_plural("OID candidates have been checked %" PRIu64 " time, but no unused OID has been found yet.",
534 "OID candidates have been checked %" PRIu64 " times, but no unused OID has been found yet.",
535 retries,
536 retries)));
537
538 /*
539 * Double the number of retries to do before logging next until it
540 * reaches GETNEWOID_LOG_MAX_INTERVAL.
541 */
544 else
546 }
547
548 retries++;
549 } while (collides);
550
551 /*
552 * If at least one log message is emitted, also log the completion of OID
553 * assignment.
554 */
555 if (retries > GETNEWOID_LOG_THRESHOLD)
556 {
557 ereport(LOG,
558 (errmsg_plural("new OID has been assigned in relation \"%s\" after %" PRIu64 " retry",
559 "new OID has been assigned in relation \"%s\" after %" PRIu64 " retries",
560 retries,
561 RelationGetRelationName(relation), retries)));
562 }
563
564 return newOid;
565}
566
567/*
568 * GetNewRelFileNumber
569 * Generate a new relfilenumber that is unique within the
570 * database of the given tablespace.
571 *
572 * If the relfilenumber will also be used as the relation's OID, pass the
573 * opened pg_class catalog, and this routine will guarantee that the result
574 * is also an unused OID within pg_class. If the result is to be used only
575 * as a relfilenumber for an existing relation, pass NULL for pg_class.
576 *
577 * As with GetNewOidWithIndex(), there is some theoretical risk of a race
578 * condition, but it doesn't seem worth worrying about.
579 *
580 * Note: we don't support using this in bootstrap mode. All relations
581 * created by bootstrap have preassigned OIDs, so there's no need.
582 */
584GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
585{
586 RelFileLocatorBackend rlocator;
587 RelPathStr rpath;
588 bool collides;
589 ProcNumber procNumber;
590
591 /*
592 * If we ever get here during pg_upgrade, there's something wrong; all
593 * relfilenumber assignments during a binary-upgrade run should be
594 * determined by commands in the dump script.
595 */
597
598 switch (relpersistence)
599 {
601 procNumber = ProcNumberForTempRelations();
602 break;
605 procNumber = INVALID_PROC_NUMBER;
606 break;
607 default:
608 elog(ERROR, "invalid relpersistence: %c", relpersistence);
609 return InvalidRelFileNumber; /* placate compiler */
610 }
611
612 /* This logic should match RelationInitPhysicalAddr */
613 rlocator.locator.spcOid = reltablespace ? reltablespace : MyDatabaseTableSpace;
614 rlocator.locator.dbOid =
615 (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ?
617
618 /*
619 * The relpath will vary based on the backend number, so we must
620 * initialize that properly here to make sure that any collisions based on
621 * filename are properly detected.
622 */
623 rlocator.backend = procNumber;
624
625 do
626 {
628
629 /* Generate the OID */
630 if (pg_class)
633 else
634 rlocator.locator.relNumber = GetNewObjectId();
635
636 /* Check for existing file of same name */
637 rpath = relpath(rlocator, MAIN_FORKNUM);
638
639 if (access(rpath.str, F_OK) == 0)
640 {
641 /* definite collision */
642 collides = true;
643 }
644 else
645 {
646 /*
647 * Here we have a little bit of a dilemma: if errno is something
648 * other than ENOENT, should we declare a collision and loop? In
649 * practice it seems best to go ahead regardless of the errno. If
650 * there is a colliding file we will get an smgr failure when we
651 * attempt to create the new relation file.
652 */
653 collides = false;
654 }
655 } while (collides);
656
657 return rlocator.locator.relNumber;
658}
659
660/*
661 * SQL callable interface for GetNewOidWithIndex(). Outside of initdb's
662 * direct insertions into catalog tables, and recovering from corruption, this
663 * should rarely be needed.
664 *
665 * Function is intentionally not documented in the user facing docs.
666 */
667Datum
669{
670 Oid reloid = PG_GETARG_OID(0);
673 Relation rel;
677 AttrNumber attno;
678 Oid newoid;
679
680 /*
681 * As this function is not intended to be used during normal running, and
682 * only supports system catalogs (which require superuser permissions to
683 * modify), just checking for superuser ought to not obstruct valid
684 * usecases.
685 */
686 if (!superuser())
689 errmsg("must be superuser to call %s()",
690 "pg_nextoid")));
691
692 rel = table_open(reloid, RowExclusiveLock);
694
695 if (!IsSystemRelation(rel))
698 errmsg("pg_nextoid() can only be used on system catalogs")));
699
700 if (idx->rd_index->indrelid != RelationGetRelid(rel))
703 errmsg("index \"%s\" does not belong to table \"%s\"",
706
711 errmsg("column \"%s\" of relation \"%s\" does not exist",
713
715 attno = attform->attnum;
716
717 if (attform->atttypid != OIDOID)
720 errmsg("column \"%s\" is not of type oid",
721 NameStr(*attname))));
722
724 idx->rd_index->indkey.values[0] != attno)
727 errmsg("index \"%s\" is not the index for column \"%s\"",
729 NameStr(*attname))));
730
731 newoid = GetNewOidWithIndex(rel, idxoid, attno);
732
736
738}
739
740/*
741 * SQL callable interface for StopGeneratingPinnedObjectIds().
742 *
743 * This is only to be used by initdb, so it's intentionally not documented in
744 * the user facing docs.
745 */
746Datum
748{
749 /*
750 * Belt-and-suspenders check, since StopGeneratingPinnedObjectIds will
751 * fail anyway in non-single-user mode.
752 */
753 if (!superuser())
756 errmsg("must be superuser to call %s()",
757 "pg_stop_making_pinned_objects")));
758
760
762}
Datum idx(PG_FUNCTION_ARGS)
Definition _int_op.c:263
int16 AttrNumber
Definition attnum.h:21
#define NameStr(name)
Definition c.h:894
#define Assert(condition)
Definition c.h:1002
uint64_t uint64
Definition c.h:684
bool IsToastRelation(Relation relation)
Definition catalog.c:208
#define GETNEWOID_LOG_THRESHOLD
Definition catalog.c:55
bool IsToastNamespace(Oid namespaceId)
Definition catalog.c:277
bool IsConflictLogTableClass(Form_pg_class reltuple)
Definition catalog.c:242
bool IsSystemRelation(Relation relation)
Definition catalog.c:74
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:475
bool IsConflictLogTableNamespace(Oid namespaceId)
Definition catalog.c:290
RelFileNumber GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
Definition catalog.c:584
bool IsCatalogNamespace(Oid namespaceId)
Definition catalog.c:259
bool IsToastClass(Form_pg_class reltuple)
Definition catalog.c:228
bool IsCatalogRelation(Relation relation)
Definition catalog.c:106
bool IsPinnedObject(Oid classId, Oid objectId)
Definition catalog.c:397
bool IsSharedRelation(Oid relationId)
Definition catalog.c:331
bool IsCatalogRelationOid(Oid relid)
Definition catalog.c:123
bool IsInplaceUpdateRelation(Relation relation)
Definition catalog.c:185
bool IsReservedName(const char *name)
Definition catalog.c:305
#define GETNEWOID_LOG_MAX_INTERVAL
Definition catalog.c:56
Datum pg_nextoid(PG_FUNCTION_ARGS)
Definition catalog.c:668
bool IsInplaceUpdateOid(Oid relid)
Definition catalog.c:195
bool IsCatalogTextUniqueIndexOid(Oid relid)
Definition catalog.c:158
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition catalog.c:86
Datum pg_stop_making_pinned_objects(PG_FUNCTION_ARGS)
Definition catalog.c:747
int errcode(int sqlerrcode)
Definition elog.c:875
#define LOG
Definition elog.h:32
int int int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_NAME(n)
Definition fmgr.h:279
#define PG_RETURN_OID(x)
Definition fmgr.h:361
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
bool IsBinaryUpgrade
Definition globals.c:123
Oid MyDatabaseTableSpace
Definition globals.c:98
Oid MyDatabaseId
Definition globals.c:96
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:178
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:134
#define RowExclusiveLock
Definition lockdefs.h:38
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
bool isTempToastNamespace(Oid namespaceId)
Definition namespace.c:3733
static char * errmsg
NameData attname
FormData_pg_attribute * Form_pg_attribute
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
unsigned int Oid
static int fb(int x)
short access
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
int ProcNumber
Definition procnumber.h:24
#define ProcNumberForTempRelations()
Definition procnumber.h:53
#define RelationGetRelid(relation)
Definition rel.h:516
#define RelationGetRelationName(relation)
Definition rel.h:550
#define RelationGetNamespace(relation)
Definition rel.h:557
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition rel.h:535
Oid RelFileNumber
Definition relpath.h:25
@ MAIN_FORKNUM
Definition relpath.h:58
#define relpath(rlocator, forknum)
Definition relpath.h:150
#define InvalidRelFileNumber
Definition relpath.h:26
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define SnapshotAny
Definition snapmgr.h:33
#define BTEqualStrategyNumber
Definition stratnum.h:31
RelFileLocator locator
RelFileNumber relNumber
char str[REL_PATH_STR_MAXLEN+1]
Definition relpath.h:123
Form_pg_class rd_rel
Definition rel.h:111
Definition c.h:889
bool superuser(void)
Definition superuser.c:47
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition syscache.c:476
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
#define FirstUnpinnedObjectId
Definition transam.h:196
Oid GetNewObjectId(void)
Definition varsup.c:554
void StopGeneratingPinnedObjectIds(void)
Definition varsup.c:651
const char * name