1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* catalog.c
|
2002-04-12 22:38:31 +02:00
|
|
|
* routines concerned with catalog naming conventions
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2003-08-04 04:40:20 +02:00
|
|
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2004-06-18 08:14:31 +02:00
|
|
|
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.52 2004/06/18 06:13:19 tgl Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1997-01-10 21:19:49 +01:00
|
|
|
|
1999-07-16 01:04:24 +02:00
|
|
|
#include "postgres.h"
|
1996-11-04 00:27:08 +01:00
|
|
|
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "access/transam.h"
|
|
|
|
#include "catalog/catalog.h"
|
1999-07-16 05:14:30 +02:00
|
|
|
#include "catalog/catname.h"
|
2002-04-12 22:38:31 +02:00
|
|
|
#include "catalog/pg_namespace.h"
|
2004-06-18 08:14:31 +02:00
|
|
|
#include "catalog/pg_tablespace.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "miscadmin.h"
|
2002-04-12 22:38:31 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
#define OIDCHARS 10 /* max chars printed by %u */
|
|
|
|
|
|
|
|
|
2000-10-16 16:52:28 +02:00
|
|
|
/*
|
|
|
|
* relpath - construct path to a relation's file
|
|
|
|
*
|
|
|
|
* Result is a palloc'd string.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
relpath(RelFileNode rnode)
|
|
|
|
{
|
2004-06-18 08:14:31 +02:00
|
|
|
int pathlen;
|
2000-10-16 16:52:28 +02:00
|
|
|
char *path;
|
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
if (rnode.spcNode == GLOBALTABLESPACE_OID)
|
2000-10-16 16:52:28 +02:00
|
|
|
{
|
|
|
|
/* Shared system relations live in {datadir}/global */
|
2004-06-18 08:14:31 +02:00
|
|
|
Assert(rnode.dbNode == 0);
|
|
|
|
pathlen = strlen(DataDir) + 8 + OIDCHARS + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/global/%u",
|
|
|
|
DataDir, rnode.relNode);
|
|
|
|
}
|
|
|
|
else if (rnode.spcNode == DEFAULTTABLESPACE_OID)
|
|
|
|
{
|
|
|
|
/* The default tablespace is {datadir}/base */
|
|
|
|
pathlen = strlen(DataDir) + 6 + OIDCHARS + 1 + OIDCHARS + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/base/%u/%u",
|
|
|
|
DataDir, rnode.dbNode, rnode.relNode);
|
2000-10-16 16:52:28 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-06-18 08:14:31 +02:00
|
|
|
/* All other tablespaces are accessed via symlinks */
|
|
|
|
pathlen = strlen(DataDir) + 16 + OIDCHARS + 1 + OIDCHARS + 1 + OIDCHARS + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/pg_tablespaces/%u/%u/%u",
|
|
|
|
DataDir, rnode.spcNode, rnode.dbNode, rnode.relNode);
|
2000-10-16 16:52:28 +02:00
|
|
|
}
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetDatabasePath - construct path to a database dir
|
|
|
|
*
|
|
|
|
* Result is a palloc'd string.
|
2004-06-18 08:14:31 +02:00
|
|
|
*
|
|
|
|
* XXX this must agree with relpath()!
|
2000-10-16 16:52:28 +02:00
|
|
|
*/
|
|
|
|
char *
|
2004-06-18 08:14:31 +02:00
|
|
|
GetDatabasePath(Oid dbNode, Oid spcNode)
|
2000-10-16 16:52:28 +02:00
|
|
|
{
|
2004-06-18 08:14:31 +02:00
|
|
|
int pathlen;
|
2000-10-16 16:52:28 +02:00
|
|
|
char *path;
|
|
|
|
|
2004-06-18 08:14:31 +02:00
|
|
|
if (spcNode == GLOBALTABLESPACE_OID)
|
2000-10-16 16:52:28 +02:00
|
|
|
{
|
|
|
|
/* Shared system relations live in {datadir}/global */
|
2004-06-18 08:14:31 +02:00
|
|
|
Assert(dbNode == 0);
|
|
|
|
pathlen = strlen(DataDir) + 7 + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/global",
|
|
|
|
DataDir);
|
|
|
|
}
|
|
|
|
else if (spcNode == DEFAULTTABLESPACE_OID)
|
|
|
|
{
|
|
|
|
/* The default tablespace is {datadir}/base */
|
|
|
|
pathlen = strlen(DataDir) + 6 + OIDCHARS + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/base/%u",
|
|
|
|
DataDir, dbNode);
|
2000-10-16 16:52:28 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-06-18 08:14:31 +02:00
|
|
|
/* All other tablespaces are accessed via symlinks */
|
|
|
|
pathlen = strlen(DataDir) + 16 + OIDCHARS + 1 + OIDCHARS + 1;
|
|
|
|
path = (char *) palloc(pathlen);
|
|
|
|
snprintf(path, pathlen, "%s/pg_tablespaces/%u/%u",
|
|
|
|
DataDir, spcNode, dbNode);
|
2000-10-16 16:52:28 +02:00
|
|
|
}
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2000-04-09 06:43:20 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
2002-04-12 22:38:31 +02:00
|
|
|
* IsSystemRelation
|
|
|
|
* True iff the relation is a system catalog relation.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-04-12 22:38:31 +02:00
|
|
|
* NB: TOAST relations are considered system relations by this test
|
|
|
|
* for compatibility with the old IsSystemRelationName function.
|
2001-11-17 00:30:35 +01:00
|
|
|
* This is appropriate in many places but not all. Where it's not,
|
2002-04-12 22:38:31 +02:00
|
|
|
* also check IsToastRelation.
|
2001-11-17 00:30:35 +01:00
|
|
|
*
|
2002-04-12 22:38:31 +02:00
|
|
|
* We now just test if the relation is in the system catalog namespace;
|
|
|
|
* so it's no longer necessary to forbid user relations from having
|
|
|
|
* names starting with pg_. Now only schema names have the pg_
|
|
|
|
* distinction/requirement.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsSystemRelation(Relation relation)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
return IsSystemNamespace(RelationGetNamespace(relation)) ||
|
|
|
|
IsToastNamespace(RelationGetNamespace(relation));
|
2002-04-12 22:38:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IsSystemClass
|
|
|
|
* Like the above, but takes a Form_pg_class as argument.
|
|
|
|
* Used when we do not want to open the relation and have to
|
|
|
|
* search pg_class directly.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsSystemClass(Form_pg_class reltuple)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
Oid relnamespace = reltuple->relnamespace;
|
2002-04-12 22:38:31 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
return IsSystemNamespace(relnamespace) ||
|
|
|
|
IsToastNamespace(relnamespace);
|
2002-04-12 22:38:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IsToastRelation
|
|
|
|
* True iff relation is a TOAST support relation (or index).
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsToastRelation(Relation relation)
|
|
|
|
{
|
|
|
|
return IsToastNamespace(RelationGetNamespace(relation));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IsToastClass
|
|
|
|
* Like the above, but takes a Form_pg_class as argument.
|
|
|
|
* Used when we do not want to open the relation and have to
|
|
|
|
* search pg_class directly.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsToastClass(Form_pg_class reltuple)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
Oid relnamespace = reltuple->relnamespace;
|
2002-04-12 22:38:31 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
return IsToastNamespace(relnamespace);
|
2002-04-12 22:38:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IsSystemNamespace
|
|
|
|
* True iff namespace is pg_catalog.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-04-12 22:38:31 +02:00
|
|
|
* NOTE: the reason this isn't a macro is to avoid having to include
|
|
|
|
* catalog/pg_namespace.h in a lot of places.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
bool
|
2002-04-12 22:38:31 +02:00
|
|
|
IsSystemNamespace(Oid namespaceId)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2002-04-12 22:38:31 +02:00
|
|
|
return namespaceId == PG_CATALOG_NAMESPACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IsToastNamespace
|
|
|
|
* True iff namespace is pg_toast.
|
|
|
|
*
|
|
|
|
* NOTE: the reason this isn't a macro is to avoid having to include
|
|
|
|
* catalog/pg_namespace.h in a lot of places.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsToastNamespace(Oid namespaceId)
|
|
|
|
{
|
|
|
|
return namespaceId == PG_TOAST_NAMESPACE;
|
2001-11-17 00:30:35 +01:00
|
|
|
}
|
|
|
|
|
2002-04-12 22:38:31 +02:00
|
|
|
|
2001-11-17 00:30:35 +01:00
|
|
|
/*
|
2002-04-12 22:38:31 +02:00
|
|
|
* IsReservedName
|
|
|
|
* True iff name starts with the pg_ prefix.
|
|
|
|
*
|
2004-01-06 19:07:32 +01:00
|
|
|
* For some classes of objects, the prefix pg_ is reserved for
|
|
|
|
* system objects only. As of 7.3, this is now only true for
|
|
|
|
* schema names.
|
2001-11-17 00:30:35 +01:00
|
|
|
*/
|
|
|
|
bool
|
2002-04-12 22:38:31 +02:00
|
|
|
IsReservedName(const char *name)
|
2001-11-17 00:30:35 +01:00
|
|
|
{
|
2002-04-12 22:38:31 +02:00
|
|
|
/* ugly coding for speed */
|
|
|
|
return (name[0] == 'p' &&
|
|
|
|
name[1] == 'g' &&
|
|
|
|
name[2] == '_');
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
2002-04-12 22:38:31 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* newoid - returns a unique identifier across all catalogs.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* Object Id allocation is now done by GetNewObjectID in
|
2001-08-10 20:57:42 +02:00
|
|
|
* access/transam/varsup.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2001-08-10 20:57:42 +02:00
|
|
|
* This code probably needs to change to generate OIDs separately
|
|
|
|
* for each table.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
Oid
|
2000-12-28 00:59:14 +01:00
|
|
|
newoid(void)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2001-08-10 20:57:42 +02:00
|
|
|
return GetNewObjectId();
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|