LCOV - differential code coverage report
Current view: top level - src/backend/commands - alter.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 87.8 % 368 323 5 40 15 308 4 25
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 10 10 5 5 1
Baseline: 16@8cea358b128 Branches: 63.9 % 230 147 9 74 5 142
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 33.3 % 6 2 4 2
(120,180] days: 100.0 % 11 11 11
(240..) days: 88.3 % 351 310 1 40 2 308
Function coverage date bins:
(120,180] days: 100.0 % 1 1 1
(240..) days: 100.0 % 9 9 4 5
Branch coverage date bins:
[..60] days: 16.7 % 6 1 5 1
(120,180] days: 100.0 % 2 2 2
(240..) days: 64.9 % 222 144 4 74 2 142

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

Generated by: LCOV version 2.1-beta2-3-g6141622