LCOV - differential code coverage report
Current view: top level - src/backend/commands - alter.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 88.3 % 375 331 3 9 26 6 9 185 12 125 28 195 1 2
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 10 10 10 10
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 87.5 % 8 7 1 7
Legend: Lines: hit not hit (60,120] days: 100.0 % 1 1 1
(120,180] days: 66.7 % 6 4 2 4
(240..) days: 88.6 % 360 319 9 26 6 9 185 125 28 182
Function coverage date bins:
(240..) days: 50.0 % 20 10 10 10

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

Generated by: LCOV version v1.16-55-g56c0a2a