]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Introduce ATT_PARTITIONED_TABLE in tablecmds.c
authorMichael Paquier <michael@paquier.xyz>
Thu, 19 Sep 2024 03:22:56 +0000 (12:22 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 19 Sep 2024 03:22:56 +0000 (12:22 +0900)
Partitioned tables and normal tables have been relying on ATT_TABLE in
ATSimplePermissions() to produce error messages that depend on the
relation's relkind, because both relkinds currently support the same set
of ALTER TABLE subcommands.

A patch to restrict SET LOGGED/UNLOGGED for partitioned tables is under
discussion, and introducing ATT_PARTITIONED_TABLE makes subcommand
restrictions for partitioned tables easier to deal with, so let's add
one.  There is no functional change.

Author: Michael Paquier
Reviewed-by: Nathan Bossart
Discussion: https://postgr.es/m/Zt6cDnwSvnuLLnak@paquier.xyz

src/backend/commands/tablecmds.c

index 022ddf172a31c1ec580e5bbb02dfd321f75fa685..2d703aa22e2685c03fb6a5ef43c0daf82524d3f3 100644 (file)
@@ -332,6 +332,7 @@ struct DropRelationCallbackState
 #define                ATT_FOREIGN_TABLE               0x0020
 #define                ATT_PARTITIONED_INDEX   0x0040
 #define                ATT_SEQUENCE                    0x0080
+#define                ATT_PARTITIONED_TABLE   0x0100
 
 /*
  * ForeignTruncateInfo
@@ -4783,7 +4784,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
        {
                case AT_AddColumn:              /* ADD COLUMN */
                        ATSimplePermissions(cmd->subtype, rel,
-                                                               ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
                        ATPrepAddColumn(wqueue, rel, recurse, recursing, false, cmd,
                                                        lockmode, context);
                        /* Recursion occurs during execution phase */
@@ -4804,7 +4806,9 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                         * substitutes default values into INSERTs before it expands
                         * rules.
                         */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_VIEW |
+                                                               ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        /* No command-specific prep needed */
                        pass = cmd->def ? AT_PASS_ADD_OTHERCONSTR : AT_PASS_DROP;
@@ -4812,19 +4816,24 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                case AT_CookedColumnDefault:    /* add a pre-cooked default */
                        /* This is currently used only in CREATE TABLE */
                        /* (so the permission check really isn't necessary) */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* This command never recurses */
                        pass = AT_PASS_ADD_OTHERCONSTR;
                        break;
                case AT_AddIdentity:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_VIEW |
+                                                               ATT_FOREIGN_TABLE);
                        /* Set up recursion for phase 2; no other prep needed */
                        if (recurse)
                                cmd->recurse = true;
                        pass = AT_PASS_ADD_OTHERCONSTR;
                        break;
                case AT_SetIdentity:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_VIEW |
+                                                               ATT_FOREIGN_TABLE);
                        /* Set up recursion for phase 2; no other prep needed */
                        if (recurse)
                                cmd->recurse = true;
@@ -4832,82 +4841,98 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_MISC;
                        break;
                case AT_DropIdentity:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_VIEW |
+                                                               ATT_FOREIGN_TABLE);
                        /* Set up recursion for phase 2; no other prep needed */
                        if (recurse)
                                cmd->recurse = true;
                        pass = AT_PASS_DROP;
                        break;
                case AT_DropNotNull:    /* ALTER COLUMN DROP NOT NULL */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        ATPrepDropNotNull(rel, recurse, recursing);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        pass = AT_PASS_DROP;
                        break;
                case AT_SetNotNull:             /* ALTER COLUMN SET NOT NULL */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* Need command-specific recursion decision */
                        ATPrepSetNotNull(wqueue, rel, cmd, recurse, recursing,
                                                         lockmode, context);
                        pass = AT_PASS_COL_ATTRS;
                        break;
                case AT_CheckNotNull:   /* check column is already marked NOT NULL */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        /* No command-specific prep needed */
                        pass = AT_PASS_COL_ATTRS;
                        break;
                case AT_SetExpression:  /* ALTER COLUMN SET EXPRESSION */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        pass = AT_PASS_SET_EXPRESSION;
                        break;
                case AT_DropExpression: /* ALTER COLUMN DROP EXPRESSION */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        ATPrepDropExpression(rel, cmd, recurse, recursing, lockmode);
                        pass = AT_PASS_DROP;
                        break;
                case AT_SetStatistics:  /* ALTER COLUMN SET STATISTICS */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_PARTITIONED_INDEX | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW |
