LCOV - code coverage report
Current view: top level - src/backend/commands - schemacmds.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 86.9 % 176 153
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 5 5
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 45.7 % 92 42

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * schemacmds.c
       4                 :             :  *        schema creation/manipulation commands
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/commands/schemacmds.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : #include "postgres.h"
      16                 :             : 
      17                 :             : #include "access/htup_details.h"
      18                 :             : #include "access/table.h"
      19                 :             : #include "access/xact.h"
      20                 :             : #include "catalog/catalog.h"
      21                 :             : #include "catalog/dependency.h"
      22                 :             : #include "catalog/indexing.h"
      23                 :             : #include "catalog/namespace.h"
      24                 :             : #include "catalog/objectaccess.h"
      25                 :             : #include "catalog/pg_authid.h"
      26                 :             : #include "catalog/pg_database.h"
      27                 :             : #include "catalog/pg_namespace.h"
      28                 :             : #include "commands/event_trigger.h"
      29                 :             : #include "commands/schemacmds.h"
      30                 :             : #include "miscadmin.h"
      31                 :             : #include "parser/parse_utilcmd.h"
      32                 :             : #include "parser/scansup.h"
      33                 :             : #include "tcop/utility.h"
      34                 :             : #include "utils/acl.h"
      35                 :             : #include "utils/builtins.h"
      36                 :             : #include "utils/lsyscache.h"
      37                 :             : #include "utils/rel.h"
      38                 :             : #include "utils/syscache.h"
      39                 :             : 
      40                 :             : static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId);
      41                 :             : 
      42                 :             : /*
      43                 :             :  * CREATE SCHEMA
      44                 :             :  *
      45                 :             :  * Note: caller should pass in location information for the whole
      46                 :             :  * CREATE SCHEMA statement, which in turn we pass down as the location
      47                 :             :  * of the component commands.  This comports with our general plan of
      48                 :             :  * reporting location/len for the whole command even when executing
      49                 :             :  * a subquery.
      50                 :             :  */
      51                 :             : Oid
      52                 :         123 : CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
      53                 :             :                                         int stmt_location, int stmt_len)
      54                 :             : {
      55                 :         123 :         const char *schemaName = stmt->schemaname;
      56                 :         123 :         Oid                     namespaceId;
      57                 :         123 :         List       *parsetree_list;
      58                 :         123 :         ListCell   *parsetree_item;
      59                 :         123 :         Oid                     owner_uid;
      60                 :         123 :         Oid                     saved_uid;
      61                 :         123 :         int                     save_sec_context;
      62                 :         123 :         int                     save_nestlevel;
      63                 :         123 :         char       *nsp = namespace_search_path;
      64                 :         123 :         AclResult       aclresult;
      65                 :         123 :         ObjectAddress address;
      66                 :         123 :         StringInfoData pathbuf;
      67                 :             : 
      68                 :         123 :         GetUserIdAndSecContext(&saved_uid, &save_sec_context);
      69                 :             : 
      70                 :             :         /*
      71                 :             :          * Who is supposed to own the new schema?
      72                 :             :          */
      73         [ +  + ]:         123 :         if (stmt->authrole)
      74                 :          23 :                 owner_uid = get_rolespec_oid(stmt->authrole, false);
      75                 :             :         else
      76                 :         100 :                 owner_uid = saved_uid;
      77                 :             : 
      78                 :             :         /* fill schema name with the user name if not specified */
      79         [ +  + ]:         123 :         if (!schemaName)
      80                 :             :         {
      81                 :          12 :                 HeapTuple       tuple;
      82                 :             : 
      83                 :          12 :                 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid));
      84         [ +  - ]:          12 :                 if (!HeapTupleIsValid(tuple))
      85   [ #  #  #  # ]:           0 :                         elog(ERROR, "cache lookup failed for role %u", owner_uid);
      86                 :          12 :                 schemaName =
      87                 :          12 :                         pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
      88                 :          12 :                 ReleaseSysCache(tuple);
      89                 :          12 :         }
      90                 :             : 
      91                 :             :         /*
      92                 :             :          * To create a schema, must have schema-create privilege on the current
      93                 :             :          * database and must be able to become the target role (this does not
      94                 :             :          * imply that the target role itself must have create-schema privilege).
      95                 :             :          * The latter provision guards against "giveaway" attacks.  Note that a
      96                 :             :          * superuser will always have both of these privileges a fortiori.
      97                 :             :          */
      98                 :         123 :         aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, saved_uid, ACL_CREATE);
      99         [ +  - ]:         123 :         if (aclresult != ACLCHECK_OK)
     100                 :           0 :                 aclcheck_error(aclresult, OBJECT_DATABASE,
     101                 :           0 :                                            get_database_name(MyDatabaseId));
     102                 :             : 
     103                 :         123 :         check_can_set_role(saved_uid, owner_uid);
     104                 :             : 
     105                 :             :         /* Additional check to protect reserved schema names */
     106   [ +  +  +  - ]:         123 :         if (!allowSystemTableMods && IsReservedName(schemaName))
     107   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     108                 :             :                                 (errcode(ERRCODE_RESERVED_NAME),
     109                 :             :                                  errmsg("unacceptable schema name \"%s\"", schemaName),
     110                 :             :                                  errdetail("The prefix \"pg_\" is reserved for system schemas.")));
     111                 :             : 
     112                 :             :         /*
     113                 :             :          * If if_not_exists was given and the schema already exists, bail out.
     114                 :             :          * (Note: we needn't check this when not if_not_exists, because
     115                 :             :          * NamespaceCreate will complain anyway.)  We could do this before making
     116                 :             :          * the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its
     117                 :             :          * creation-permission check first, we do likewise.
     118                 :             :          */
     119         [ +  + ]:         123 :         if (stmt->if_not_exists)
     120                 :             :         {
     121                 :           1 :                 namespaceId = get_namespace_oid(schemaName, true);
     122         [ +  - ]:           1 :                 if (OidIsValid(namespaceId))
     123                 :             :                 {
     124                 :             :                         /*
     125                 :             :                          * If we are in an extension script, insist that the pre-existing
     126                 :             :                          * object be a member of the extension, to avoid security risks.
     127                 :             :                          */
     128                 :           1 :                         ObjectAddressSet(address, NamespaceRelationId, namespaceId);
     129                 :           1 :                         checkMembershipInCurrentExtension(&address);
     130                 :             : 
     131                 :             :                         /* OK to skip */
     132   [ -  +  +  - ]:           1 :                         ereport(NOTICE,
     133                 :             :                                         (errcode(ERRCODE_DUPLICATE_SCHEMA),
     134                 :             :                                          errmsg("schema \"%s\" already exists, skipping",
     135                 :             :                                                         schemaName)));
     136                 :           1 :                         return InvalidOid;
     137                 :             :                 }
     138                 :           0 :         }
     139                 :             : 
     140                 :             :         /*
     141                 :             :          * If the requested authorization is different from the current user,
     142                 :             :          * temporarily set the current user so that the object(s) will be created
     143                 :             :          * with the correct ownership.
     144                 :             :          *
     145                 :             :          * (The setting will be restored at the end of this routine, or in case of
     146                 :             :          * error, transaction abort will clean things up.)
     147                 :             :          */
     148         [ +  + ]:         122 :         if (saved_uid != owner_uid)
     149                 :          20 :                 SetUserIdAndSecContext(owner_uid,
     150                 :          10 :                                                            save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
     151                 :             : 
     152                 :             :         /* Create the schema's namespace */
     153                 :         122 :         namespaceId = NamespaceCreate(schemaName, owner_uid, false);
     154                 :             : 
     155                 :             :         /* Advance cmd counter to make the namespace visible */
     156                 :         122 :         CommandCounterIncrement();
     157                 :             : 
     158                 :             :         /*
     159                 :             :          * Prepend the new schema to the current search path.
     160                 :             :          *
     161                 :             :          * We use the equivalent of a function SET option to allow the setting to
     162                 :             :          * persist for exactly the duration of the schema creation.  guc.c also
     163                 :             :          * takes care of undoing the setting on error.
     164                 :             :          */
     165                 :         122 :         save_nestlevel = NewGUCNestLevel();
     166                 :             : 
     167                 :         122 :         initStringInfo(&pathbuf);
     168                 :         122 :         appendStringInfoString(&pathbuf, quote_identifier(schemaName));
     169                 :             : 
     170         [ +  + ]:         123 :         while (scanner_isspace(*nsp))
     171                 :           1 :                 nsp++;
     172                 :             : 
     173         [ +  + ]:         122 :         if (*nsp != '\0')
     174                 :         119 :                 appendStringInfo(&pathbuf, ", %s", nsp);
     175                 :             : 
     176                 :         122 :         (void) set_config_option("search_path", pathbuf.data,
     177                 :             :                                                          PGC_USERSET, PGC_S_SESSION,
     178                 :             :                                                          GUC_ACTION_SAVE, true, 0, false);
     179                 :             : 
     180                 :             :         /*
     181                 :             :          * Report the new schema to possibly interested event triggers.  Note we
     182                 :             :          * must do this here and not in ProcessUtilitySlow because otherwise the
     183                 :             :          * objects created below are reported before the schema, which would be
     184                 :             :          * wrong.
     185                 :             :          */
     186                 :         122 :         ObjectAddressSet(address, NamespaceRelationId, namespaceId);
     187                 :         122 :         EventTriggerCollectSimpleCommand(address, InvalidObjectAddress,
     188                 :         122 :                                                                          (Node *) stmt);
     189                 :             : 
     190                 :             :         /*
     191                 :             :          * Examine the list of commands embedded in the CREATE SCHEMA command, and
     192                 :             :          * reorganize them into a sequentially executable order with no forward
     193                 :             :          * references.  Note that the result is still a list of raw parsetrees ---
     194                 :             :          * we cannot, in general, run parse analysis on one statement until we
     195                 :             :          * have actually executed the prior ones.
     196                 :             :          */
     197                 :         244 :         parsetree_list = transformCreateSchemaStmtElements(stmt->schemaElts,
     198                 :         122 :                                                                                                            schemaName);
     199                 :             : 
     200                 :             :         /*
     201                 :             :          * Execute each command contained in the CREATE SCHEMA.  Since the grammar
     202                 :             :          * allows only utility commands in CREATE SCHEMA, there is no need to pass
     203                 :             :          * them through parse_analyze_*() or the rewriter; we can just hand them
     204                 :             :          * straight to ProcessUtility.
     205                 :             :          */
     206   [ +  +  +  +  :         180 :         foreach(parsetree_item, parsetree_list)
                   +  + ]
     207                 :             :         {
     208                 :          58 :                 Node       *stmt = (Node *) lfirst(parsetree_item);
     209                 :          58 :                 PlannedStmt *wrapper;
     210                 :             : 
     211                 :             :                 /* need to make a wrapper PlannedStmt */
     212                 :          58 :                 wrapper = makeNode(PlannedStmt);
     213                 :          58 :                 wrapper->commandType = CMD_UTILITY;
     214                 :          58 :                 wrapper->canSetTag = false;
     215                 :          58 :                 wrapper->utilityStmt = stmt;
     216                 :          58 :                 wrapper->stmt_location = stmt_location;
     217                 :          58 :                 wrapper->stmt_len = stmt_len;
     218                 :          58 :                 wrapper->planOrigin = PLAN_STMT_INTERNAL;
     219                 :             : 
     220                 :             :                 /* do this step */
     221                 :         116 :                 ProcessUtility(wrapper,
     222                 :          58 :                                            queryString,
     223                 :             :                                            false,
     224                 :             :                                            PROCESS_UTILITY_SUBCOMMAND,
     225                 :             :                                            NULL,
     226                 :             :                                            NULL,
     227                 :          58 :                                            None_Receiver,
     228                 :             :                                            NULL);
     229                 :             : 
     230                 :             :                 /* make sure later steps can see the object created here */
     231                 :          58 :                 CommandCounterIncrement();
     232                 :          58 :         }
     233                 :             : 
     234                 :             :         /*
     235                 :             :          * Restore the GUC variable search_path we set above.
     236                 :             :          */
     237                 :         122 :         AtEOXact_GUC(true, save_nestlevel);
     238                 :             : 
     239                 :             :         /* Reset current user and security context */
     240                 :         122 :         SetUserIdAndSecContext(saved_uid, save_sec_context);
     241                 :             : 
     242                 :         122 :         return namespaceId;
     243                 :         123 : }
     244                 :             : 
     245                 :             : 
     246                 :             : /*
     247                 :             :  * Rename schema
     248                 :             :  */
     249                 :             : ObjectAddress
     250                 :           3 : RenameSchema(const char *oldname, const char *newname)
     251                 :             : {
     252                 :           3 :         Oid                     nspOid;
     253                 :           3 :         HeapTuple       tup;
     254                 :           3 :         Relation        rel;
     255                 :           3 :         AclResult       aclresult;
     256                 :             :         ObjectAddress address;
     257                 :           3 :         Form_pg_namespace nspform;
     258                 :             : 
     259                 :           3 :         rel = table_open(NamespaceRelationId, RowExclusiveLock);
     260                 :             : 
     261                 :           3 :         tup = SearchSysCacheCopy1(NAMESPACENAME, CStringGetDatum(oldname));
     262         [ +  - ]:           3 :         if (!HeapTupleIsValid(tup))
     263   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     264                 :             :                                 (errcode(ERRCODE_UNDEFINED_SCHEMA),
     265                 :             :                                  errmsg("schema \"%s\" does not exist", oldname)));
     266                 :             : 
     267                 :           3 :         nspform = (Form_pg_namespace) GETSTRUCT(tup);
     268                 :           3 :         nspOid = nspform->oid;
     269                 :             : 
     270                 :             :         /* make sure the new name doesn't exist */
     271         [ +  - ]:           3 :         if (OidIsValid(get_namespace_oid(newname, true)))
     272   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     273                 :             :                                 (errcode(ERRCODE_DUPLICATE_SCHEMA),
     274                 :             :                                  errmsg("schema \"%s\" already exists", newname)));
     275                 :             : 
     276                 :             :         /* must be owner */
     277         [ +  - ]:           3 :         if (!object_ownercheck(NamespaceRelationId, nspOid, GetUserId()))
     278                 :           0 :                 aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA,
     279                 :           0 :                                            oldname);
     280                 :             : 
     281                 :             :         /* must have CREATE privilege on database */
     282                 :           3 :         aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
     283         [ +  - ]:           3 :         if (aclresult != ACLCHECK_OK)
     284                 :           0 :                 aclcheck_error(aclresult, OBJECT_DATABASE,
     285                 :           0 :                                            get_database_name(MyDatabaseId));
     286                 :             : 
     287   [ +  -  +  - ]:           3 :         if (!allowSystemTableMods && IsReservedName(newname))
     288   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     289                 :             :                                 (errcode(ERRCODE_RESERVED_NAME),
     290                 :             :                                  errmsg("unacceptable schema name \"%s\"", newname),
     291                 :             :                                  errdetail("The prefix \"pg_\" is reserved for system schemas.")));
     292                 :             : 
     293                 :             :         /* rename */
     294                 :           3 :         namestrcpy(&nspform->nspname, newname);
     295                 :           3 :         CatalogTupleUpdate(rel, &tup->t_self, tup);
     296                 :             : 
     297         [ +  - ]:           3 :         InvokeObjectPostAlterHook(NamespaceRelationId, nspOid, 0);
     298                 :             : 
     299                 :           3 :         ObjectAddressSet(address, NamespaceRelationId, nspOid);
     300                 :             : 
     301                 :           3 :         table_close(rel, NoLock);
     302                 :           3 :         heap_freetuple(tup);
     303                 :             : 
     304                 :             :         return address;
     305                 :           3 : }
     306                 :             : 
     307                 :             : void
     308                 :           1 : AlterSchemaOwner_oid(Oid schemaoid, Oid newOwnerId)
     309                 :             : {
     310                 :           1 :         HeapTuple       tup;
     311                 :           1 :         Relation        rel;
     312                 :             : 
     313                 :           1 :         rel = table_open(NamespaceRelationId, RowExclusiveLock);
     314                 :             : 
     315                 :           1 :         tup = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(schemaoid));
     316         [ +  - ]:           1 :         if (!HeapTupleIsValid(tup))
     317   [ #  #  #  # ]:           0 :                 elog(ERROR, "cache lookup failed for schema %u", schemaoid);
     318                 :             : 
     319                 :           1 :         AlterSchemaOwner_internal(tup, rel, newOwnerId);
     320                 :             : 
     321                 :           1 :         ReleaseSysCache(tup);
     322                 :             : 
     323                 :           1 :         table_close(rel, RowExclusiveLock);
     324                 :           1 : }
     325                 :             : 
     326                 :             : 
     327                 :             : /*
     328                 :             :  * Change schema owner
     329                 :             :  */
     330                 :             : ObjectAddress
     331                 :           5 : AlterSchemaOwner(const char *name, Oid newOwnerId)
     332                 :             : {
     333                 :           5 :         Oid                     nspOid;
     334                 :           5 :         HeapTuple       tup;
     335                 :           5 :         Relation        rel;
     336                 :             :         ObjectAddress address;
     337                 :           5 :         Form_pg_namespace nspform;
     338                 :             : 
     339                 :           5 :         rel = table_open(NamespaceRelationId, RowExclusiveLock);
     340                 :             : 
     341                 :           5 :         tup = SearchSysCache1(NAMESPACENAME, CStringGetDatum(name));
     342         [ +  - ]:           5 :         if (!HeapTupleIsValid(tup))
     343   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     344                 :             :                                 (errcode(ERRCODE_UNDEFINED_SCHEMA),
     345                 :             :                                  errmsg("schema \"%s\" does not exist", name)));
     346                 :             : 
     347                 :           5 :         nspform = (Form_pg_namespace) GETSTRUCT(tup);
     348                 :           5 :         nspOid = nspform->oid;
     349                 :             : 
     350                 :           5 :         AlterSchemaOwner_internal(tup, rel, newOwnerId);
     351                 :             : 
     352                 :           5 :         ObjectAddressSet(address, NamespaceRelationId, nspOid);
     353                 :             : 
     354                 :           5 :         ReleaseSysCache(tup);
     355                 :             : 
     356                 :           5 :         table_close(rel, RowExclusiveLock);
     357                 :             : 
     358                 :             :         return address;
     359                 :           5 : }
     360                 :             : 
     361                 :             : static void
     362                 :           6 : AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
     363                 :             : {
     364                 :           6 :         Form_pg_namespace nspForm;
     365                 :             : 
     366         [ +  - ]:           6 :         Assert(tup->t_tableOid == NamespaceRelationId);
     367         [ +  - ]:           6 :         Assert(RelationGetRelid(rel) == NamespaceRelationId);
     368                 :             : 
     369                 :           6 :         nspForm = (Form_pg_namespace) GETSTRUCT(tup);
     370                 :             : 
     371                 :             :         /*
     372                 :             :          * If the new owner is the same as the existing owner, consider the
     373                 :             :          * command to have succeeded.  This is for dump restoration purposes.
     374                 :             :          */
     375         [ -  + ]:           6 :         if (nspForm->nspowner != newOwnerId)
     376                 :             :         {
     377                 :           6 :                 Datum           repl_val[Natts_pg_namespace];
     378                 :           6 :                 bool            repl_null[Natts_pg_namespace];
     379                 :           6 :                 bool            repl_repl[Natts_pg_namespace];
     380                 :           6 :                 Acl                *newAcl;
     381                 :           6 :                 Datum           aclDatum;
     382                 :           6 :                 bool            isNull;
     383                 :           6 :                 HeapTuple       newtuple;
     384                 :           6 :                 AclResult       aclresult;
     385                 :             : 
     386                 :             :                 /* Otherwise, must be owner of the existing object */
     387         [ +  - ]:           6 :                 if (!object_ownercheck(NamespaceRelationId, nspForm->oid, GetUserId()))
     388                 :           0 :                         aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA,
     389                 :           0 :                                                    NameStr(nspForm->nspname));
     390                 :             : 
     391                 :             :                 /* Must be able to become new owner */
     392                 :           6 :                 check_can_set_role(GetUserId(), newOwnerId);
     393                 :             : 
     394                 :             :                 /*
     395                 :             :                  * must have create-schema rights
     396                 :             :                  *
     397                 :             :                  * NOTE: This is different from other alter-owner checks in that the
     398                 :             :                  * current user is checked for create privileges instead of the
     399                 :             :                  * destination owner.  This is consistent with the CREATE case for
     400                 :             :                  * schemas.  Because superusers will always have this right, we need
     401                 :             :                  * no special case for them.
     402                 :             :                  */
     403                 :           6 :                 aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
     404                 :             :                                                                         ACL_CREATE);
     405         [ +  - ]:           6 :                 if (aclresult != ACLCHECK_OK)
     406                 :           0 :                         aclcheck_error(aclresult, OBJECT_DATABASE,
     407                 :           0 :                                                    get_database_name(MyDatabaseId));
     408                 :             : 
     409                 :           6 :                 memset(repl_null, false, sizeof(repl_null));
     410                 :           6 :                 memset(repl_repl, false, sizeof(repl_repl));
     411                 :             : 
     412                 :           6 :                 repl_repl[Anum_pg_namespace_nspowner - 1] = true;
     413                 :           6 :                 repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId);
     414                 :             : 
     415                 :             :                 /*
     416                 :             :                  * Determine the modified ACL for the new owner.  This is only
     417                 :             :                  * necessary when the ACL is non-null.
     418                 :             :                  */
     419                 :           6 :                 aclDatum = SysCacheGetAttr(NAMESPACENAME, tup,
     420                 :             :                                                                    Anum_pg_namespace_nspacl,
     421                 :             :                                                                    &isNull);
     422         [ +  - ]:           6 :                 if (!isNull)
     423                 :             :                 {
     424                 :           0 :                         newAcl = aclnewowner(DatumGetAclP(aclDatum),
     425                 :           0 :                                                                  nspForm->nspowner, newOwnerId);
     426                 :           0 :                         repl_repl[Anum_pg_namespace_nspacl - 1] = true;
     427                 :           0 :                         repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
     428                 :           0 :                 }
     429                 :             : 
     430                 :           6 :                 newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
     431                 :             : 
     432                 :           6 :                 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
     433                 :             : 
     434                 :           6 :                 heap_freetuple(newtuple);
     435                 :             : 
     436                 :             :                 /* Update owner dependency reference */
     437                 :          12 :                 changeDependencyOnOwner(NamespaceRelationId, nspForm->oid,
     438                 :           6 :                                                                 newOwnerId);
     439                 :           6 :         }
     440                 :             : 
     441         [ +  - ]:           6 :         InvokeObjectPostAlterHook(NamespaceRelationId,
     442                 :             :                                                           nspForm->oid, 0);
     443                 :           6 : }
        

Generated by: LCOV version 2.3.2-1