LCOV - code coverage report
Current view: top level - src/backend/catalog - pg_namespace.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 32 33 97.0 %
Date: 2024-04-19 12:11:01 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_namespace.c
       4             :  *    routines to support manipulation of the pg_namespace relation
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/catalog/pg_namespace.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include "access/htup_details.h"
      18             : #include "access/table.h"
      19             : #include "catalog/catalog.h"
      20             : #include "catalog/dependency.h"
      21             : #include "catalog/indexing.h"
      22             : #include "catalog/objectaccess.h"
      23             : #include "catalog/pg_namespace.h"
      24             : #include "utils/builtins.h"
      25             : #include "utils/rel.h"
      26             : #include "utils/syscache.h"
      27             : 
      28             : 
      29             : /* ----------------
      30             :  * NamespaceCreate
      31             :  *
      32             :  * Create a namespace (schema) with the given name and owner OID.
      33             :  *
      34             :  * If isTemp is true, this schema is a per-backend schema for holding
      35             :  * temporary tables.  Currently, it is used to prevent it from being
      36             :  * linked as a member of any active extension.  (If someone does CREATE
      37             :  * TEMP TABLE in an extension script, we don't want the temp schema to
      38             :  * become part of the extension). And to avoid checking for default ACL
      39             :  * for temp namespace (as it is not necessary).
      40             :  * ---------------
      41             :  */
      42             : Oid
      43        1710 : NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
      44             : {
      45             :     Relation    nspdesc;
      46             :     HeapTuple   tup;
      47             :     Oid         nspoid;
      48             :     bool        nulls[Natts_pg_namespace];
      49             :     Datum       values[Natts_pg_namespace];
      50             :     NameData    nname;
      51             :     TupleDesc   tupDesc;
      52             :     ObjectAddress myself;
      53             :     int         i;
      54             :     Acl        *nspacl;
      55             : 
      56             :     /* sanity checks */
      57        1710 :     if (!nspName)
      58           0 :         elog(ERROR, "no namespace name supplied");
      59             : 
      60             :     /* make sure there is no existing namespace of same name */
      61        1710 :     if (SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(nspName)))
      62           6 :         ereport(ERROR,
      63             :                 (errcode(ERRCODE_DUPLICATE_SCHEMA),
      64             :                  errmsg("schema \"%s\" already exists", nspName)));
      65             : 
      66        1704 :     if (!isTemp)
      67         924 :         nspacl = get_user_default_acl(OBJECT_SCHEMA, ownerId,
      68             :                                       InvalidOid);
      69             :     else
      70         780 :         nspacl = NULL;
      71             : 
      72        1704 :     nspdesc = table_open(NamespaceRelationId, RowExclusiveLock);
      73        1704 :     tupDesc = nspdesc->rd_att;
      74             : 
      75             :     /* initialize nulls and values */
      76        8520 :     for (i = 0; i < Natts_pg_namespace; i++)
      77             :     {
      78        6816 :         nulls[i] = false;
      79        6816 :         values[i] = (Datum) NULL;
      80             :     }
      81             : 
      82        1704 :     nspoid = GetNewOidWithIndex(nspdesc, NamespaceOidIndexId,
      83             :                                 Anum_pg_namespace_oid);
      84        1704 :     values[Anum_pg_namespace_oid - 1] = ObjectIdGetDatum(nspoid);
      85        1704 :     namestrcpy(&nname, nspName);
      86        1704 :     values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
      87        1704 :     values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
      88        1704 :     if (nspacl != NULL)
      89          12 :         values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(nspacl);
      90             :     else
      91        1692 :         nulls[Anum_pg_namespace_nspacl - 1] = true;
      92             : 
      93             : 
      94        1704 :     tup = heap_form_tuple(tupDesc, values, nulls);
      95             : 
      96        1704 :     CatalogTupleInsert(nspdesc, tup);
      97             :     Assert(OidIsValid(nspoid));
      98             : 
      99        1704 :     table_close(nspdesc, RowExclusiveLock);
     100             : 
     101             :     /* Record dependencies */
     102        1704 :     myself.classId = NamespaceRelationId;
     103        1704 :     myself.objectId = nspoid;
     104        1704 :     myself.objectSubId = 0;
     105             : 
     106             :     /* dependency on owner */
     107        1704 :     recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
     108             : 
     109             :     /* dependencies on roles mentioned in default ACL */
     110        1704 :     recordDependencyOnNewAcl(NamespaceRelationId, nspoid, 0, ownerId, nspacl);
     111             : 
     112             :     /* dependency on extension ... but not for magic temp schemas */
     113        1704 :     if (!isTemp)
     114         924 :         recordDependencyOnCurrentExtension(&myself, false);
     115             : 
     116             :     /* Post creation hook for new schema */
     117        1704 :     InvokeObjectPostCreateHook(NamespaceRelationId, nspoid, 0);
     118             : 
     119        1704 :     return nspoid;
     120             : }

Generated by: LCOV version 1.14