LCOV - differential code coverage report
Current view: top level - src/backend/commands - alter.c (source / functions) Coverage Total Hit UBC GNC CBC DUB DCB
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 91.2 % 363 331 32 5 326 11
Current Date: 2026-03-14 14:10:32 -0400 Functions: 100.0 % 10 10 3 7
Baseline: lcov-20260315-024220-baseline Branches: 67.9 % 212 144 68 2 142 6 8
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 4 4 4
(30,360] days: 100.0 % 1 1 1
(360..) days: 91.1 % 358 326 32 326
Function coverage date bins:
(360..) days: 100.0 % 10 10 3 7
Branch coverage date bins:
(30,360] days: 100.0 % 2 2 2
(360..) days: 67.6 % 210 142 68 142

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * alter.c
                                  4                 :                :  *    Drivers for generic alter 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/alter.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "access/htup_details.h"
                                 18                 :                : #include "access/relation.h"
                                 19                 :                : #include "access/table.h"
                                 20                 :                : #include "catalog/dependency.h"
                                 21                 :                : #include "catalog/indexing.h"
                                 22                 :                : #include "catalog/namespace.h"
                                 23                 :                : #include "catalog/objectaccess.h"
                                 24                 :                : #include "catalog/pg_collation.h"
                                 25                 :                : #include "catalog/pg_conversion.h"
                                 26                 :                : #include "catalog/pg_database_d.h"
                                 27                 :                : #include "catalog/pg_event_trigger.h"
                                 28                 :                : #include "catalog/pg_foreign_data_wrapper.h"
                                 29                 :                : #include "catalog/pg_foreign_server.h"
                                 30                 :                : #include "catalog/pg_language.h"
                                 31                 :                : #include "catalog/pg_largeobject.h"
                                 32                 :                : #include "catalog/pg_largeobject_metadata.h"
                                 33                 :                : #include "catalog/pg_namespace.h"
                                 34                 :                : #include "catalog/pg_opclass.h"
                                 35                 :                : #include "catalog/pg_operator.h"
                                 36                 :                : #include "catalog/pg_opfamily.h"
                                 37                 :                : #include "catalog/pg_proc.h"
                                 38                 :                : #include "catalog/pg_statistic_ext.h"
                                 39                 :                : #include "catalog/pg_subscription.h"
                                 40                 :                : #include "catalog/pg_ts_config.h"
                                 41                 :                : #include "catalog/pg_ts_dict.h"
                                 42                 :                : #include "catalog/pg_ts_parser.h"
                                 43                 :                : #include "catalog/pg_ts_template.h"
                                 44                 :                : #include "commands/alter.h"
                                 45                 :                : #include "commands/collationcmds.h"
                                 46                 :                : #include "commands/dbcommands.h"
                                 47                 :                : #include "commands/defrem.h"
                                 48                 :                : #include "commands/event_trigger.h"
                                 49                 :                : #include "commands/extension.h"
                                 50                 :                : #include "commands/policy.h"
                                 51                 :                : #include "commands/publicationcmds.h"
                                 52                 :                : #include "commands/schemacmds.h"
                                 53                 :                : #include "commands/subscriptioncmds.h"
                                 54                 :                : #include "commands/tablecmds.h"
                                 55                 :                : #include "commands/tablespace.h"
                                 56                 :                : #include "commands/trigger.h"
                                 57                 :                : #include "commands/typecmds.h"
                                 58                 :                : #include "commands/user.h"
                                 59                 :                : #include "miscadmin.h"
                                 60                 :                : #include "replication/logicalworker.h"
                                 61                 :                : #include "rewrite/rewriteDefine.h"
                                 62                 :                : #include "storage/lmgr.h"
                                 63                 :                : #include "utils/acl.h"
                                 64                 :                : #include "utils/builtins.h"
                                 65                 :                : #include "utils/lsyscache.h"
                                 66                 :                : #include "utils/rel.h"
                                 67                 :                : #include "utils/syscache.h"
                                 68                 :                : 
                                 69                 :                : static Oid  AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid);
                                 70                 :                : 
                                 71                 :                : /*
                                 72                 :                :  * Raise an error to the effect that an object of the given name is already
                                 73                 :                :  * present in the given namespace.
                                 74                 :                :  */
                                 75                 :                : static void
 4801 alvherre@alvh.no-ip.       76                 :CBC          12 : report_name_conflict(Oid classId, const char *name)
                                 77                 :                : {
                                 78                 :                :     char       *msgfmt;
                                 79                 :                : 
                                 80   [ +  +  +  +  :             12 :     switch (classId)
                                           -  -  - ]
                                 81                 :                :     {
                                 82                 :              3 :         case EventTriggerRelationId:
                                 83                 :              3 :             msgfmt = gettext_noop("event trigger \"%s\" already exists");
                                 84                 :              3 :             break;
                                 85                 :              3 :         case ForeignDataWrapperRelationId:
                                 86                 :              3 :             msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
                                 87                 :              3 :             break;
                                 88                 :              3 :         case ForeignServerRelationId:
                                 89                 :              3 :             msgfmt = gettext_noop("server \"%s\" already exists");
                                 90                 :              3 :             break;
                                 91                 :              3 :         case LanguageRelationId:
                                 92                 :              3 :             msgfmt = gettext_noop("language \"%s\" already exists");
                                 93                 :              3 :             break;
 3299 peter_e@gmx.net            94                 :UBC           0 :         case PublicationRelationId:
                                 95                 :              0 :             msgfmt = gettext_noop("publication \"%s\" already exists");
                                 96                 :              0 :             break;
                                 97                 :              0 :         case SubscriptionRelationId:
                                 98                 :              0 :             msgfmt = gettext_noop("subscription \"%s\" already exists");
                                 99                 :              0 :             break;
 4801 alvherre@alvh.no-ip.      100                 :              0 :         default:
 1223 peter@eisentraut.org      101         [ #  # ]:              0 :             elog(ERROR, "unsupported object class: %u", classId);
                                102                 :                :             break;
                                103                 :                :     }
                                104                 :                : 
 4801 alvherre@alvh.no-ip.      105         [ +  - ]:CBC          12 :     ereport(ERROR,
                                106                 :                :             (errcode(ERRCODE_DUPLICATE_OBJECT),
                                107                 :                :              errmsg(msgfmt, name)));
                                108                 :                : }
                                109                 :                : 
                                110                 :                : static void
                                111                 :             36 : report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
                                112                 :                : {
                                113                 :                :     char       *msgfmt;
                                114                 :                : 
                                115         [ -  + ]:             36 :     Assert(OidIsValid(nspOid));
                                116                 :                : 
                                117   [ +  +  +  +  :             36 :     switch (classId)
                                           +  +  - ]
                                118                 :                :     {
                                119                 :              6 :         case ConversionRelationId:
                                120                 :              6 :             msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
                                121                 :              6 :             break;
 3278                           122                 :              6 :         case StatisticExtRelationId:
 3227 tgl@sss.pgh.pa.us         123                 :              6 :             msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
 3278 alvherre@alvh.no-ip.      124                 :              6 :             break;
 4801                           125                 :              6 :         case TSParserRelationId:
                                126                 :              6 :             msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
                                127                 :              6 :             break;
                                128                 :              6 :         case TSDictionaryRelationId:
                                129                 :              6 :             msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
                                130                 :              6 :             break;
                                131                 :              6 :         case TSTemplateRelationId:
                                132                 :              6 :             msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
                                133                 :              6 :             break;
                                134                 :              6 :         case TSConfigRelationId:
                                135                 :              6 :             msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
                                136                 :              6 :             break;
 4801 alvherre@alvh.no-ip.      137                 :UBC           0 :         default:
 1223 peter@eisentraut.org      138         [ #  # ]:              0 :             elog(ERROR, "unsupported object class: %u", classId);
                                139                 :                :             break;
                                140                 :                :     }
                                141                 :                : 
 4801 alvherre@alvh.no-ip.      142         [ +  - ]:CBC          36 :     ereport(ERROR,
                                143                 :                :             (errcode(ERRCODE_DUPLICATE_OBJECT),
                                144                 :                :              errmsg(msgfmt, name, get_namespace_name(nspOid))));
                                145                 :                : }
                                146                 :                : 
                                147                 :                : /*
                                148                 :                :  * AlterObjectRename_internal
                                149                 :                :  *
                                150                 :                :  * Generic function to rename the given object, for simple cases (won't
                                151                 :                :  * work for tables, nor other cases where we need to do more than change
                                152                 :                :  * the name column of a single catalog entry).
                                153                 :                :  *
                                154                 :                :  * rel: catalog relation containing object (RowExclusiveLock'd by caller)
                                155                 :                :  * objectId: OID of object to be renamed
                                156                 :                :  * new_name: CString representation of new name
                                157                 :                :  */
                                158                 :                : static void
                                159                 :            214 : AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
                                160                 :                : {
                                161                 :            214 :     Oid         classId = RelationGetRelid(rel);
   25 michael@paquier.xyz       162                 :GNC         214 :     SysCacheIdentifier oidCacheId = get_object_catcache_oid(classId);
                                163                 :            214 :     SysCacheIdentifier nameCacheId = get_object_catcache_name(classId);
 4801 alvherre@alvh.no-ip.      164                 :CBC         214 :     AttrNumber  Anum_name = get_object_attnum_name(classId);
                                165                 :            214 :     AttrNumber  Anum_namespace = get_object_attnum_namespace(classId);
                                166                 :            214 :     AttrNumber  Anum_owner = get_object_attnum_owner(classId);
                                167                 :                :     HeapTuple   oldtup;
                                168                 :                :     HeapTuple   newtup;
                                169                 :                :     Datum       datum;
                                170                 :                :     bool        isnull;
                                171                 :                :     Oid         namespaceId;
                                172                 :                :     Oid         ownerId;
                                173                 :                :     char       *old_name;
                                174                 :                :     AclResult   aclresult;
                                175                 :                :     Datum      *values;
                                176                 :                :     bool       *nulls;
                                177                 :                :     bool       *replaces;
                                178                 :                :     NameData    nameattrdata;
                                179                 :                : 
                                180                 :            214 :     oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
                                181         [ -  + ]:            214 :     if (!HeapTupleIsValid(oldtup))
 4801 alvherre@alvh.no-ip.      182         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
                                183                 :                :              objectId, RelationGetRelationName(rel));
                                184                 :                : 
 4801 alvherre@alvh.no-ip.      185                 :CBC         214 :     datum = heap_getattr(oldtup, Anum_name,
                                186                 :                :                          RelationGetDescr(rel), &isnull);
                                187         [ -  + ]:            214 :     Assert(!isnull);
                                188                 :            214 :     old_name = NameStr(*(DatumGetName(datum)));
                                189                 :                : 
                                190                 :                :     /* Get OID of namespace */
                                191         [ +  + ]:            214 :     if (Anum_namespace > 0)
                                192                 :                :     {
                                193                 :            135 :         datum = heap_getattr(oldtup, Anum_namespace,
                                194                 :                :                              RelationGetDescr(rel), &isnull);
                                195         [ -  + ]:            135 :         Assert(!isnull);
                                196                 :            135 :         namespaceId = DatumGetObjectId(datum);
                                197                 :                :     }
                                198                 :                :     else
                                199                 :             79 :         namespaceId = InvalidOid;
                                200                 :                : 
                                201                 :                :     /* Permission checks ... superusers can always do it */
                                202         [ +  + ]:            214 :     if (!superuser())
                                203                 :                :     {
                                204                 :                :         /* Fail if object does not have an explicit owner */
                                205         [ -  + ]:            123 :         if (Anum_owner <= 0)
 4801 alvherre@alvh.no-ip.      206         [ #  # ]:UBC           0 :             ereport(ERROR,
                                207                 :                :                     (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                208                 :                :                      errmsg("must be superuser to rename %s",
                                209                 :                :                             getObjectDescriptionOids(classId, objectId))));
                                210                 :                : 
                                211                 :                :         /* Otherwise, must be owner of the existing object */
 4801 alvherre@alvh.no-ip.      212                 :CBC         123 :         datum = heap_getattr(oldtup, Anum_owner,
                                213                 :                :                              RelationGetDescr(rel), &isnull);
                                214         [ -  + ]:            123 :         Assert(!isnull);
                                215                 :            123 :         ownerId = DatumGetObjectId(datum);
                                216                 :                : 
  219 peter@eisentraut.org      217         [ +  + ]:GNC         123 :         if (!has_privs_of_role(GetUserId(), ownerId))
 2322 tgl@sss.pgh.pa.us         218                 :CBC          36 :             aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objectId),
                                219                 :                :                            old_name);
                                220                 :                : 
                                221                 :                :         /* User must have CREATE privilege on the namespace */
 4801 alvherre@alvh.no-ip.      222         [ +  + ]:             87 :         if (OidIsValid(namespaceId))
                                223                 :                :         {
 1218 peter@eisentraut.org      224                 :             72 :             aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
                                225                 :                :                                         ACL_CREATE);
 4801 alvherre@alvh.no-ip.      226         [ -  + ]:             72 :             if (aclresult != ACLCHECK_OK)
 3025 peter_e@gmx.net           227                 :UBC           0 :                 aclcheck_error(aclresult, OBJECT_SCHEMA,
 4801 alvherre@alvh.no-ip.      228                 :              0 :                                get_namespace_name(namespaceId));
                                229                 :                :         }
                                230                 :                : 
 1081 rhaas@postgresql.org      231         [ +  + ]:CBC          87 :         if (classId == SubscriptionRelationId)
                                232                 :                :         {
                                233                 :                :             Form_pg_subscription form;
                                234                 :                : 
                                235                 :                :             /* must have CREATE privilege on database */
                                236                 :              9 :             aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId,
                                237                 :                :                                         GetUserId(), ACL_CREATE);
                                238         [ +  + ]:              9 :             if (aclresult != ACLCHECK_OK)
                                239                 :              3 :                 aclcheck_error(aclresult, OBJECT_DATABASE,
                                240                 :              3 :                                get_database_name(MyDatabaseId));
                                241                 :                : 
                                242                 :                :             /*
                                243                 :                :              * Don't allow non-superuser modification of a subscription with
                                244                 :                :              * password_required=false.
                                245                 :                :              */
                                246                 :              6 :             form = (Form_pg_subscription) GETSTRUCT(oldtup);
                                247   [ -  +  -  - ]:              6 :             if (!form->subpasswordrequired && !superuser())
 1081 rhaas@postgresql.org      248         [ #  # ]:UBC           0 :                 ereport(ERROR,
                                249                 :                :                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                250                 :                :                          errmsg("password_required=false is superuser-only"),
                                251                 :                :                          errhint("Subscriptions with the password_required option set to false may only be created or modified by the superuser.")));
                                252                 :                :         }
                                253                 :                :     }
                                254                 :                : 
                                255                 :                :     /*
                                256                 :                :      * Check for duplicate name (more friendly than unique-index failure).
                                257                 :                :      * Since this is just a friendliness check, we can just skip it in cases
                                258                 :                :      * where there isn't suitable support.
                                259                 :                :      */
 4801 alvherre@alvh.no-ip.      260         [ +  + ]:CBC         175 :     if (classId == ProcedureRelationId)
                                261                 :                :     {
                                262                 :             36 :         Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
                                263                 :                : 
                                264                 :             36 :         IsThereFunctionInNamespace(new_name, proc->pronargs,
                                265                 :                :                                    &proc->proargtypes, proc->pronamespace);
                                266                 :                :     }
                                267         [ +  + ]:            139 :     else if (classId == CollationRelationId)
                                268                 :                :     {
                                269                 :              6 :         Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(oldtup);
                                270                 :                : 
                                271                 :              6 :         IsThereCollationInNamespace(new_name, coll->collnamespace);
                                272                 :                :     }
                                273         [ +  + ]:            133 :     else if (classId == OperatorClassRelationId)
                                274                 :                :     {
                                275                 :              9 :         Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
                                276                 :                : 
                                277                 :              9 :         IsThereOpClassInNamespace(new_name, opc->opcmethod,
                                278                 :                :                                   opc->opcnamespace);
                                279                 :                :     }
                                280         [ +  + ]:            124 :     else if (classId == OperatorFamilyRelationId)
                                281                 :                :     {
                                282                 :              9 :         Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(oldtup);
                                283                 :                : 
                                284                 :              9 :         IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
                                285                 :                :                                    opf->opfnamespace);
                                286                 :                :     }
 3299 peter_e@gmx.net           287         [ +  + ]:            115 :     else if (classId == SubscriptionRelationId)
                                288                 :                :     {
  969 michael@paquier.xyz       289         [ -  + ]:             13 :         if (SearchSysCacheExists2(SUBSCRIPTIONNAME,
                                290                 :                :                                   ObjectIdGetDatum(MyDatabaseId),
                                291                 :                :                                   CStringGetDatum(new_name)))
 3299 peter_e@gmx.net           292                 :UBC           0 :             report_name_conflict(classId, new_name);
                                293                 :                : 
                                294                 :                :         /* Also enforce regression testing naming rules, if enabled */
                                295                 :                : #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
                                296                 :                :         if (strncmp(new_name, "regress_", 8) != 0)
                                297                 :                :             elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
                                298                 :                : #endif
                                299                 :                : 
                                300                 :                :         /* Wake up related replication workers to handle this change quickly */
 1164 tgl@sss.pgh.pa.us         301                 :CBC          13 :         LogicalRepWorkersWakeupAtCommit(objectId);
                                302                 :                :     }
 4801 alvherre@alvh.no-ip.      303         [ +  - ]:            102 :     else if (nameCacheId >= 0)
                                304                 :                :     {
                                305         [ +  + ]:            102 :         if (OidIsValid(namespaceId))
                                306                 :                :         {
                                307         [ +  + ]:             48 :             if (SearchSysCacheExists2(nameCacheId,
                                308                 :                :                                       CStringGetDatum(new_name),
                                309                 :                :                                       ObjectIdGetDatum(namespaceId)))
                                310                 :             18 :                 report_namespace_conflict(classId, new_name, namespaceId);
                                311                 :                :         }
                                312                 :                :         else
                                313                 :                :         {
                                314         [ +  + ]:             54 :             if (SearchSysCacheExists1(nameCacheId,
                                315                 :                :                                       CStringGetDatum(new_name)))
                                316                 :             12 :                 report_name_conflict(classId, new_name);
                                317                 :                :         }
                                318                 :                :     }
                                319                 :                : 
                                320                 :                :     /* Build modified tuple */
                                321                 :            130 :     values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
                                322                 :            130 :     nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
                                323                 :            130 :     replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
 4659 noah@leadboat.com         324                 :            130 :     namestrcpy(&nameattrdata, new_name);
                                325                 :            130 :     values[Anum_name - 1] = NameGetDatum(&nameattrdata);
 4801 alvherre@alvh.no-ip.      326                 :            130 :     replaces[Anum_name - 1] = true;
                                327                 :            130 :     newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
                                328                 :                :                                values, nulls, replaces);
                                329                 :                : 
                                330                 :                :     /* Perform actual update */
 3330                           331                 :            130 :     CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
                                332                 :                : 
 4746 rhaas@postgresql.org      333         [ -  + ]:            130 :     InvokeObjectPostAlterHook(classId, objectId, 0);
                                334                 :                : 
                                335                 :                :     /* Do post catalog-update tasks */
  367 akapila@postgresql.o      336         [ +  + ]:            130 :     if (classId == PublicationRelationId)
                                337                 :                :     {
                                338                 :             18 :         Form_pg_publication pub = (Form_pg_publication) GETSTRUCT(oldtup);
                                339                 :                : 
                                340                 :                :         /*
                                341                 :                :          * Invalidate relsynccache entries.
                                342                 :                :          *
                                343                 :                :          * Unlike ALTER PUBLICATION ADD/SET/DROP commands, renaming a
                                344                 :                :          * publication does not impact the publication status of tables. So,
                                345                 :                :          * we don't need to invalidate relcache to rebuild the rd_pubdesc.
                                346                 :                :          * Instead, we invalidate only the relsyncache.
                                347                 :                :          */
                                348                 :             18 :         InvalidatePubRelSyncCache(pub->oid, pub->puballtables);
                                349                 :                :     }
                                350                 :                : 
                                351                 :                :     /* Release memory */
 4801 alvherre@alvh.no-ip.      352                 :            130 :     pfree(values);
                                353                 :            130 :     pfree(nulls);
                                354                 :            130 :     pfree(replaces);
                                355                 :            130 :     heap_freetuple(newtup);
                                356                 :                : 
                                357                 :            130 :     ReleaseSysCache(oldtup);
                                358                 :            130 : }
                                359                 :                : 
                                360                 :                : /*
                                361                 :                :  * Executes an ALTER OBJECT / RENAME TO statement.  Based on the object
                                362                 :                :  * type, the function appropriate to that type is executed.
                                363                 :                :  *
                                364                 :                :  * Return value is the address of the renamed object.
                                365                 :                :  */
                                366                 :                : ObjectAddress
                                367                 :            779 : ExecRenameStmt(RenameStmt *stmt)
                                368                 :                : {
                                369   [ +  +  +  +  :            779 :     switch (stmt->renameType)
                                     +  +  +  +  +  
                                        +  +  +  - ]
                                370                 :                :     {
 4100                           371                 :             42 :         case OBJECT_TABCONSTRAINT:
                                372                 :                :         case OBJECT_DOMCONSTRAINT:
 4801                           373                 :             42 :             return RenameConstraint(stmt);
                                374                 :                : 
                                375                 :              7 :         case OBJECT_DATABASE:
                                376                 :              7 :             return RenameDatabase(stmt->subname, stmt->newname);
                                377                 :                : 
 7565 tgl@sss.pgh.pa.us         378                 :             15 :         case OBJECT_ROLE:
 4830 rhaas@postgresql.org      379                 :             15 :             return RenameRole(stmt->subname, stmt->newname);
                                380                 :                : 
 8297 peter_e@gmx.net           381                 :             10 :         case OBJECT_SCHEMA:
 4830 rhaas@postgresql.org      382                 :             10 :             return RenameSchema(stmt->subname, stmt->newname);
                                383                 :                : 
 7933 tgl@sss.pgh.pa.us         384                 :              6 :         case OBJECT_TABLESPACE:
 4830 rhaas@postgresql.org      385                 :              6 :             return RenameTableSpace(stmt->subname, stmt->newname);
                                386                 :                : 
 8297 peter_e@gmx.net           387                 :            259 :         case OBJECT_TABLE:
                                388                 :                :         case OBJECT_SEQUENCE:
                                389                 :                :         case OBJECT_VIEW:
                                390                 :                :         case OBJECT_MATVIEW:
                                391                 :                :         case OBJECT_INDEX:
                                392                 :                :         case OBJECT_FOREIGN_TABLE:
 4830 rhaas@postgresql.org      393                 :            259 :             return RenameRelation(stmt);
                                394                 :                : 
 8297 peter_e@gmx.net           395                 :            158 :         case OBJECT_COLUMN:
                                396                 :                :         case OBJECT_ATTRIBUTE:
 4830 rhaas@postgresql.org      397                 :            158 :             return renameatt(stmt);
                                398                 :                : 
 4783 tgl@sss.pgh.pa.us         399                 :             17 :         case OBJECT_RULE:
                                400                 :             17 :             return RenameRewriteRule(stmt->relation, stmt->subname,
                                401                 :             17 :                                      stmt->newname);
                                402                 :                : 
 8297 peter_e@gmx.net           403                 :             20 :         case OBJECT_TRIGGER:
 4830 rhaas@postgresql.org      404                 :             20 :             return renametrig(stmt);
                                405                 :                : 
 4195 sfrost@snowman.net        406                 :              9 :         case OBJECT_POLICY:
                                407                 :              9 :             return rename_policy(stmt);
                                408                 :                : 
 4801 alvherre@alvh.no-ip.      409                 :             16 :         case OBJECT_DOMAIN:
                                410                 :                :         case OBJECT_TYPE:
                                411                 :             16 :             return RenameType(stmt);
                                412                 :                : 
                                413                 :            220 :         case OBJECT_AGGREGATE:
                                414                 :                :         case OBJECT_COLLATION:
                                415                 :                :         case OBJECT_CONVERSION:
                                416                 :                :         case OBJECT_EVENT_TRIGGER:
                                417                 :                :         case OBJECT_FDW:
                                418                 :                :         case OBJECT_FOREIGN_SERVER:
                                419                 :                :         case OBJECT_FUNCTION:
                                420                 :                :         case OBJECT_OPCLASS:
                                421                 :                :         case OBJECT_OPFAMILY:
                                422                 :                :         case OBJECT_LANGUAGE:
                                423                 :                :         case OBJECT_PROCEDURE:
                                424                 :                :         case OBJECT_ROUTINE:
                                425                 :                :         case OBJECT_STATISTIC_EXT:
                                426                 :                :         case OBJECT_TSCONFIGURATION:
                                427                 :                :         case OBJECT_TSDICTIONARY:
                                428                 :                :         case OBJECT_TSPARSER:
                                429                 :                :         case OBJECT_TSTEMPLATE:
                                430                 :                :         case OBJECT_PUBLICATION:
                                431                 :                :         case OBJECT_SUBSCRIPTION:
                                432                 :                :             {
                                433                 :                :                 ObjectAddress address;
                                434                 :                :                 Relation    catalog;
                                435                 :                : 
                                436                 :            220 :                 address = get_object_address(stmt->renameType,
                                437                 :                :                                              stmt->object,
                                438                 :                :                                              NULL,
                                439                 :                :                                              AccessExclusiveLock, false);
                                440                 :                : 
 2610 andres@anarazel.de        441                 :            214 :                 catalog = table_open(address.classId, RowExclusiveLock);
 4801 alvherre@alvh.no-ip.      442                 :            214 :                 AlterObjectRename_internal(catalog,
                                443                 :                :                                            address.objectId,
                                444                 :            214 :                                            stmt->newname);
 2610 andres@anarazel.de        445                 :            130 :                 table_close(catalog, RowExclusiveLock);
                                446                 :                : 
 4030 alvherre@alvh.no-ip.      447                 :            130 :                 return address;
                                448                 :                :             }
                                449                 :                : 
 8297 peter_e@gmx.net           450                 :UBC           0 :         default:
 8274 tgl@sss.pgh.pa.us         451         [ #  # ]:              0 :             elog(ERROR, "unrecognized rename stmt type: %d",
                                452                 :                :                  (int) stmt->renameType);
                                453                 :                :             return InvalidObjectAddress;    /* keep compiler happy */
                                454                 :                :     }
                                455                 :                : }
                                456                 :                : 
                                457                 :                : /*
                                458                 :                :  * Executes an ALTER OBJECT / [NO] DEPENDS ON EXTENSION statement.
                                459                 :                :  *
                                460                 :                :  * Return value is the address of the altered object.  refAddress is an output
                                461                 :                :  * argument which, if not null, receives the address of the object that the
                                462                 :                :  * altered object now depends on.
                                463                 :                :  */
                                464                 :                : ObjectAddress
 3631 alvherre@alvh.no-ip.      465                 :CBC          23 : ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddress)
                                466                 :                : {
                                467                 :                :     ObjectAddress address;
                                468                 :                :     ObjectAddress refAddr;
                                469                 :                :     Relation    rel;
                                470                 :                : 
                                471                 :                :     address =
 3410 peter_e@gmx.net           472                 :             23 :         get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
                                473                 :                :                               &rel, AccessExclusiveLock, false);
                                474                 :                : 
                                475                 :                :     /*
                                476                 :                :      * Verify that the user is entitled to run the command.
                                477                 :                :      *
                                478                 :                :      * We don't check any privileges on the extension, because that's not
                                479                 :                :      * needed.  The object owner is stipulating, by running this command, that
                                480                 :                :      * the extension owner can drop the object whenever they feel like it,
                                481                 :                :      * which is not considered a problem.
                                482                 :                :      */
 2225 alvherre@alvh.no-ip.      483                 :             23 :     check_object_ownership(GetUserId(),
                                484                 :                :                            stmt->objectType, address, stmt->object, rel);
                                485                 :                : 
                                486                 :                :     /*
                                487                 :                :      * If a relation was involved, it would have been opened and locked. We
                                488                 :                :      * don't need the relation here, but we'll retain the lock until commit.
                                489                 :                :      */
 3631                           490         [ +  + ]:             23 :     if (rel)
 2610 andres@anarazel.de        491                 :             17 :         table_close(rel, NoLock);
                                492                 :                : 
 3410 peter_e@gmx.net           493                 :             23 :     refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
                                494                 :                :                                  NULL, AccessExclusiveLock, false);
 3631 alvherre@alvh.no-ip.      495         [ +  - ]:             23 :     if (refAddress)
                                496                 :             23 :         *refAddress = refAddr;
                                497                 :                : 
 2155                           498         [ +  + ]:             23 :     if (stmt->remove)
                                499                 :                :     {
                                500                 :              4 :         deleteDependencyRecordsForSpecific(address.classId, address.objectId,
                                501                 :                :                                            DEPENDENCY_AUTO_EXTENSION,
                                502                 :                :                                            refAddr.classId, refAddr.objectId);
                                503                 :                :     }
                                504                 :                :     else
                                505                 :                :     {
                                506                 :                :         List       *currexts;
                                507                 :                : 
                                508                 :                :         /* Avoid duplicates */
                                509                 :             19 :         currexts = getAutoExtensionsOfObject(address.classId,
                                510                 :                :                                              address.objectId);
                                511         [ +  + ]:             19 :         if (!list_member_oid(currexts, refAddr.objectId))
                                512                 :             18 :             recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
                                513                 :                :     }
                                514                 :                : 
 3631                           515                 :             23 :     return address;
                                516                 :                : }
                                517                 :                : 
                                518                 :                : /*
                                519                 :                :  * Executes an ALTER OBJECT / SET SCHEMA statement.  Based on the object
                                520                 :                :  * type, the function appropriate to that type is executed.
                                521                 :                :  *
                                522                 :                :  * Return value is that of the altered object.
                                523                 :                :  *
                                524                 :                :  * oldSchemaAddr is an output argument which, if not NULL, is set to the object
                                525                 :                :  * address of the original schema.
                                526                 :                :  */
                                527                 :                : ObjectAddress
 4030                           528                 :            199 : ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
                                529                 :                :                           ObjectAddress *oldSchemaAddr)
                                530                 :                : {
                                531                 :                :     ObjectAddress address;
                                532                 :                :     Oid         oldNspOid;
                                533                 :                : 
 7531 tgl@sss.pgh.pa.us         534   [ +  +  +  +  :            199 :     switch (stmt->objectType)
                                                 - ]
                                535                 :                :     {
 5514                           536                 :              6 :         case OBJECT_EXTENSION:
 1648 peter@eisentraut.org      537         [ +  - ]:              6 :             address = AlterExtensionNamespace(strVal(stmt->object), stmt->newschema,
                                538                 :                :                                               oldSchemaAddr ? &oldNspOid : NULL);
 4030 alvherre@alvh.no-ip.      539                 :              4 :             break;
                                540                 :                : 
 4807                           541                 :             52 :         case OBJECT_FOREIGN_TABLE:
                                542                 :                :         case OBJECT_SEQUENCE:
                                543                 :                :         case OBJECT_TABLE:
                                544                 :                :         case OBJECT_VIEW:
                                545                 :                :         case OBJECT_MATVIEW:
 4030                           546         [ +  - ]:             52 :             address = AlterTableNamespace(stmt,
                                547                 :                :                                           oldSchemaAddr ? &oldNspOid : NULL);
                                548                 :             48 :             break;
                                549                 :                : 
 4917                           550                 :              9 :         case OBJECT_DOMAIN:
                                551                 :                :         case OBJECT_TYPE:
 3410 peter_e@gmx.net           552         [ +  - ]:              9 :             address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
                                553                 :                :                                          stmt->objectType,
                                554                 :                :                                          oldSchemaAddr ? &oldNspOid : NULL);
 4030 alvherre@alvh.no-ip.      555                 :              9 :             break;
                                556                 :                : 
                                557                 :                :             /* generic code path */
 4807                           558                 :            132 :         case OBJECT_AGGREGATE:
                                559                 :                :         case OBJECT_COLLATION:
                                560                 :                :         case OBJECT_CONVERSION:
                                561                 :                :         case OBJECT_FUNCTION:
                                562                 :                :         case OBJECT_OPERATOR:
                                563                 :                :         case OBJECT_OPCLASS:
                                564                 :                :         case OBJECT_OPFAMILY:
                                565                 :                :         case OBJECT_PROCEDURE:
                                566                 :                :         case OBJECT_ROUTINE:
                                567                 :                :         case OBJECT_STATISTIC_EXT:
                                568                 :                :         case OBJECT_TSCONFIGURATION:
                                569                 :                :         case OBJECT_TSDICTIONARY:
                                570                 :                :         case OBJECT_TSPARSER:
                                571                 :                :         case OBJECT_TSTEMPLATE:
                                572                 :                :             {
                                573                 :                :                 Relation    catalog;
                                574                 :                :                 Oid         classId;
                                575                 :                :                 Oid         nspOid;
                                576                 :                : 
 4917                           577                 :            132 :                 address = get_object_address(stmt->objectType,
                                578                 :                :                                              stmt->object,
                                579                 :                :                                              NULL,
                                580                 :                :                                              AccessExclusiveLock,
                                581                 :                :                                              false);
                                582                 :            129 :                 classId = address.classId;
 2610 andres@anarazel.de        583                 :            129 :                 catalog = table_open(classId, RowExclusiveLock);
 4917 alvherre@alvh.no-ip.      584                 :            129 :                 nspOid = LookupCreationNamespace(stmt->newschema);
                                585                 :                : 
 4030                           586                 :            129 :                 oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
                                587                 :                :                                                           nspOid);
 2610 andres@anarazel.de        588                 :             72 :                 table_close(catalog, RowExclusiveLock);
                                589                 :                :             }
 7531 tgl@sss.pgh.pa.us         590                 :             72 :             break;
                                591                 :                : 
 7531 tgl@sss.pgh.pa.us         592                 :UBC           0 :         default:
                                593         [ #  # ]:              0 :             elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
                                594                 :                :                  (int) stmt->objectType);
                                595                 :                :             return InvalidObjectAddress;    /* keep compiler happy */
                                596                 :                :     }
                                597                 :                : 
 4030 alvherre@alvh.no-ip.      598         [ +  - ]:CBC         133 :     if (oldSchemaAddr)
                                599                 :            133 :         ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
                                600                 :                : 
                                601                 :            133 :     return address;
                                602                 :                : }
                                603                 :                : 
                                604                 :                : /*
                                605                 :                :  * Change an object's namespace given its classOid and object Oid.
                                606                 :                :  *
                                607                 :                :  * Objects that don't have a namespace should be ignored, as should
                                608                 :                :  * dependent types such as array types.
                                609                 :                :  *
                                610                 :                :  * This function is currently used only by ALTER EXTENSION SET SCHEMA,
                                611                 :                :  * so it only needs to cover object kinds that can be members of an
                                612                 :                :  * extension, and it can silently ignore dependent types --- we assume
                                613                 :                :  * those will be moved when their parent object is moved.
                                614                 :                :  *
                                615                 :                :  * Returns the OID of the object's previous namespace, or InvalidOid if
                                616                 :                :  * object doesn't have a schema or was ignored due to being a dependent type.
                                617                 :                :  */
                                618                 :                : Oid
 4883                           619                 :             21 : AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
                                620                 :                :                          ObjectAddresses *objsMoved)
                                621                 :                : {
 5514 tgl@sss.pgh.pa.us         622                 :             21 :     Oid         oldNspOid = InvalidOid;
                                623                 :                : 
  719 peter@eisentraut.org      624   [ +  +  +  + ]:             21 :     switch (classId)
                                625                 :                :     {
                                626                 :              1 :         case RelationRelationId:
                                627                 :                :             {
                                628                 :                :                 Relation    rel;
                                629                 :                : 
 5453 bruce@momjian.us          630                 :              1 :                 rel = relation_open(objid, AccessExclusiveLock);
                                631                 :              1 :                 oldNspOid = RelationGetNamespace(rel);
                                632                 :                : 
 4883 alvherre@alvh.no-ip.      633                 :              1 :                 AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
                                634                 :                : 
 5453 bruce@momjian.us          635                 :              1 :                 relation_close(rel, NoLock);
                                636                 :              1 :                 break;
                                637                 :                :             }
                                638                 :                : 
  719 peter@eisentraut.org      639                 :              8 :         case TypeRelationId:
  675 tgl@sss.pgh.pa.us         640                 :              8 :             oldNspOid = AlterTypeNamespace_oid(objid, nspOid, true, objsMoved);
 5514                           641                 :              8 :             break;
                                642                 :                : 
  719 peter@eisentraut.org      643                 :             11 :         case ProcedureRelationId:
                                644                 :                :         case CollationRelationId:
                                645                 :                :         case ConversionRelationId:
                                646                 :                :         case OperatorRelationId:
                                647                 :                :         case OperatorClassRelationId:
                                648                 :                :         case OperatorFamilyRelationId:
                                649                 :                :         case StatisticExtRelationId:
                                650                 :                :         case TSParserRelationId:
                                651                 :                :         case TSDictionaryRelationId:
                                652                 :                :         case TSTemplateRelationId:
                                653                 :                :         case TSConfigRelationId:
                                654                 :                :             {
                                655                 :                :                 Relation    catalog;
                                656                 :                : 
 2610 andres@anarazel.de        657                 :             11 :                 catalog = table_open(classId, RowExclusiveLock);
                                658                 :                : 
 4917 alvherre@alvh.no-ip.      659                 :             11 :                 oldNspOid = AlterObjectNamespace_internal(catalog, objid,
                                660                 :                :                                                           nspOid);
                                661                 :                : 
 2610 andres@anarazel.de        662                 :             11 :                 table_close(catalog, RowExclusiveLock);
                                663                 :                :             }
 5514 tgl@sss.pgh.pa.us         664                 :             11 :             break;
                                665                 :                : 
  719 peter@eisentraut.org      666                 :              1 :         default:
                                667                 :                :             /* ignore object types that don't have schema-qualified names */
                                668         [ -  + ]:              1 :             Assert(get_object_attnum_namespace(classId) == InvalidAttrNumber);
                                669                 :                :     }
                                670                 :                : 
 5514 tgl@sss.pgh.pa.us         671                 :             21 :     return oldNspOid;
                                672                 :                : }
                                673                 :                : 
                                674                 :                : /*
                                675                 :                :  * Generic function to change the namespace of a given object, for simple
                                676                 :                :  * cases (won't work for tables, nor other cases where we need to do more
                                677                 :                :  * than change the namespace column of a single catalog entry).
                                678                 :                :  *
                                679                 :                :  * rel: catalog relation containing object (RowExclusiveLock'd by caller)
                                680                 :                :  * objid: OID of object to change the namespace of
                                681                 :                :  * nspOid: OID of new namespace
                                682                 :                :  *
                                683                 :                :  * Returns the OID of the object's previous namespace.
                                684                 :                :  */
                                685                 :                : static Oid
 4917 alvherre@alvh.no-ip.      686                 :            140 : AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
                                687                 :                : {
 5514 tgl@sss.pgh.pa.us         688                 :            140 :     Oid         classId = RelationGetRelid(rel);
   25 michael@paquier.xyz       689                 :GNC         140 :     SysCacheIdentifier oidCacheId = get_object_catcache_oid(classId);
                                690                 :            140 :     SysCacheIdentifier nameCacheId = get_object_catcache_name(classId);
 4917 alvherre@alvh.no-ip.      691                 :CBC         140 :     AttrNumber  Anum_name = get_object_attnum_name(classId);
                                692                 :            140 :     AttrNumber  Anum_namespace = get_object_attnum_namespace(classId);
                                693                 :            140 :     AttrNumber  Anum_owner = get_object_attnum_owner(classId);
                                694                 :                :     Oid         oldNspOid;
                                695                 :                :     Datum       name,
                                696                 :                :                 namespace;
                                697                 :                :     bool        isnull;
                                698                 :                :     HeapTuple   tup,
                                699                 :                :                 newtup;
                                700                 :                :     Datum      *values;
                                701                 :                :     bool       *nulls;
                                702                 :                :     bool       *replaces;
                                703                 :                : 
 5514 tgl@sss.pgh.pa.us         704                 :            140 :     tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
 5588 rhaas@postgresql.org      705         [ -  + ]:            140 :     if (!HeapTupleIsValid(tup)) /* should not happen */
 5514 tgl@sss.pgh.pa.us         706         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
                                707                 :                :              objid, RelationGetRelationName(rel));
                                708                 :                : 
 5514 tgl@sss.pgh.pa.us         709                 :CBC         140 :     name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
                                710         [ -  + ]:            140 :     Assert(!isnull);
 4917 alvherre@alvh.no-ip.      711                 :            140 :     namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
                                712                 :                :                              &isnull);
 5514 tgl@sss.pgh.pa.us         713         [ -  + ]:            140 :     Assert(!isnull);
 5588 rhaas@postgresql.org      714                 :            140 :     oldNspOid = DatumGetObjectId(namespace);
                                715                 :                : 
                                716                 :                :     /*
                                717                 :                :      * If the object is already in the correct namespace, we don't need to do
                                718                 :                :      * anything except fire the object access hook.
                                719                 :                :      */
 3769                           720         [ +  + ]:            140 :     if (oldNspOid == nspOid)
                                721                 :                :     {
                                722         [ -  + ]:              3 :         InvokeObjectPostAlterHook(classId, objid, 0);
                                723                 :              3 :         return oldNspOid;
                                724                 :                :     }
                                725                 :                : 
                                726                 :                :     /* Check basic namespace related issues */
                                727                 :            137 :     CheckSetNamespace(oldNspOid, nspOid);
                                728                 :                : 
                                729                 :                :     /* Permission checks ... superusers can always do it */
 5588                           730         [ +  + ]:            137 :     if (!superuser())
                                731                 :                :     {
                                732                 :                :         Datum       owner;
                                733                 :                :         Oid         ownerId;
                                734                 :                :         AclResult   aclresult;
                                735                 :                : 
                                736                 :                :         /* Fail if object does not have an explicit owner */
 5514 tgl@sss.pgh.pa.us         737         [ -  + ]:             78 :         if (Anum_owner <= 0)
 5588 rhaas@postgresql.org      738         [ #  # ]:UBC           0 :             ereport(ERROR,
                                739                 :                :                     (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                740                 :                :                      errmsg("must be superuser to set schema of %s",
                                741                 :                :                             getObjectDescriptionOids(classId, objid))));
                                742                 :                : 
                                743                 :                :         /* Otherwise, must be owner of the existing object */
 5514 tgl@sss.pgh.pa.us         744                 :CBC          78 :         owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
                                745         [ -  + ]:             78 :         Assert(!isnull);
 5588 rhaas@postgresql.org      746                 :             78 :         ownerId = DatumGetObjectId(owner);
                                747                 :                : 
                                748         [ +  + ]:             78 :         if (!has_privs_of_role(GetUserId(), ownerId))
 2322 tgl@sss.pgh.pa.us         749                 :             27 :             aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objid),
 5588 rhaas@postgresql.org      750                 :             27 :                            NameStr(*(DatumGetName(name))));
                                751                 :                : 
                                752                 :                :         /* User must have CREATE privilege on new namespace */
 1218 peter@eisentraut.org      753                 :             51 :         aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
 5588 rhaas@postgresql.org      754         [ -  + ]:             51 :         if (aclresult != ACLCHECK_OK)
 3025 peter_e@gmx.net           755                 :UBC           0 :             aclcheck_error(aclresult, OBJECT_SCHEMA,
 5514 tgl@sss.pgh.pa.us         756                 :              0 :                            get_namespace_name(nspOid));
                                757                 :                :     }
                                758                 :                : 
                                759                 :                :     /*
                                760                 :                :      * Check for duplicate name (more friendly than unique-index failure).
                                761                 :                :      * Since this is just a friendliness check, we can just skip it in cases
                                762                 :                :      * where there isn't suitable support.
                                763                 :                :      */
 4807 alvherre@alvh.no-ip.      764         [ +  + ]:CBC         110 :     if (classId == ProcedureRelationId)
                                765                 :                :     {
 4801                           766                 :             32 :         Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
                                767                 :                : 
 4807                           768                 :             32 :         IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
                                769                 :                :                                    &proc->proargtypes, nspOid);
                                770                 :                :     }
                                771         [ +  + ]:             78 :     else if (classId == CollationRelationId)
                                772                 :                :     {
 4801                           773                 :              3 :         Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(tup);
                                774                 :                : 
                                775                 :              3 :         IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
                                776                 :                :     }
                                777         [ +  + ]:             75 :     else if (classId == OperatorClassRelationId)
                                778                 :                :     {
                                779                 :              9 :         Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(tup);
                                780                 :                : 
                                781                 :              9 :         IsThereOpClassInNamespace(NameStr(opc->opcname),
                                782                 :                :                                   opc->opcmethod, nspOid);
                                783                 :                :     }
                                784         [ +  + ]:             66 :     else if (classId == OperatorFamilyRelationId)
                                785                 :                :     {
                                786                 :              9 :         Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(tup);
                                787                 :                : 
                                788                 :              9 :         IsThereOpFamilyInNamespace(NameStr(opf->opfname),
                                789                 :                :                                    opf->opfmethod, nspOid);
                                790                 :                :     }
 4807                           791   [ +  +  +  + ]:            108 :     else if (nameCacheId >= 0 &&
                                792                 :             51 :              SearchSysCacheExists2(nameCacheId, name,
                                793                 :                :                                    ObjectIdGetDatum(nspOid)))
                                794                 :             18 :         report_namespace_conflict(classId,
                                795                 :             18 :                                   NameStr(*(DatumGetName(name))),
                                796                 :                :                                   nspOid);
                                797                 :                : 
                                798                 :                :     /* Build modified tuple */
 5514 tgl@sss.pgh.pa.us         799                 :             80 :     values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
                                800                 :             80 :     nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
                                801                 :             80 :     replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
                                802                 :             80 :     values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
 5588 rhaas@postgresql.org      803                 :             80 :     replaces[Anum_namespace - 1] = true;
 5514 tgl@sss.pgh.pa.us         804                 :             80 :     newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
                                805                 :                :                                values, nulls, replaces);
                                806                 :                : 
                                807                 :                :     /* Perform actual update */
 3330 alvherre@alvh.no-ip.      808                 :             80 :     CatalogTupleUpdate(rel, &tup->t_self, newtup);
                                809                 :                : 
                                810                 :                :     /* Release memory */
 5588 rhaas@postgresql.org      811                 :             80 :     pfree(values);
                                812                 :             80 :     pfree(nulls);
                                813                 :             80 :     pfree(replaces);
                                814                 :                : 
                                815                 :                :     /* update dependency to point to the new schema */
  979 michael@paquier.xyz       816         [ -  + ]:             80 :     if (changeDependencyFor(classId, objid,
                                817                 :                :                             NamespaceRelationId, oldNspOid, nspOid) != 1)
  979 michael@paquier.xyz       818         [ #  # ]:UBC           0 :         elog(ERROR, "could not change schema dependency for object %u",
                                819                 :                :              objid);
                                820                 :                : 
 4746 rhaas@postgresql.org      821         [ -  + ]:CBC          80 :     InvokeObjectPostAlterHook(classId, objid, 0);
                                822                 :                : 
 5514 tgl@sss.pgh.pa.us         823                 :             80 :     return oldNspOid;
                                824                 :                : }
                                825                 :                : 
                                826                 :                : /*
                                827                 :                :  * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
                                828                 :                :  * type, the function appropriate to that type is executed.
                                829                 :                :  */
                                830                 :                : ObjectAddress
 7933                           831                 :            842 : ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
                                832                 :                : {
 4024 alvherre@alvh.no-ip.      833                 :            842 :     Oid         newowner = get_rolespec_oid(stmt->newowner, false);
                                834                 :                : 
 7933 tgl@sss.pgh.pa.us         835   [ +  +  +  +  :            836 :     switch (stmt->objectType)
                                     +  +  +  +  +  
                                                 - ]
                                836                 :                :     {
                                837                 :             45 :         case OBJECT_DATABASE:
 1648 peter@eisentraut.org      838                 :             45 :             return AlterDatabaseOwner(strVal(stmt->object), newowner);
                                839                 :                : 
 7933 tgl@sss.pgh.pa.us         840                 :             32 :         case OBJECT_SCHEMA:
 1648 peter@eisentraut.org      841                 :             32 :             return AlterSchemaOwner(strVal(stmt->object), newowner);
                                842                 :                : 
 7933 tgl@sss.pgh.pa.us         843                 :             66 :         case OBJECT_TYPE:
                                844                 :                :         case OBJECT_DOMAIN:     /* same as TYPE */
 3410 peter_e@gmx.net           845                 :             66 :             return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
                                846                 :                :             break;
                                847                 :                : 
 6295                           848                 :             10 :         case OBJECT_FDW:
 1648 peter@eisentraut.org      849                 :             10 :             return AlterForeignDataWrapperOwner(strVal(stmt->object),
                                850                 :                :                                                 newowner);
                                851                 :                : 
 6295 peter_e@gmx.net           852                 :             34 :         case OBJECT_FOREIGN_SERVER:
 1648 peter@eisentraut.org      853                 :             34 :             return AlterForeignServerOwner(strVal(stmt->object),
                                854                 :                :                                            newowner);
                                855                 :                : 
 4988 rhaas@postgresql.org      856                 :              7 :         case OBJECT_EVENT_TRIGGER:
 1648 peter@eisentraut.org      857                 :              7 :             return AlterEventTriggerOwner(strVal(stmt->object),
                                858                 :                :                                           newowner);
                                859                 :                : 
 3342 peter_e@gmx.net           860                 :             18 :         case OBJECT_PUBLICATION:
 1648 peter@eisentraut.org      861                 :             18 :             return AlterPublicationOwner(strVal(stmt->object),
                                862                 :                :                                          newowner);
                                863                 :                : 
 3342 peter_e@gmx.net           864                 :              9 :         case OBJECT_SUBSCRIPTION:
 1648 peter@eisentraut.org      865                 :              9 :             return AlterSubscriptionOwner(strVal(stmt->object),
                                866                 :                :                                           newowner);
                                867                 :                : 
                                868                 :                :             /* Generic cases */
 4911 alvherre@alvh.no-ip.      869                 :            615 :         case OBJECT_AGGREGATE:
                                870                 :                :         case OBJECT_COLLATION:
                                871                 :                :         case OBJECT_CONVERSION:
                                872                 :                :         case OBJECT_FUNCTION:
                                873                 :                :         case OBJECT_LANGUAGE:
                                874                 :                :         case OBJECT_LARGEOBJECT:
                                875                 :                :         case OBJECT_OPERATOR:
                                876                 :                :         case OBJECT_OPCLASS:
                                877                 :                :         case OBJECT_OPFAMILY:
                                878                 :                :         case OBJECT_PROCEDURE:
                                879                 :                :         case OBJECT_ROUTINE:
                                880                 :                :         case OBJECT_STATISTIC_EXT:
                                881                 :                :         case OBJECT_TABLESPACE:
                                882                 :                :         case OBJECT_TSDICTIONARY:
                                883                 :                :         case OBJECT_TSCONFIGURATION:
                                884                 :                :             {
                                885                 :                :                 ObjectAddress address;
                                886                 :                : 
                                887                 :            615 :                 address = get_object_address(stmt->objectType,
                                888                 :                :                                              stmt->object,
                                889                 :                :                                              NULL,
                                890                 :                :                                              AccessExclusiveLock,
                                891                 :                :                                              false);
                                892                 :                : 
  821 tgl@sss.pgh.pa.us         893                 :            611 :                 AlterObjectOwner_internal(address.classId, address.objectId,
                                894                 :                :                                           newowner);
                                895                 :                : 
 4030 alvherre@alvh.no-ip.      896                 :            524 :                 return address;
                                897                 :                :             }
                                898                 :                :             break;
                                899                 :                : 
 7933 tgl@sss.pgh.pa.us         900                 :UBC           0 :         default:
                                901         [ #  # ]:              0 :             elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
                                902                 :                :                  (int) stmt->objectType);
                                903                 :                :             return InvalidObjectAddress;    /* keep compiler happy */
                                904                 :                :     }
                                905                 :                : }
                                906                 :                : 
                                907                 :                : /*
                                908                 :                :  * Generic function to change the ownership of a given object, for simple
                                909                 :                :  * cases (won't work for tables, nor other cases where we need to do more than
                                910                 :                :  * change the ownership column of a single catalog entry).
                                911                 :                :  *
                                912                 :                :  * classId: OID of catalog containing object
                                913                 :                :  * objectId: OID of object to change the ownership of
                                914                 :                :  * new_ownerId: OID of new object owner
                                915                 :                :  *
                                916                 :                :  * This will work on large objects, but we have to beware of the fact that
                                917                 :                :  * classId isn't the OID of the catalog to modify in that case.
                                918                 :                :  */
                                919                 :                : void
  821 tgl@sss.pgh.pa.us         920                 :CBC         621 : AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
                                921                 :                : {
                                922                 :                :     /* For large objects, the catalog to modify is pg_largeobject_metadata */
                                923         [ +  + ]:            621 :     Oid         catalogId = (classId == LargeObjectRelationId) ? LargeObjectMetadataRelationId : classId;
                                924                 :            621 :     AttrNumber  Anum_oid = get_object_attnum_oid(catalogId);
                                925                 :            621 :     AttrNumber  Anum_owner = get_object_attnum_owner(catalogId);
                                926                 :            621 :     AttrNumber  Anum_namespace = get_object_attnum_namespace(catalogId);
                                927                 :            621 :     AttrNumber  Anum_acl = get_object_attnum_acl(catalogId);
                                928                 :            621 :     AttrNumber  Anum_name = get_object_attnum_name(catalogId);
                                929                 :                :     Relation    rel;
                                930                 :                :     HeapTuple   oldtup;
                                931                 :                :     Datum       datum;
                                932                 :                :     bool        isnull;
                                933                 :                :     Oid         old_ownerId;
 4911 alvherre@alvh.no-ip.      934                 :            621 :     Oid         namespaceId = InvalidOid;
                                935                 :                : 
  821 tgl@sss.pgh.pa.us         936                 :            621 :     rel = table_open(catalogId, RowExclusiveLock);
                                937                 :                : 
                                938                 :                :     /* Search tuple and lock it. */
                                939                 :                :     oldtup =
  442 noah@leadboat.com         940                 :            621 :         get_catalog_object_by_oid_extended(rel, Anum_oid, objectId, true);
 4911 alvherre@alvh.no-ip.      941         [ -  + ]:            621 :     if (oldtup == NULL)
 4911 alvherre@alvh.no-ip.      942         [ #  # ]:UBC           0 :         elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
                                943                 :                :              objectId, RelationGetRelationName(rel));
                                944                 :                : 
 4911 alvherre@alvh.no-ip.      945                 :CBC         621 :     datum = heap_getattr(oldtup, Anum_owner,
                                946                 :                :                          RelationGetDescr(rel), &isnull);
                                947         [ -  + ]:            621 :     Assert(!isnull);
                                948                 :            621 :     old_ownerId = DatumGetObjectId(datum);
                                949                 :                : 
                                950         [ +  + ]:            621 :     if (Anum_namespace != InvalidAttrNumber)
                                951                 :                :     {
                                952                 :            534 :         datum = heap_getattr(oldtup, Anum_namespace,
                                953                 :                :                              RelationGetDescr(rel), &isnull);
                                954         [ -  + ]:            534 :         Assert(!isnull);
                                955                 :            534 :         namespaceId = DatumGetObjectId(datum);
                                956                 :                :     }
                                957                 :                : 
                                958         [ +  + ]:            621 :     if (old_ownerId != new_ownerId)
                                959                 :                :     {
                                960                 :                :         AttrNumber  nattrs;
                                961                 :                :         HeapTuple   newtup;
                                962                 :                :         Datum      *values;
                                963                 :                :         bool       *nulls;
                                964                 :                :         bool       *replaces;
                                965                 :                : 
                                966                 :                :         /* Superusers can bypass permission checks */
                                967         [ +  + ]:            194 :         if (!superuser())
                                968                 :                :         {
                                969                 :                :             /* must be owner */
                                970         [ +  + ]:            117 :             if (!has_privs_of_role(GetUserId(), old_ownerId))
                                971                 :                :             {
                                972                 :                :                 char       *objname;
                                973                 :                :                 char        namebuf[NAMEDATALEN];
                                974                 :                : 
                                975         [ +  - ]:             30 :                 if (Anum_name != InvalidAttrNumber)
                                976                 :                :                 {
                                977                 :             30 :                     datum = heap_getattr(oldtup, Anum_name,
                                978                 :                :                                          RelationGetDescr(rel), &isnull);
                                979         [ -  + ]:             30 :                     Assert(!isnull);
                                980                 :             30 :                     objname = NameStr(*DatumGetName(datum));
                                981                 :                :                 }
                                982                 :                :                 else
                                983                 :                :                 {
 2672 andres@anarazel.de        984                 :UBC           0 :                     snprintf(namebuf, sizeof(namebuf), "%u", objectId);
 4911 alvherre@alvh.no-ip.      985                 :              0 :                     objname = namebuf;
                                986                 :                :                 }
  821 tgl@sss.pgh.pa.us         987                 :CBC          30 :                 aclcheck_error(ACLCHECK_NOT_OWNER,
                                988                 :                :                                get_object_type(catalogId, objectId),
                                989                 :                :                                objname);
                                990                 :                :             }
                                991                 :                :             /* Must be able to become new owner */
 1213 rhaas@postgresql.org      992                 :             87 :             check_can_set_role(GetUserId(), new_ownerId);
                                993                 :                : 
                                994                 :                :             /* New owner must have CREATE privilege on namespace */
 4911 alvherre@alvh.no-ip.      995         [ +  + ]:             30 :             if (OidIsValid(namespaceId))
                                996                 :                :             {
                                997                 :                :                 AclResult   aclresult;
                                998                 :                : 
 1218 peter@eisentraut.org      999                 :             27 :                 aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
                               1000                 :                :                                             ACL_CREATE);
 4911 alvherre@alvh.no-ip.     1001         [ -  + ]:             27 :                 if (aclresult != ACLCHECK_OK)
 3025 peter_e@gmx.net          1002                 :UBC           0 :                     aclcheck_error(aclresult, OBJECT_SCHEMA,
 4911 alvherre@alvh.no-ip.     1003                 :              0 :                                    get_namespace_name(namespaceId));
                               1004                 :                :             }
                               1005                 :                :         }
                               1006                 :                : 
                               1007                 :                :         /* Build a modified tuple */
 4911 alvherre@alvh.no-ip.     1008                 :CBC         107 :         nattrs = RelationGetNumberOfAttributes(rel);
                               1009                 :            107 :         values = palloc0(nattrs * sizeof(Datum));
                               1010                 :            107 :         nulls = palloc0(nattrs * sizeof(bool));
                               1011                 :            107 :         replaces = palloc0(nattrs * sizeof(bool));
                               1012                 :            107 :         values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
                               1013                 :            107 :         replaces[Anum_owner - 1] = true;
                               1014                 :                : 
                               1015                 :                :         /*
                               1016                 :                :          * Determine the modified ACL for the new owner.  This is only
                               1017                 :                :          * necessary when the ACL is non-null.
                               1018                 :                :          */
                               1019         [ +  + ]:            107 :         if (Anum_acl != InvalidAttrNumber)
                               1020                 :                :         {
                               1021                 :             58 :             datum = heap_getattr(oldtup,
                               1022                 :                :                                  Anum_acl, RelationGetDescr(rel), &isnull);
                               1023         [ +  + ]:             58 :             if (!isnull)
                               1024                 :                :             {
                               1025                 :                :                 Acl        *newAcl;
                               1026                 :                : 
                               1027                 :              4 :                 newAcl = aclnewowner(DatumGetAclP(datum),
                               1028                 :                :                                      old_ownerId, new_ownerId);
                               1029                 :              4 :                 values[Anum_acl - 1] = PointerGetDatum(newAcl);
                               1030                 :              4 :                 replaces[Anum_acl - 1] = true;
                               1031                 :                :             }
                               1032                 :                :         }
                               1033                 :                : 
                               1034                 :            107 :         newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
                               1035                 :                :                                    values, nulls, replaces);
                               1036                 :                : 
                               1037                 :                :         /* Perform actual update */
 3330                          1038                 :            107 :         CatalogTupleUpdate(rel, &newtup->t_self, newtup);
                               1039                 :                : 
  442 noah@leadboat.com        1040                 :            107 :         UnlockTuple(rel, &oldtup->t_self, InplaceUpdateTupleLock);
                               1041                 :                : 
                               1042                 :                :         /* Update owner dependency reference */
 2672 andres@anarazel.de       1043                 :            107 :         changeDependencyOnOwner(classId, objectId, new_ownerId);
                               1044                 :                : 
                               1045                 :                :         /* Release memory */
 4911 alvherre@alvh.no-ip.     1046                 :            107 :         pfree(values);
                               1047                 :            107 :         pfree(nulls);
                               1048                 :            107 :         pfree(replaces);
                               1049                 :                :     }
                               1050                 :                :     else
  442 noah@leadboat.com        1051                 :            427 :         UnlockTuple(rel, &oldtup->t_self, InplaceUpdateTupleLock);
                               1052                 :                : 
                               1053                 :                :     /* Note the post-alter hook gets classId not catalogId */
 4746 rhaas@postgresql.org     1054         [ -  + ]:            534 :     InvokeObjectPostAlterHook(classId, objectId, 0);
                               1055                 :                : 
  821 tgl@sss.pgh.pa.us        1056                 :            534 :     table_close(rel, RowExclusiveLock);
 4911 alvherre@alvh.no-ip.     1057                 :            534 : }
        

Generated by: LCOV version 2.4-beta