LCOV - differential code coverage report
Current view: top level - src/backend/commands - alter.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 91.3 % 369 337 32 1 336 1
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 10 10 1 9
Baseline: lcov-20250906-005545-baseline Branches: 67.0 % 224 150 74 2 148
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 1 1 1
(30,360] days: 100.0 % 6 6 6
(360..) days: 91.2 % 362 330 32 330
Function coverage date bins:
(360..) days: 100.0 % 10 10 1 9
Branch coverage date bins:
(7,30] days: 100.0 % 2 2 2
(30,360] days: 100.0 % 2 2 2
(360..) days: 66.4 % 220 146 74 146

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

Generated by: LCOV version 2.4-beta