1 /*-------------------------------------------------------------------------
4 * routines concerned with catalog naming conventions and other
5 * bits of hard-wired knowledge
8 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/catalog/catalog.c
15 *-------------------------------------------------------------------------
23 #include "access/genam.h"
24 #include "access/htup_details.h"
25 #include "access/sysattr.h"
26 #include "access/table.h"
27 #include "access/transam.h"
28 #include "catalog/catalog.h"
29 #include "catalog/indexing.h"
30 #include "catalog/namespace.h"
31 #include "catalog/pg_auth_members.h"
32 #include "catalog/pg_authid.h"
33 #include "catalog/pg_database.h"
34 #include "catalog/pg_db_role_setting.h"
35 #include "catalog/pg_namespace.h"
36 #include "catalog/pg_replication_origin.h"
37 #include "catalog/pg_shdepend.h"
38 #include "catalog/pg_shdescription.h"
39 #include "catalog/pg_shseclabel.h"
40 #include "catalog/pg_subscription.h"
41 #include "catalog/pg_tablespace.h"
42 #include "catalog/pg_type.h"
43 #include "catalog/toasting.h"
44 #include "miscadmin.h"
45 #include "storage/fd.h"
46 #include "utils/fmgroids.h"
47 #include "utils/fmgrprotos.h"
48 #include "utils/rel.h"
49 #include "utils/snapmgr.h"
50 #include "utils/syscache.h"
54 * True iff the relation is either a system catalog or a toast table.
55 * See IsCatalogRelation for the exact definition of a system catalog.
57 * We treat toast tables of user relations as "system relations" for
58 * protection purposes, e.g. you can't change their schemas without
59 * special permissions. Therefore, most uses of this function are
60 * checking whether allow_system_table_mods restrictions apply.
61 * For other purposes, consider whether you shouldn't be using
62 * IsCatalogRelation instead.
64 * This function does not perform any catalog accesses.
65 * Some callers rely on that!
68 IsSystemRelation(Relation relation
)
70 return IsSystemClass(RelationGetRelid(relation
), relation
->rd_rel
);
75 * Like the above, but takes a Form_pg_class as argument.
76 * Used when we do not want to open the relation and have to
77 * search pg_class directly.
80 IsSystemClass(Oid relid
, Form_pg_class reltuple
)
82 /* IsCatalogRelationOid is a bit faster, so test that first */
83 return (IsCatalogRelationOid(relid
) || IsToastClass(reltuple
));
88 * True iff the relation is a system catalog.
90 * By a system catalog, we mean one that is created during the bootstrap
91 * phase of initdb. That includes not just the catalogs per se, but
92 * also their indexes, and TOAST tables and indexes if any.
94 * This function does not perform any catalog accesses.
95 * Some callers rely on that!
98 IsCatalogRelation(Relation relation
)
100 return IsCatalogRelationOid(RelationGetRelid(relation
));
104 * IsCatalogRelationOid
105 * True iff the relation identified by this OID is a system catalog.
107 * By a system catalog, we mean one that is created during the bootstrap
108 * phase of initdb. That includes not just the catalogs per se, but
109 * also their indexes, and TOAST tables and indexes if any.
111 * This function does not perform any catalog accesses.
112 * Some callers rely on that!
115 IsCatalogRelationOid(Oid relid
)
118 * We consider a relation to be a system catalog if it has an OID that was
119 * manually assigned or assigned by genbki.pl. This includes all the
120 * defined catalogs, their indexes, and their TOAST tables and indexes.
122 * This rule excludes the relations in information_schema, which are not
123 * integral to the system and can be treated the same as user relations.
124 * (Since it's valid to drop and recreate information_schema, any rule
125 * that did not act this way would be wrong.)
127 * This test is reliable since an OID wraparound will skip this range of
128 * OIDs; see GetNewObjectId().
130 return (relid
< (Oid
) FirstBootstrapObjectId
);
135 * True iff relation is a TOAST support relation (or index).
137 * Does not perform any catalog accesses.
140 IsToastRelation(Relation relation
)
143 * What we actually check is whether the relation belongs to a pg_toast
144 * namespace. This should be equivalent because of restrictions that are
145 * enforced elsewhere against creating user relations in, or moving
146 * relations into/out of, a pg_toast namespace. Notice also that this
147 * will not say "true" for toast tables belonging to other sessions' temp
148 * tables; we expect that other mechanisms will prevent access to those.
150 return IsToastNamespace(RelationGetNamespace(relation
));
155 * Like the above, but takes a Form_pg_class as argument.
156 * Used when we do not want to open the relation and have to
157 * search pg_class directly.
160 IsToastClass(Form_pg_class reltuple
)
162 Oid relnamespace
= reltuple
->relnamespace
;
164 return IsToastNamespace(relnamespace
);
169 * True iff namespace is pg_catalog.
171 * Does not perform any catalog accesses.
173 * NOTE: the reason this isn't a macro is to avoid having to include
174 * catalog/pg_namespace.h in a lot of places.
177 IsCatalogNamespace(Oid namespaceId
)
179 return namespaceId
== PG_CATALOG_NAMESPACE
;
184 * True iff namespace is pg_toast or my temporary-toast-table namespace.
186 * Does not perform any catalog accesses.
188 * Note: this will return false for temporary-toast-table namespaces belonging
189 * to other backends. Those are treated the same as other backends' regular
190 * temp table namespaces, and access is prevented where appropriate.
191 * If you need to check for those, you may be able to use isAnyTempNamespace,
192 * but beware that that does involve a catalog access.
195 IsToastNamespace(Oid namespaceId
)
197 return (namespaceId
== PG_TOAST_NAMESPACE
) ||
198 isTempToastNamespace(namespaceId
);
204 * True iff name starts with the pg_ prefix.
206 * For some classes of objects, the prefix pg_ is reserved for
207 * system objects only. As of 8.0, this was only true for
208 * schema and tablespace names. With 9.6, this is also true
212 IsReservedName(const char *name
)
214 /* ugly coding for speed */
215 return (name
[0] == 'p' &&
223 * Given the OID of a relation, determine whether it's supposed to be
224 * shared across an entire database cluster.
226 * In older releases, this had to be hard-wired so that we could compute the
227 * locktag for a relation and lock it before examining its catalog entry.
228 * Since we now have MVCC catalog access, the race conditions that made that
229 * a hard requirement are gone, so we could look at relaxing this restriction.
230 * However, if we scanned the pg_class entry to find relisshared, and only
231 * then locked the relation, pg_class could get updated in the meantime,
232 * forcing us to scan the relation again, which would definitely be complex
233 * and might have undesirable performance consequences. Fortunately, the set
234 * of shared relations is fairly static, so a hand-maintained list of their
235 * OIDs isn't completely impractical.
238 IsSharedRelation(Oid relationId
)
240 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
241 if (relationId
== AuthIdRelationId
||
242 relationId
== AuthMemRelationId
||
243 relationId
== DatabaseRelationId
||
244 relationId
== SharedDescriptionRelationId
||
245 relationId
== SharedDependRelationId
||
246 relationId
== SharedSecLabelRelationId
||
247 relationId
== TableSpaceRelationId
||
248 relationId
== DbRoleSettingRelationId
||
249 relationId
== ReplicationOriginRelationId
||
250 relationId
== SubscriptionRelationId
)
252 /* These are their indexes (see indexing.h) */
253 if (relationId
== AuthIdRolnameIndexId
||
254 relationId
== AuthIdOidIndexId
||
255 relationId
== AuthMemRoleMemIndexId
||
256 relationId
== AuthMemMemRoleIndexId
||
257 relationId
== DatabaseNameIndexId
||
258 relationId
== DatabaseOidIndexId
||
259 relationId
== SharedDescriptionObjIndexId
||
260 relationId
== SharedDependDependerIndexId
||
261 relationId
== SharedDependReferenceIndexId
||
262 relationId
== SharedSecLabelObjectIndexId
||
263 relationId
== TablespaceOidIndexId
||
264 relationId
== TablespaceNameIndexId
||
265 relationId
== DbRoleSettingDatidRolidIndexId
||
266 relationId
== ReplicationOriginIdentIndex
||
267 relationId
== ReplicationOriginNameIndex
||
268 relationId
== SubscriptionObjectIndexId
||
269 relationId
== SubscriptionNameIndexId
)
271 /* These are their toast tables and toast indexes (see toasting.h) */
272 if (relationId
== PgAuthidToastTable
||
273 relationId
== PgAuthidToastIndex
||
274 relationId
== PgDatabaseToastTable
||
275 relationId
== PgDatabaseToastIndex
||
276 relationId
== PgDbRoleSettingToastTable
||
277 relationId
== PgDbRoleSettingToastIndex
||
278 relationId
== PgReplicationOriginToastTable
||
279 relationId
== PgReplicationOriginToastIndex
||
280 relationId
== PgShdescriptionToastTable
||
281 relationId
== PgShdescriptionToastIndex
||
282 relationId
== PgShseclabelToastTable
||
283 relationId
== PgShseclabelToastIndex
||
284 relationId
== PgSubscriptionToastTable
||
285 relationId
== PgSubscriptionToastIndex
||
286 relationId
== PgTablespaceToastTable
||
287 relationId
== PgTablespaceToastIndex
)
295 * Generate a new OID that is unique within the system relation.
297 * Since the OID is not immediately inserted into the table, there is a
298 * race condition here; but a problem could occur only if someone else
299 * managed to cycle through 2^32 OIDs and generate the same OID before we
300 * finish inserting our row. This seems unlikely to be a problem. Note
301 * that if we had to *commit* the row to end the race condition, the risk
302 * would be rather higher; therefore we use SnapshotAny in the test, so that
303 * we will see uncommitted rows. (We used to use SnapshotDirty, but that has
304 * the disadvantage that it ignores recently-deleted rows, creating a risk
305 * of transient conflicts for as long as our own MVCC snapshots think a
306 * recently-deleted row is live. The risk is far higher when selecting TOAST
307 * OIDs, because SnapshotToast considers dead rows as active indefinitely.)
309 * Note that we are effectively assuming that the table has a relatively small
310 * number of entries (much less than 2^32) and there aren't very long runs of
311 * consecutive existing OIDs. This is a mostly reasonable assumption for
314 * Caller must have a suitable lock on the relation.
317 GetNewOidWithIndex(Relation relation
, Oid indexId
, AttrNumber oidcolumn
)
324 /* Only system relations are supported */
325 Assert(IsSystemRelation(relation
));
327 /* In bootstrap mode, we don't have any indexes to use */
328 if (IsBootstrapProcessingMode())
329 return GetNewObjectId();
332 * We should never be asked to generate a new pg_type OID during
333 * pg_upgrade; doing so would risk collisions with the OIDs it wants to
334 * assign. Hitting this assert means there's some path where we failed to
335 * ensure that a type OID is determined by commands in the dump script.
337 Assert(!IsBinaryUpgrade
|| RelationGetRelid(relation
) != TypeRelationId
);
339 /* Generate new OIDs until we find one not in the table */
342 CHECK_FOR_INTERRUPTS();
344 newOid
= GetNewObjectId();
348 BTEqualStrategyNumber
, F_OIDEQ
,
349 ObjectIdGetDatum(newOid
));
351 /* see notes above about using SnapshotAny */
352 scan
= systable_beginscan(relation
, indexId
, true,
353 SnapshotAny
, 1, &key
);
355 collides
= HeapTupleIsValid(systable_getnext(scan
));
357 systable_endscan(scan
);
365 * Generate a new relfilenode number that is unique within the
366 * database of the given tablespace.
368 * If the relfilenode will also be used as the relation's OID, pass the
369 * opened pg_class catalog, and this routine will guarantee that the result
370 * is also an unused OID within pg_class. If the result is to be used only
371 * as a relfilenode for an existing relation, pass NULL for pg_class.
373 * As with GetNewOidWithIndex(), there is some theoretical risk of a race
374 * condition, but it doesn't seem worth worrying about.
376 * Note: we don't support using this in bootstrap mode. All relations
377 * created by bootstrap have preassigned OIDs, so there's no need.
380 GetNewRelFileNode(Oid reltablespace
, Relation pg_class
, char relpersistence
)
382 RelFileNodeBackend rnode
;
388 * If we ever get here during pg_upgrade, there's something wrong; all
389 * relfilenode assignments during a binary-upgrade run should be
390 * determined by commands in the dump script.
392 Assert(!IsBinaryUpgrade
);
394 switch (relpersistence
)
396 case RELPERSISTENCE_TEMP
:
397 backend
= BackendIdForTempRelations();
399 case RELPERSISTENCE_UNLOGGED
:
400 case RELPERSISTENCE_PERMANENT
:
401 backend
= InvalidBackendId
;
404 elog(ERROR
, "invalid relpersistence: %c", relpersistence
);
405 return InvalidOid
; /* placate compiler */
408 /* This logic should match RelationInitPhysicalAddr */
409 rnode
.node
.spcNode
= reltablespace
? reltablespace
: MyDatabaseTableSpace
;
410 rnode
.node
.dbNode
= (rnode
.node
.spcNode
== GLOBALTABLESPACE_OID
) ? InvalidOid
: MyDatabaseId
;
413 * The relpath will vary based on the backend ID, so we must initialize
414 * that properly here to make sure that any collisions based on filename
415 * are properly detected.
417 rnode
.backend
= backend
;
421 CHECK_FOR_INTERRUPTS();
423 /* Generate the OID */
425 rnode
.node
.relNode
= GetNewOidWithIndex(pg_class
, ClassOidIndexId
,
428 rnode
.node
.relNode
= GetNewObjectId();
430 /* Check for existing file of same name */
431 rpath
= relpath(rnode
, MAIN_FORKNUM
);
433 if (access(rpath
, F_OK
) == 0)
435 /* definite collision */
441 * Here we have a little bit of a dilemma: if errno is something
442 * other than ENOENT, should we declare a collision and loop? In
443 * practice it seems best to go ahead regardless of the errno. If
444 * there is a colliding file we will get an smgr failure when we
445 * attempt to create the new relation file.
453 return rnode
.node
.relNode
;
457 * SQL callable interface for GetNewOidWithIndex(). Outside of initdb's
458 * direct insertions into catalog tables, and recovering from corruption, this
459 * should rarely be needed.
461 * Function is intentionally not documented in the user facing docs.
464 pg_nextoid(PG_FUNCTION_ARGS
)
466 Oid reloid
= PG_GETARG_OID(0);
467 Name attname
= PG_GETARG_NAME(1);
468 Oid idxoid
= PG_GETARG_OID(2);
472 Form_pg_attribute attform
;
477 * As this function is not intended to be used during normal running, and
478 * only supports system catalogs (which require superuser permissions to
479 * modify), just checking for superuser ought to not obstruct valid
484 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
485 errmsg("must be superuser to call pg_nextoid()")));
487 rel
= table_open(reloid
, RowExclusiveLock
);
488 idx
= index_open(idxoid
, RowExclusiveLock
);
490 if (!IsSystemRelation(rel
))
492 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
493 errmsg("pg_nextoid() can only be used on system catalogs")));
495 if (idx
->rd_index
->indrelid
!= RelationGetRelid(rel
))
497 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
498 errmsg("index \"%s\" does not belong to table \"%s\"",
499 RelationGetRelationName(idx
),
500 RelationGetRelationName(rel
))));
502 atttuple
= SearchSysCacheAttName(reloid
, NameStr(*attname
));
503 if (!HeapTupleIsValid(atttuple
))
505 (errcode(ERRCODE_UNDEFINED_COLUMN
),
506 errmsg("column \"%s\" of relation \"%s\" does not exist",
507 NameStr(*attname
), RelationGetRelationName(rel
))));
509 attform
= ((Form_pg_attribute
) GETSTRUCT(atttuple
));
510 attno
= attform
->attnum
;
512 if (attform
->atttypid
!= OIDOID
)
514 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
515 errmsg("column \"%s\" is not of type oid",
516 NameStr(*attname
))));
518 if (IndexRelationGetNumberOfKeyAttributes(idx
) != 1 ||
519 idx
->rd_index
->indkey
.values
[0] != attno
)
521 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
522 errmsg("index \"%s\" is not the index for column \"%s\"",
523 RelationGetRelationName(idx
),
524 NameStr(*attname
))));
526 newoid
= GetNewOidWithIndex(rel
, idxoid
, attno
);
528 ReleaseSysCache(atttuple
);
529 table_close(rel
, RowExclusiveLock
);
530 index_close(idx
, RowExclusiveLock
);