+                                                               ATT_INDEX | ATT_PARTITIONED_INDEX | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_SetOptions:             /* ALTER COLUMN SET ( options ) */
                case AT_ResetOptions:   /* ALTER COLUMN RESET ( options ) */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_MATVIEW | ATT_FOREIGN_TABLE);
                        /* This command never recurses */
                        pass = AT_PASS_MISC;
                        break;
                case AT_SetStorage:             /* ALTER COLUMN SET STORAGE */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_MATVIEW | ATT_FOREIGN_TABLE);
                        ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context);
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_SetCompression: /* ALTER COLUMN SET COMPRESSION */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW);
                        /* This command never recurses */
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_DropColumn:             /* DROP COLUMN */
                        ATSimplePermissions(cmd->subtype, rel,
-                                                               ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
                        ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd,
                                                         lockmode, context);
                        /* Recursion occurs during execution phase */
                        pass = AT_PASS_DROP;
                        break;
                case AT_AddIndex:               /* ADD INDEX */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* This command never recurses */
                        /* No command-specific prep needed */
                        pass = AT_PASS_ADD_INDEX;
                        break;
                case AT_AddConstraint:  /* ADD CONSTRAINT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* Recursion occurs during execution phase */
                        /* No command-specific prep needed except saving recurse flag */
                        if (recurse)
@@ -4915,13 +4940,14 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_ADD_CONSTR;
                        break;
                case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* This command never recurses */
                        /* No command-specific prep needed */
                        pass = AT_PASS_ADD_INDEXCONSTR;
                        break;
                case AT_DropConstraint: /* DROP CONSTRAINT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        ATCheckPartitionsNotInUse(rel, lockmode);
                        /* Other recursion occurs during execution phase */
                        /* No command-specific prep needed except saving recurse flag */
@@ -4931,7 +4957,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        break;
                case AT_AlterColumnType:        /* ALTER COLUMN TYPE */
                        ATSimplePermissions(cmd->subtype, rel,
-                                                               ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
                        /* See comments for ATPrepAlterColumnType */
                        cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, recurse, lockmode,
                                                                          AT_PASS_UNSET, context);
@@ -4954,14 +4981,16 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        break;
                case AT_ClusterOn:              /* CLUSTER ON */
                case AT_DropCluster:    /* SET WITHOUT CLUSTER */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW);
                        /* These commands never recurse */
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_SetLogged:              /* SET LOGGED */
                case AT_SetUnLogged:    /* SET UNLOGGED */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_SEQUENCE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_SEQUENCE);
                        if (tab->chgPersistence)
                                ereport(ERROR,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4970,11 +4999,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_MISC;
                        break;
                case AT_DropOids:               /* SET WITHOUT OIDS */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        pass = AT_PASS_DROP;
                        break;
                case AT_SetAccessMethod:        /* SET ACCESS METHOD */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW);
 
                        /* check if another access method change was already requested */
                        if (tab->chgAccessMethod)
@@ -4986,8 +5017,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_MISC;    /* does not matter; no work in Phase 2 */
                        break;
                case AT_SetTableSpace:  /* SET TABLESPACE */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_INDEX |
-                                                               ATT_PARTITIONED_INDEX);
+                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABLE |
+                                                               ATT_MATVIEW | ATT_INDEX | ATT_PARTITIONED_INDEX);
                        /* This command never recurses */
                        ATPrepSetTableSpace(tab, rel, cmd->name, lockmode);
                        pass = AT_PASS_MISC;    /* doesn't actually matter */
@@ -4995,30 +5026,36 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                case AT_SetRelOptions:  /* SET (...) */
                case AT_ResetRelOptions:        /* RESET (...) */
                case AT_ReplaceRelOptions:      /* reset them all, then set just these */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_MATVIEW | ATT_INDEX);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_VIEW |
+                                                               ATT_MATVIEW | ATT_INDEX);
                        /* This command never recurses */
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_AddInherit:             /* INHERIT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* This command never recurses */
                        ATPrepAddInherit(rel);
                        pass = AT_PASS_MISC;
                        break;
                case AT_DropInherit:    /* NO INHERIT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* This command never recurses */
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_AlterConstraint:        /* ALTER CONSTRAINT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* Recursion occurs during execution phase */
                        pass = AT_PASS_MISC;
                        break;
                case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* Recursion occurs during execution phase */
                        /* No command-specific prep needed except saving recurse flag */
                        if (recurse)
