1 /*-------------------------------------------------------------------------
4 * routines concerned with catalog naming conventions and other
5 * bits of hard-wired knowledge
8 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.68 2006/10/04 00:29:50 momjian Exp $
15 *-------------------------------------------------------------------------
23 #include "access/genam.h"
24 #include "access/transam.h"
25 #include "catalog/catalog.h"
26 #include "catalog/indexing.h"
27 #include "catalog/pg_auth_members.h"
28 #include "catalog/pg_authid.h"
29 #include "catalog/pg_database.h"
30 #include "catalog/pg_namespace.h"
31 #include "catalog/pg_pltemplate.h"
32 #include "catalog/pg_shdepend.h"
33 #include "catalog/pg_shdescription.h"
34 #include "catalog/pg_tablespace.h"
35 #include "catalog/toasting.h"
36 #include "miscadmin.h"
37 #include "storage/fd.h"
38 #include "utils/fmgroids.h"
39 #include "utils/relcache.h"
42 #define OIDCHARS 10 /* max chars printed by %u */
46 * relpath - construct path to a relation's file
48 * Result is a palloc'd string.
51 relpath(RelFileNode rnode)
56 if (rnode.spcNode == GLOBALTABLESPACE_OID)
58 /* Shared system relations live in {datadir}/global */
59 Assert(rnode.dbNode == 0);
60 pathlen = 7 + OIDCHARS + 1;
61 path = (char *) palloc(pathlen);
62 snprintf(path, pathlen, "global/%u",
65 else if (rnode.spcNode == DEFAULTTABLESPACE_OID)
67 /* The default tablespace is {datadir}/base */
68 pathlen = 5 + OIDCHARS + 1 + OIDCHARS + 1;
69 path = (char *) palloc(pathlen);
70 snprintf(path, pathlen, "base/%u/%u",
71 rnode.dbNode, rnode.relNode);
75 /* All other tablespaces are accessed via symlinks */
76 pathlen = 10 + OIDCHARS + 1 + OIDCHARS + 1 + OIDCHARS + 1;
77 path = (char *) palloc(pathlen);
78 snprintf(path, pathlen, "pg_tblspc/%u/%u/%u",
79 rnode.spcNode, rnode.dbNode, rnode.relNode);
85 * GetDatabasePath - construct path to a database dir
87 * Result is a palloc'd string.
89 * XXX this must agree with relpath()!
92 GetDatabasePath(Oid dbNode, Oid spcNode)
97 if (spcNode == GLOBALTABLESPACE_OID)
99 /* Shared system relations live in {datadir}/global */
102 path = (char *) palloc(pathlen);
103 snprintf(path, pathlen, "global");
105 else if (spcNode == DEFAULTTABLESPACE_OID)
107 /* The default tablespace is {datadir}/base */
108 pathlen = 5 + OIDCHARS + 1;
109 path = (char *) palloc(pathlen);
110 snprintf(path, pathlen, "base/%u",
115 /* All other tablespaces are accessed via symlinks */
116 pathlen = 10 + OIDCHARS + 1 + OIDCHARS + 1;
117 path = (char *) palloc(pathlen);
118 snprintf(path, pathlen, "pg_tblspc/%u/%u",
127 * True iff the relation is a system catalog relation.
129 * NB: TOAST relations are considered system relations by this test
130 * for compatibility with the old IsSystemRelationName function.
131 * This is appropriate in many places but not all. Where it's not,
132 * also check IsToastRelation.
134 * We now just test if the relation is in the system catalog namespace;
135 * so it's no longer necessary to forbid user relations from having
136 * names starting with pg_.
139 IsSystemRelation(Relation relation)
141 return IsSystemNamespace(RelationGetNamespace(relation)) ||
142 IsToastNamespace(RelationGetNamespace(relation));
147 * Like the above, but takes a Form_pg_class as argument.
148 * Used when we do not want to open the relation and have to
149 * search pg_class directly.
152 IsSystemClass(Form_pg_class reltuple)
154 Oid relnamespace = reltuple->relnamespace;
156 return IsSystemNamespace(relnamespace) ||
157 IsToastNamespace(relnamespace);
162 * True iff relation is a TOAST support relation (or index).
165 IsToastRelation(Relation relation)
167 return IsToastNamespace(RelationGetNamespace(relation));
172 * Like the above, but takes a Form_pg_class as argument.
173 * Used when we do not want to open the relation and have to
174 * search pg_class directly.
177 IsToastClass(Form_pg_class reltuple)
179 Oid relnamespace = reltuple->relnamespace;
181 return IsToastNamespace(relnamespace);
186 * True iff namespace is pg_catalog.
188 * NOTE: the reason this isn't a macro is to avoid having to include
189 * catalog/pg_namespace.h in a lot of places.
192 IsSystemNamespace(Oid namespaceId)
194 return namespaceId == PG_CATALOG_NAMESPACE;
199 * True iff namespace is pg_toast.
201 * NOTE: the reason this isn't a macro is to avoid having to include
202 * catalog/pg_namespace.h in a lot of places.
205 IsToastNamespace(Oid namespaceId)
207 return namespaceId == PG_TOAST_NAMESPACE;
213 * True iff name starts with the pg_ prefix.
215 * For some classes of objects, the prefix pg_ is reserved for
216 * system objects only. As of 8.0, this is only true for
217 * schema and tablespace names.
220 IsReservedName(const char *name)
222 /* ugly coding for speed */
223 return (name[0] == 'p' &&
231 * Given the OID of a relation, determine whether it's supposed to be
232 * shared across an entire database cluster.
234 * Hard-wiring this list is pretty grotty, but we really need it so that
235 * we can compute the locktag for a relation (and then lock it) without
236 * having already read its pg_class entry. If we try to retrieve relisshared
237 * from pg_class with no pre-existing lock, there is a race condition against
238 * anyone who is concurrently committing a change to the pg_class entry:
239 * since we read system catalog entries under SnapshotNow, it's possible
240 * that both the old and new versions of the row are invalid at the instants
241 * we scan them. We fix this by insisting that updaters of a pg_class
242 * row must hold exclusive lock on the corresponding rel, and that users
243 * of a relation must hold at least AccessShareLock on the rel *before*
244 * trying to open its relcache entry. But to lock a rel, you have to
245 * know if it's shared. Fortunately, the set of shared relations is
246 * fairly static, so a hand-maintained list of their OIDs isn't completely
250 IsSharedRelation(Oid relationId)
252 /* These are the shared catalogs (look for BKI_SHARED_RELATION) */
253 if (relationId == AuthIdRelationId ||
254 relationId == AuthMemRelationId ||
255 relationId == DatabaseRelationId ||
256 relationId == PLTemplateRelationId ||
257 relationId == SharedDescriptionRelationId ||
258 relationId == SharedDependRelationId ||
259 relationId == TableSpaceRelationId)
261 /* These are their indexes (see indexing.h) */
262 if (relationId == AuthIdRolnameIndexId ||
263 relationId == AuthIdOidIndexId ||
264 relationId == AuthMemRoleMemIndexId ||
265 relationId == AuthMemMemRoleIndexId ||
266 relationId == DatabaseNameIndexId ||
267 relationId == DatabaseOidIndexId ||
268 relationId == PLTemplateNameIndexId ||
269 relationId == SharedDescriptionObjIndexId ||
270 relationId == SharedDependDependerIndexId ||
271 relationId == SharedDependReferenceIndexId ||
272 relationId == TablespaceOidIndexId ||
273 relationId == TablespaceNameIndexId)
275 /* These are their toast tables and toast indexes (see toasting.h) */
276 if (relationId == PgAuthidToastTable ||
277 relationId == PgAuthidToastIndex ||
278 relationId == PgDatabaseToastTable ||
279 relationId == PgDatabaseToastIndex ||
280 relationId == PgShdescriptionToastTable ||
281 relationId == PgShdescriptionToastIndex)
289 * Generate a new OID that is unique within the given relation.
291 * Caller must have a suitable lock on the relation.
293 * Uniqueness is promised only if the relation has a unique index on OID.
294 * This is true for all system catalogs that have OIDs, but might not be
295 * true for user tables. Note that we are effectively assuming that the
296 * table has a relatively small number of entries (much less than 2^32)
297 * and there aren't very long runs of consecutive existing OIDs. Again,
298 * this is reasonable for system catalogs but less so for user tables.
300 * Since the OID is not immediately inserted into the table, there is a
301 * race condition here; but a problem could occur only if someone else
302 * managed to cycle through 2^32 OIDs and generate the same OID before we
303 * finish inserting our row. This seems unlikely to be a problem. Note
304 * that if we had to *commit* the row to end the race condition, the risk
305 * would be rather higher; therefore we use SnapshotDirty in the test,
306 * so that we will see uncommitted rows.
309 GetNewOid(Relation relation)
315 /* If relation doesn't have OIDs at all, caller is confused */
316 Assert(relation->rd_rel->relhasoids);
318 /* In bootstrap mode, we don't have any indexes to use */
319 if (IsBootstrapProcessingMode())
320 return GetNewObjectId();
322 /* The relcache will cache the identity of the OID index for us */
323 oidIndex = RelationGetOidIndex(relation);
325 /* If no OID index, just hand back the next OID counter value */
326 if (!OidIsValid(oidIndex))
329 * System catalogs that have OIDs should *always* have a unique OID
330 * index; we should only take this path for user tables. Give a
331 * warning if it looks like somebody forgot an index.
333 if (IsSystemRelation(relation))
334 elog(WARNING, "generating possibly-non-unique OID for \"%s\"",
335 RelationGetRelationName(relation));
337 return GetNewObjectId();
340 /* Otherwise, use the index to find a nonconflicting OID */
341 indexrel = index_open(oidIndex, AccessShareLock);
342 newOid = GetNewOidWithIndex(relation, indexrel);
343 index_close(indexrel, AccessShareLock);
350 * Guts of GetNewOid: use the supplied index
352 * This is exported separately because there are cases where we want to use
353 * an index that will not be recognized by RelationGetOidIndex: TOAST tables
354 * and pg_largeobject have indexes that are usable, but have multiple columns
355 * and are on ordinary columns rather than a true OID column. This code
356 * will work anyway, so long as the OID is the index's first column.
358 * Caller must have a suitable lock on the relation.
361 GetNewOidWithIndex(Relation relation, Relation indexrel)
368 /* Generate new OIDs until we find one not in the table */
371 newOid = GetNewObjectId();
375 BTEqualStrategyNumber, F_OIDEQ,
376 ObjectIdGetDatum(newOid));
378 /* see notes above about using SnapshotDirty */
379 scan = index_beginscan(relation, indexrel,
380 SnapshotDirty, 1, &key);
382 collides = HeapTupleIsValid(index_getnext(scan, ForwardScanDirection));
392 * Generate a new relfilenode number that is unique within the given
395 * If the relfilenode will also be used as the relation's OID, pass the
396 * opened pg_class catalog, and this routine will guarantee that the result
397 * is also an unused OID within pg_class. If the result is to be used only
398 * as a relfilenode for an existing relation, pass NULL for pg_class.
400 * As with GetNewOid, there is some theoretical risk of a race condition,
401 * but it doesn't seem worth worrying about.
403 * Note: we don't support using this in bootstrap mode. All relations
404 * created by bootstrap have preassigned OIDs, so there's no need.
407 GetNewRelFileNode(Oid reltablespace, bool relisshared, Relation pg_class)
414 /* This should match RelationInitPhysicalAddr */
415 rnode.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
416 rnode.dbNode = relisshared ? InvalidOid : MyDatabaseId;
420 /* Generate the OID */
422 rnode.relNode = GetNewOid(pg_class);
424 rnode.relNode = GetNewObjectId();
426 /* Check for existing file of same name */
427 rpath = relpath(rnode);
428 fd = BasicOpenFile(rpath, O_RDONLY | PG_BINARY, 0);
432 /* definite collision */
439 * Here we have a little bit of a dilemma: if errno is something
440 * other than ENOENT, should we declare a collision and loop? In
441 * particular one might think this advisable for, say, EPERM.
442 * However there really shouldn't be any unreadable files in a
443 * tablespace directory, and if the EPERM is actually complaining
444 * that we can't read the directory itself, we'd be in an infinite
445 * loop. In practice it seems best to go ahead regardless of the
446 * errno. If there is a colliding file we will get an smgr
447 * failure when we attempt to create the new relation file.
455 return rnode.relNode;