2002-03-22 22:34:44 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* pg_namespace.c
|
|
|
|
* routines to support manipulation of the pg_namespace relation
|
|
|
|
*
|
2017-01-03 19:48:53 +01:00
|
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
2002-03-22 22:34:44 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/catalog/pg_namespace.c
|
2002-03-22 22:34:44 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include "access/heapam.h"
|
2012-08-30 22:15:44 +02:00
|
|
|
#include "access/htup_details.h"
|
2005-07-07 22:40:02 +02:00
|
|
|
#include "catalog/dependency.h"
|
2002-03-22 22:34:44 +01:00
|
|
|
#include "catalog/indexing.h"
|
2010-11-25 17:48:49 +01:00
|
|
|
#include "catalog/objectaccess.h"
|
2002-03-22 22:34:44 +01:00
|
|
|
#include "catalog/pg_namespace.h"
|
|
|
|
#include "utils/builtins.h"
|
2008-06-19 02:46:06 +02:00
|
|
|
#include "utils/rel.h"
|
2002-03-22 22:34:44 +01:00
|
|
|
#include "utils/syscache.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
* NamespaceCreate
|
2012-03-08 21:52:26 +01:00
|
|
|
*
|
|
|
|
* Create a namespace (schema) with the given name and owner OID.
|
|
|
|
*
|
|
|
|
* If isTemp is true, this schema is a per-backend schema for holding
|
|
|
|
* temporary tables. Currently, the only effect of that is to prevent it
|
|
|
|
* from being linked as a member of any active extension. (If someone
|
|
|
|
* does CREATE TEMP TABLE in an extension script, we don't want the temp
|
|
|
|
* schema to become part of the extension.)
|
2002-03-22 22:34:44 +01:00
|
|
|
* ---------------
|
|
|
|
*/
|
|
|
|
Oid
|
2012-03-08 21:52:26 +01:00
|
|
|
NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
|
2002-03-22 22:34:44 +01:00
|
|
|
{
|
|
|
|
Relation nspdesc;
|
|
|
|
HeapTuple tup;
|
|
|
|
Oid nspoid;
|
2008-11-02 02:45:28 +01:00
|
|
|
bool nulls[Natts_pg_namespace];
|
2002-03-22 22:34:44 +01:00
|
|
|
Datum values[Natts_pg_namespace];
|
|
|
|
NameData nname;
|
|
|
|
TupleDesc tupDesc;
|
2011-02-08 22:08:41 +01:00
|
|
|
ObjectAddress myself;
|
2002-03-22 22:34:44 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* sanity checks */
|
|
|
|
if (!nspName)
|
|
|
|
elog(ERROR, "no namespace name supplied");
|
|
|
|
|
|
|
|
/* make sure there is no existing namespace of same name */
|
2010-02-14 19:42:19 +01:00
|
|
|
if (SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(nspName)))
|
2003-07-21 03:59:11 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_SCHEMA),
|
|
|
|
errmsg("schema \"%s\" already exists", nspName)));
|
2002-03-22 22:34:44 +01:00
|
|
|
|
|
|
|
/* initialize nulls and values */
|
|
|
|
for (i = 0; i < Natts_pg_namespace; i++)
|
|
|
|
{
|
2008-11-02 02:45:28 +01:00
|
|
|
nulls[i] = false;
|
2002-03-22 22:34:44 +01:00
|
|
|
values[i] = (Datum) NULL;
|
|
|
|
}
|
|
|
|
namestrcpy(&nname, nspName);
|
|
|
|
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
|
2005-06-28 07:09:14 +02:00
|
|
|
values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
|
2008-11-02 02:45:28 +01:00
|
|
|
nulls[Anum_pg_namespace_nspacl - 1] = true;
|
2002-03-22 22:34:44 +01:00
|
|
|
|
2005-04-14 22:03:27 +02:00
|
|
|
nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
|
2002-03-22 22:34:44 +01:00
|
|
|
tupDesc = nspdesc->rd_att;
|
2002-05-22 00:05:55 +02:00
|
|
|
|
2008-11-02 02:45:28 +01:00
|
|
|
tup = heap_form_tuple(tupDesc, values, nulls);
|
2002-08-05 05:29:17 +02:00
|
|
|
|
2002-05-22 00:05:55 +02:00
|
|
|
nspoid = simple_heap_insert(nspdesc, tup);
|
|
|
|
Assert(OidIsValid(nspoid));
|
2002-03-22 22:34:44 +01:00
|
|
|
|
2002-08-05 05:29:17 +02:00
|
|
|
CatalogUpdateIndexes(nspdesc, tup);
|
2002-03-22 22:34:44 +01:00
|
|
|
|
|
|
|
heap_close(nspdesc, RowExclusiveLock);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* Record dependencies */
|
|
|
|
myself.classId = NamespaceRelationId;
|
|
|
|
myself.objectId = nspoid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
/* dependency on owner */
|
2005-07-07 22:40:02 +02:00
|
|
|
recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
|
|
|
|
|
2012-03-08 21:52:26 +01:00
|
|
|
/* dependency on extension ... but not for magic temp schemas */
|
|
|
|
if (!isTemp)
|
|
|
|
recordDependencyOnCurrentExtension(&myself, false);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2010-11-25 17:48:49 +01:00
|
|
|
/* Post creation hook for new schema */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(NamespaceRelationId, nspoid, 0);
|
2010-11-25 17:48:49 +01:00
|
|
|
|
2002-03-22 22:34:44 +01:00
|
|
|
return nspoid;
|
|
|
|
}
|