@@ -5026,7 +5063,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_MISC;
                        break;
                case AT_ReplicaIdentity:        /* REPLICA IDENTITY ... */
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_MATVIEW);
                        pass = AT_PASS_MISC;
                        /* This command never recurses */
                        /* No command-specific prep needed */
@@ -5039,7 +5077,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                case AT_DisableTrig:    /* DISABLE TRIGGER variants */
                case AT_DisableTrigAll:
                case AT_DisableTrigUser:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
                        /* Set up recursion for phase 2; no other prep needed */
                        if (recurse)
                                cmd->recurse = true;
@@ -5055,7 +5094,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                case AT_DisableRowSecurity:
                case AT_ForceRowSecurity:
                case AT_NoForceRowSecurity:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* These commands never recurse */
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
@@ -5066,17 +5106,20 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
                        pass = AT_PASS_MISC;
                        break;
                case AT_AttachPartition:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_INDEX);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_PARTITIONED_INDEX);
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_DetachPartition:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
                case AT_DetachPartitionFinalize:
-                       ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
+                       ATSimplePermissions(cmd->subtype, rel,
+                                                               ATT_TABLE | ATT_PARTITIONED_TABLE);
                        /* No command-specific prep needed */
                        pass = AT_PASS_MISC;
                        break;
@@ -6493,9 +6536,11 @@ ATSimplePermissions(AlterTableType cmdtype, Relation rel, int allowed_targets)
        switch (rel->rd_rel->relkind)
        {
                case RELKIND_RELATION:
-               case RELKIND_PARTITIONED_TABLE:
                        actual_target = ATT_TABLE;
                        break;
+               case RELKIND_PARTITIONED_TABLE:
+                       actual_target = ATT_PARTITIONED_TABLE;
+                       break;
                case RELKIND_VIEW:
                        actual_target = ATT_VIEW;
                        break;
@@ -6989,7 +7034,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 
        /* At top level, permission check was done in ATPrepCmd, else do it */
        if (recursing)
-               ATSimplePermissions((*cmd)->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+               ATSimplePermissions((*cmd)->subtype, rel,
+                                                       ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        if (rel->rd_rel->relispartition && !recursing)
                ereport(ERROR,
@@ -8913,7 +8959,8 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
 
        /* At top level, permission check was done in ATPrepCmd, else do it */
        if (recursing)
-               ATSimplePermissions(AT_DropColumn, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+               ATSimplePermissions(AT_DropColumn, rel,
+                                                       ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        /* Initialize addrs on the first invocation */
        Assert(!recursing || addrs != NULL);
@@ -9402,7 +9449,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
 
        /* At top level, permission check was done in ATPrepCmd, else do it */
        if (recursing)
-               ATSimplePermissions(AT_AddConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+               ATSimplePermissions(AT_AddConstraint, rel,
+                                                       ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        /*
         * Call AddRelationNewConstraints to do the work, making sure it works on
@@ -12549,7 +12597,8 @@ ATExecDropConstraint(Relation rel, const char *constrName,
 
        /* At top level, permission check was done in ATPrepCmd, else do it */
        if (recursing)
-               ATSimplePermissions(AT_DropConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+               ATSimplePermissions(AT_DropConstraint, rel,
+                                                       ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        conrel = table_open(ConstraintRelationId, RowExclusiveLock);
 
@@ -15631,7 +15680,8 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
         * Must be owner of both parent and child -- child was checked by
         * ATSimplePermissions call in ATPrepCmd
         */
-       ATSimplePermissions(AT_AddInherit, parent_rel, ATT_TABLE | ATT_FOREIGN_TABLE);
+       ATSimplePermissions(AT_AddInherit, parent_rel,
+                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        /* Permanent rels cannot inherit from temporary ones */
        if (parent_rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
@@ -18476,7 +18526,8 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd,
         * Must be owner of both parent and source table -- parent was checked by
         * ATSimplePermissions call in ATPrepCmd
         */
-       ATSimplePermissions(AT_AttachPartition, attachrel, ATT_TABLE | ATT_FOREIGN_TABLE);
+       ATSimplePermissions(AT_AttachPartition, attachrel,
+                                               ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE);
 
        /* A partition can only have one parent */
        if (attachrel->rd_rel->relispartition)