Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_namespace.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pg_namespace.c
00004  *    routines to support manipulation of the pg_namespace relation
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/catalog/pg_namespace.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include "access/heapam.h"
00018 #include "access/htup_details.h"
00019 #include "catalog/dependency.h"
00020 #include "catalog/indexing.h"
00021 #include "catalog/objectaccess.h"
00022 #include "catalog/pg_namespace.h"
00023 #include "utils/builtins.h"
00024 #include "utils/rel.h"
00025 #include "utils/syscache.h"
00026 
00027 
00028 /* ----------------
00029  * NamespaceCreate
00030  *
00031  * Create a namespace (schema) with the given name and owner OID.
00032  *
00033  * If isTemp is true, this schema is a per-backend schema for holding
00034  * temporary tables.  Currently, the only effect of that is to prevent it
00035  * from being linked as a member of any active extension.  (If someone
00036  * does CREATE TEMP TABLE in an extension script, we don't want the temp
00037  * schema to become part of the extension.)
00038  * ---------------
00039  */
00040 Oid
00041 NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
00042 {
00043     Relation    nspdesc;
00044     HeapTuple   tup;
00045     Oid         nspoid;
00046     bool        nulls[Natts_pg_namespace];
00047     Datum       values[Natts_pg_namespace];
00048     NameData    nname;
00049     TupleDesc   tupDesc;
00050     ObjectAddress myself;
00051     int         i;
00052 
00053     /* sanity checks */
00054     if (!nspName)
00055         elog(ERROR, "no namespace name supplied");
00056 
00057     /* make sure there is no existing namespace of same name */
00058     if (SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(nspName)))
00059         ereport(ERROR,
00060                 (errcode(ERRCODE_DUPLICATE_SCHEMA),
00061                  errmsg("schema \"%s\" already exists", nspName)));
00062 
00063     /* initialize nulls and values */
00064     for (i = 0; i < Natts_pg_namespace; i++)
00065     {
00066         nulls[i] = false;
00067         values[i] = (Datum) NULL;
00068     }
00069     namestrcpy(&nname, nspName);
00070     values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
00071     values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
00072     nulls[Anum_pg_namespace_nspacl - 1] = true;
00073 
00074     nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
00075     tupDesc = nspdesc->rd_att;
00076 
00077     tup = heap_form_tuple(tupDesc, values, nulls);
00078 
00079     nspoid = simple_heap_insert(nspdesc, tup);
00080     Assert(OidIsValid(nspoid));
00081 
00082     CatalogUpdateIndexes(nspdesc, tup);
00083 
00084     heap_close(nspdesc, RowExclusiveLock);
00085 
00086     /* Record dependencies */
00087     myself.classId = NamespaceRelationId;
00088     myself.objectId = nspoid;
00089     myself.objectSubId = 0;
00090 
00091     /* dependency on owner */
00092     recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
00093 
00094     /* dependency on extension ... but not for magic temp schemas */
00095     if (!isTemp)
00096         recordDependencyOnCurrentExtension(&myself, false);
00097 
00098     /* Post creation hook for new schema */
00099     InvokeObjectPostCreateHook(NamespaceRelationId, nspoid, 0);
00100 
00101     return nspoid;
00102 }