Make nbtree split REDO locking match original execution.
[pgsql.git] / src / backend / catalog / catalog.c
blob7d6acaed92c9e6fd5227f782c454341cf092b08a
1 /*-------------------------------------------------------------------------
3 * catalog.c
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
12 * IDENTIFICATION
13 * src/backend/catalog/catalog.c
15 *-------------------------------------------------------------------------
18 #include "postgres.h"
20 #include <fcntl.h>
21 #include <unistd.h>
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"
53 * IsSystemRelation
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!
67 bool
68 IsSystemRelation(Relation relation)
70 return IsSystemClass(RelationGetRelid(relation), relation->rd_rel);
74 * IsSystemClass
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.
79 bool
80 IsSystemClass(Oid relid, Form_pg_class reltuple)
82 /* IsCatalogRelationOid is a bit faster, so test that first */
83 return (IsCatalogRelationOid(relid) || IsToastClass(reltuple));
87 * IsCatalogRelation
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!
97 bool
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!
114 bool
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);
134 * IsToastRelation
135 * True iff relation is a TOAST support relation (or index).
137 * Does not perform any catalog accesses.
139 bool
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));
154 * IsToastClass
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.
159 bool
160 IsToastClass(Form_pg_class reltuple)
162 Oid relnamespace = reltuple->relnamespace;
164 return IsToastNamespace(relnamespace);
168 * IsCatalogNamespace
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.
176 bool
177 IsCatalogNamespace(Oid namespaceId)
179 return namespaceId == PG_CATALOG_NAMESPACE;
183 * IsToastNamespace
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.
194 bool
195 IsToastNamespace(Oid namespaceId)
197 return (namespaceId == PG_TOAST_NAMESPACE) ||
198 isTempToastNamespace(namespaceId);
203 * IsReservedName
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
209 * for roles.
211 bool
212 IsReservedName(const char *name)
214 /* ugly coding for speed */
215 return (name[0] == 'p' &&
216 name[1] == 'g' &&
217 name[2] == '_');
222 * IsSharedRelation
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.
237 bool
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)
251 return true;
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)
270 return true;
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)
288 return true;
289 return false;
294 * GetNewOidWithIndex
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
312 * system catalogs.
314 * Caller must have a suitable lock on the relation.
317 GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
319 Oid newOid;
320 SysScanDesc scan;
321 ScanKeyData key;
322 bool collides;
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();
346 ScanKeyInit(&key,
347 oidcolumn,
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);
358 } while (collides);
360 return newOid;
364 * GetNewRelFileNode
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;
383 char *rpath;
384 bool collides;
385 BackendId backend;
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();
398 break;
399 case RELPERSISTENCE_UNLOGGED:
400 case RELPERSISTENCE_PERMANENT:
401 backend = InvalidBackendId;
402 break;
403 default:
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 */
424 if (pg_class)
425 rnode.node.relNode = GetNewOidWithIndex(pg_class, ClassOidIndexId,
426 Anum_pg_class_oid);
427 else
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 */
436 collides = true;
438 else
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.
447 collides = false;
450 pfree(rpath);
451 } while (collides);
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.
463 Datum
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);
469 Relation rel;
470 Relation idx;
471 HeapTuple atttuple;
472 Form_pg_attribute attform;
473 AttrNumber attno;
474 Oid newoid;
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
480 * usecases.
482 if (!superuser())
483 ereport(ERROR,
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))
491 ereport(ERROR,
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))
496 ereport(ERROR,
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))
504 ereport(ERROR,
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)
513 ereport(ERROR,
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)
520 ereport(ERROR,
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);
532 return newoid;