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

Generated by: LCOV version 2.5.0-beta