@ -398,8 +398,7 @@ static void ATRewriteTables(AlterTableStmt *parsetree,
AlterTableUtilityContext * context ) ;
static void ATRewriteTable ( AlteredTableInfo * tab , Oid OIDNewHeap , LOCKMODE lockmode ) ;
static AlteredTableInfo * ATGetQueueEntry ( List * * wqueue , Relation rel ) ;
static void ATSimplePermissions ( Relation rel , int allowed_targets ) ;
static void ATWrongRelkindError ( Relation rel , int allowed_targets ) ;
static void ATSimplePermissions ( AlterTableType cmdtype , Relation rel , int allowed_targets ) ;
static void ATSimpleRecursion ( List * * wqueue , Relation rel ,
AlterTableCmd * cmd , bool recurse , LOCKMODE lockmode ,
AlterTableUtilityContext * context ) ;
@ -3394,8 +3393,9 @@ renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing)
relkind ! = RELKIND_PARTITIONED_TABLE )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " \" %s \" is not a table, view, materialized view, composite type, index, or foreign table " ,
NameStr ( classform - > relname ) ) ) ) ;
errmsg ( " cannot rename columns of relation \" %s \" " ,
NameStr ( classform - > relname ) ) ,
errdetail_relkind_not_supported ( relkind ) ) ) ;
/*
* permissions checking . only the owner of a class can change its schema .
@ -4422,7 +4422,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
switch ( cmd - > subtype )
{
case AT_AddColumn : /* ADD COLUMN */
ATSimplePermissions ( rel ,
ATSimplePermissions ( cmd - > subtype , rel ,
ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE ) ;
ATPrepAddColumn ( wqueue , rel , recurse , recursing , false , cmd ,
lockmode , context ) ;
@ -4430,7 +4430,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_ADD_COL ;
break ;
case AT_AddColumnToView : /* add column via CREATE OR REPLACE VIEW */
ATSimplePermissions ( rel , ATT_VIEW ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_VIEW ) ;
ATPrepAddColumn ( wqueue , rel , recurse , recursing , true , cmd ,
lockmode , context ) ;
/* Recursion occurs during execution phase */
@ -4444,7 +4444,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
* substitutes default values into INSERTs before it expands
* rules .
*/
ATSimplePermissions ( rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ;
@ -4452,77 +4452,77 @@ 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 ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
pass = AT_PASS_ADD_OTHERCONSTR ;
break ;
case AT_AddIdentity :
ATSimplePermissions ( rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
pass = AT_PASS_ADD_OTHERCONSTR ;
break ;
case AT_SetIdentity :
ATSimplePermissions ( rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
/* This should run after AddIdentity, so do it in MISC pass */
pass = AT_PASS_MISC ;
break ;
case AT_DropIdentity :
ATSimplePermissions ( rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
pass = AT_PASS_DROP ;
break ;
case AT_DropNotNull : /* ALTER COLUMN DROP NOT NULL */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimpleRecursion ( wqueue , rel , cmd , recurse , lockmode , context ) ;
/* No command-specific prep needed */
pass = AT_PASS_COL_ATTRS ;
break ;
case AT_DropExpression : /* ALTER COLUMN DROP EXPRESSION */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_PARTITIONED_INDEX | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
pass = AT_PASS_MISC ;
break ;
case AT_SetStorage : /* ALTER COLUMN SET STORAGE */
ATSimplePermissions ( rel , ATT_TABLE | ATT_MATVIEW | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_MATVIEW ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_MATVIEW ) ;
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_DropColumn : /* DROP COLUMN */
ATSimplePermissions ( rel ,
ATSimplePermissions ( cmd - > subtype , rel ,
ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE ) ;
ATPrepDropColumn ( wqueue , rel , recurse , recursing , cmd ,
lockmode , context ) ;
@ -4530,13 +4530,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_DROP ;
break ;
case AT_AddIndex : /* ADD INDEX */
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_ADD_INDEX ;
break ;
case AT_AddConstraint : /* ADD CONSTRAINT */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* Recursion occurs during execution phase */
/* No command-specific prep needed except saving recurse flag */
if ( recurse )
@ -4544,13 +4544,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_ADD_CONSTR ;
break ;
case AT_AddIndexConstraint : /* ADD CONSTRAINT USING INDEX */
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_ADD_INDEXCONSTR ;
break ;
case AT_DropConstraint : /* DROP CONSTRAINT */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATCheckPartitionsNotInUse ( rel , lockmode ) ;
/* Other recursion occurs during execution phase */
/* No command-specific prep needed except saving recurse flag */
@ -4559,7 +4559,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_DROP ;
break ;
case AT_AlterColumnType : /* ALTER COLUMN TYPE */
ATSimplePermissions ( rel ,
ATSimplePermissions ( cmd - > subtype , rel ,
ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE ) ;
/* See comments for ATPrepAlterColumnType */
cmd = ATParseTransformCmd ( wqueue , tab , rel , cmd , recurse , lockmode ,
@ -4571,7 +4571,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_ALTER_TYPE ;
break ;
case AT_AlterColumnGenericOptions :
ATSimplePermissions ( rel , ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
@ -4583,13 +4583,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
break ;
case AT_ClusterOn : /* CLUSTER ON */
case AT_DropCluster : /* SET WITHOUT CLUSTER */
ATSimplePermissions ( rel , ATT_TABLE | ATT_MATVIEW ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_MATVIEW ) ;
/* These commands never recurse */
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_SetLogged : /* SET LOGGED */
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
if ( tab - > chgPersistence )
ereport ( ERROR ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
@ -4604,7 +4604,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_MISC ;
break ;
case AT_SetUnLogged : /* SET UNLOGGED */
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
if ( tab - > chgPersistence )
ereport ( ERROR ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
@ -4619,11 +4619,11 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_MISC ;
break ;
case AT_DropOids : /* SET WITHOUT OIDS */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
pass = AT_PASS_DROP ;
break ;
case AT_SetTableSpace : /* SET TABLESPACE */
ATSimplePermissions ( rel , ATT_TABLE | ATT_MATVIEW | ATT_INDEX |
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_MATVIEW | ATT_INDEX |
ATT_PARTITIONED_INDEX ) ;
/* This command never recurses */
ATPrepSetTableSpace ( tab , rel , cmd - > name , lockmode ) ;
@ -4632,30 +4632,30 @@ 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 ( rel , ATT_TABLE | ATT_VIEW | ATT_MATVIEW | ATT_INDEX ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_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 ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
ATPrepAddInherit ( rel ) ;
pass = AT_PASS_MISC ;
break ;
case AT_DropInherit : /* NO INHERIT */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_AlterConstraint : /* ALTER CONSTRAINT */
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* Recursion occurs during execution phase */
pass = AT_PASS_MISC ;
break ;
case AT_ValidateConstraint : /* VALIDATE CONSTRAINT */
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* Recursion occurs during execution phase */
/* No command-specific prep needed except saving recurse flag */
if ( recurse )
@ -4663,7 +4663,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_MISC ;
break ;
case AT_ReplicaIdentity : /* REPLICA IDENTITY ... */
ATSimplePermissions ( rel , ATT_TABLE | ATT_MATVIEW ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_MATVIEW ) ;
pass = AT_PASS_MISC ;
/* This command never recurses */
/* No command-specific prep needed */
@ -4676,7 +4676,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
case AT_DisableTrig : /* DISABLE TRIGGER variants */
case AT_DisableTrigAll :
case AT_DisableTrigUser :
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE )
ATSimpleRecursion ( wqueue , rel , cmd , recurse , lockmode , context ) ;
pass = AT_PASS_MISC ;
@ -4691,28 +4691,28 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
case AT_DisableRowSecurity :
case AT_ForceRowSecurity :
case AT_NoForceRowSecurity :
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* These commands never recurse */
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_GenericOptions :
ATSimplePermissions ( rel , ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_FOREIGN_TABLE ) ;
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_AttachPartition :
ATSimplePermissions ( rel , ATT_TABLE | ATT_PARTITIONED_INDEX ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE | ATT_PARTITIONED_INDEX ) ;
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_DetachPartition :
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
case AT_DetachPartitionFinalize :
ATSimplePermissions ( rel , ATT_TABLE ) ;
ATSimplePermissions ( cmd - > subtype , rel , ATT_TABLE ) ;
/* No command-specific prep needed */
pass = AT_PASS_MISC ;
break ;
@ -5941,6 +5941,145 @@ ATGetQueueEntry(List **wqueue, Relation rel)
return tab ;
}
static const char *
alter_table_type_to_string ( AlterTableType cmdtype )
{
switch ( cmdtype )
{
case AT_AddColumn :
case AT_AddColumnRecurse :
case AT_AddColumnToView :
return " ADD COLUMN " ;
case AT_ColumnDefault :
case AT_CookedColumnDefault :
return " ALTER COLUMN ... SET DEFAULT " ;
case AT_DropNotNull :
return " ALTER COLUMN ... DROP NOT NULL " ;
case AT_SetNotNull :
return " ALTER COLUMN ... SET NOT NULL " ;
case AT_DropExpression :
return " ALTER COLUMN ... DROP EXPRESSION " ;
case AT_CheckNotNull :
return NULL ; /* not real grammar */
case AT_SetStatistics :
return " ALTER COLUMN ... SET STATISTICS " ;
case AT_SetOptions :
return " ALTER COLUMN ... SET " ;
case AT_ResetOptions :
return " ALTER COLUMN ... RESET " ;
case AT_SetStorage :
return " ALTER COLUMN ... SET STORAGE " ;
case AT_SetCompression :
return " ALTER COLUMN ... SET COMPRESSION " ;
case AT_DropColumn :
case AT_DropColumnRecurse :
return " DROP COLUMN " ;
case AT_AddIndex :
case AT_ReAddIndex :
return NULL ; /* not real grammar */
case AT_AddConstraint :
case AT_AddConstraintRecurse :
case AT_ReAddConstraint :
case AT_ReAddDomainConstraint :
case AT_AddIndexConstraint :
return " ADD CONSTRAINT " ;
case AT_AlterConstraint :
return " ALTER CONSTRAINT " ;
case AT_ValidateConstraint :
case AT_ValidateConstraintRecurse :
return " VALIDATE CONSTRAINT " ;
case AT_DropConstraint :
case AT_DropConstraintRecurse :
return " DROP CONSTRAINT " ;
case AT_ReAddComment :
return NULL ; /* not real grammar */
case AT_AlterColumnType :
return " ALTER COLUMN ... SET DATA TYPE " ;
case AT_AlterColumnGenericOptions :
return " ALTER COLUMN ... OPTIONS " ;
case AT_ChangeOwner :
return " OWNER TO " ;
case AT_ClusterOn :
return " CLUSTER ON " ;
case AT_DropCluster :
return " SET WITHOUT CLUSTER " ;
case AT_SetLogged :
return " SET LOGGED " ;
case AT_SetUnLogged :
return " SET UNLOGGED " ;
case AT_DropOids :
return " SET WITHOUT OIDS " ;
case AT_SetTableSpace :
return " SET TABLESPACE " ;
case AT_SetRelOptions :
return " SET " ;
case AT_ResetRelOptions :
return " RESET " ;
case AT_ReplaceRelOptions :
return NULL ; /* not real grammar */
case AT_EnableTrig :
return " ENABLE TRIGGER " ;
case AT_EnableAlwaysTrig :
return " ENABLE ALWAYS TRIGGER " ;
case AT_EnableReplicaTrig :
return " ENABLE REPLICA TRIGGER " ;
case AT_DisableTrig :
return " DISABLE TRIGGER " ;
case AT_EnableTrigAll :
return " ENABLE TRIGGER ALL " ;
case AT_DisableTrigAll :
return " DISABLE TRIGGER ALL " ;
case AT_EnableTrigUser :
return " ENABLE TRIGGER USER " ;
case AT_DisableTrigUser :
return " DISABLE TRIGGER USER " ;
case AT_EnableRule :
return " ENABLE RULE " ;
case AT_EnableAlwaysRule :
return " ENABLE ALWAYS RULE " ;
case AT_EnableReplicaRule :
return " ENABLE REPLICA RULE " ;
case AT_DisableRule :
return " DISABLE RULE " ;
case AT_AddInherit :
return " INHERIT " ;
case AT_DropInherit :
return " NO INHERIT " ;
case AT_AddOf :
return " OF " ;
case AT_DropOf :
return " NOT OF " ;
case AT_ReplicaIdentity :
return " REPLICA IDENTITY " ;
case AT_EnableRowSecurity :
return " ENABLE ROW SECURITY " ;
case AT_DisableRowSecurity :
return " DISABLE ROW SECURITY " ;
case AT_ForceRowSecurity :
return " FORCE ROW SECURITY " ;
case AT_NoForceRowSecurity :
return " NO FORCE ROW SECURITY " ;
case AT_GenericOptions :
return " OPTIONS " ;
case AT_AttachPartition :
return " ATTACH PARTITION " ;
case AT_DetachPartition :
return " DETACH PARTITION " ;
case AT_DetachPartitionFinalize :
return " DETACH PARTITION ... FINALIZE " ;
case AT_AddIdentity :
return " ALTER COLUMN ... ADD IDENTITY " ;
case AT_SetIdentity :
return " ALTER COLUMN ... SET " ;
case AT_DropIdentity :
return " ALTER COLUMN ... DROP IDENTITY " ;
case AT_ReAddStatistics :
return NULL ; /* not real grammar */
}
return NULL ;
}
/*
* ATSimplePermissions
*
@ -5949,7 +6088,7 @@ ATGetQueueEntry(List **wqueue, Relation rel)
* - Ensure that it is not a system table
*/
static void
ATSimplePermissions ( Relation rel , int allowed_targets )
ATSimplePermissions ( AlterTableType cmdtype , Relation rel , int allowed_targets )
{
int actual_target ;
@ -5984,7 +6123,21 @@ ATSimplePermissions(Relation rel, int allowed_targets)
/* Wrong target type? */
if ( ( actual_target & allowed_targets ) = = 0 )
ATWrongRelkindError ( rel , allowed_targets ) ;
{
const char * action_str = alter_table_type_to_string ( cmdtype ) ;
if ( action_str )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
/* translator: %s is a group of some SQL keywords */
errmsg ( " ALTER action %s cannot be performed on relation \" %s \" " ,
action_str , RelationGetRelationName ( rel ) ) ,
errdetail_relkind_not_supported ( rel - > rd_rel - > relkind ) ) ) ;
else
/* internal error? */
elog ( ERROR , " invalid ALTER action attempted on relation \" %s \" " ,
RelationGetRelationName ( rel ) ) ;
}
/* Permissions checks */
if ( ! pg_class_ownercheck ( RelationGetRelid ( rel ) , GetUserId ( ) ) )
@ -5998,66 +6151,6 @@ ATSimplePermissions(Relation rel, int allowed_targets)
RelationGetRelationName ( rel ) ) ) ) ;
}
/*
* ATWrongRelkindError
*
* Throw an error when a relation has been determined to be of the wrong
* type .
*/
static void
ATWrongRelkindError ( Relation rel , int allowed_targets )
{
char * msg ;
switch ( allowed_targets )
{
case ATT_TABLE :
msg = _ ( " \" %s \" is not a table " ) ;
break ;
case ATT_TABLE | ATT_VIEW :
msg = _ ( " \" %s \" is not a table or view " ) ;
break ;
case ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a table, view, or foreign table " ) ;
break ;
case ATT_TABLE | ATT_VIEW | ATT_MATVIEW | ATT_INDEX :
msg = _ ( " \" %s \" is not a table, view, materialized view, or index " ) ;
break ;
case ATT_TABLE | ATT_MATVIEW :
msg = _ ( " \" %s \" is not a table or materialized view " ) ;
break ;
case ATT_TABLE | ATT_MATVIEW | ATT_INDEX :
msg = _ ( " \" %s \" is not a table, materialized view, or index " ) ;
break ;
case ATT_TABLE | ATT_MATVIEW | ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a table, materialized view, or foreign table " ) ;
break ;
case ATT_TABLE | ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a table or foreign table " ) ;
break ;
case ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a table, composite type, or foreign table " ) ;
break ;
case ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a table, materialized view, index, or foreign table " ) ;
break ;
case ATT_VIEW :
msg = _ ( " \" %s \" is not a view " ) ;
break ;
case ATT_FOREIGN_TABLE :
msg = _ ( " \" %s \" is not a foreign table " ) ;
break ;
default :
/* shouldn't get here, add all necessary cases above */
msg = _ ( " \" %s \" is of the wrong type " ) ;
break ;
}
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( msg , RelationGetRelationName ( rel ) ) ) ) ;
}
/*
* ATSimpleRecursion
*
@ -6452,7 +6545,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
/* At top level, permission check was done in ATPrepCmd, else do it */
if ( recursing )
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( ( * cmd ) - > subtype , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
if ( rel - > rd_rel - > relispartition & & ! recursing )
ereport ( ERROR ,
@ -8186,7 +8279,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
/* At top level, permission check was done in ATPrepCmd, else do it */
if ( recursing )
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( AT_DropColumn , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* Initialize addrs on the first invocation */
Assert ( ! recursing | | addrs ! = NULL ) ;
@ -8670,7 +8763,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
/* At top level, permission check was done in ATPrepCmd, else do it */
if ( recursing )
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( AT_AddConstraint , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/*
* Call AddRelationNewConstraints to do the work , making sure it works on
@ -11286,7 +11379,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
/* At top level, permission check was done in ATPrepCmd, else do it */
if ( recursing )
ATSimplePermissions ( rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( AT_DropConstraint , rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
conrel = table_open ( ConstraintRelationId , RowExclusiveLock ) ;
@ -13205,8 +13298,9 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
default :
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " \" %s \" is not a table, view, sequence, or foreign table " ,
NameStr ( tuple_class - > relname ) ) ) ) ;
errmsg ( " cannot change owner of relation \" %s \" " ,
NameStr ( tuple_class - > relname ) ) ,
errdetail_relkind_not_supported ( tuple_class - > relkind ) ) ) ;
}
/*
@ -13621,8 +13715,9 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
default :
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " \" %s \" is not a table, view, materialized view, index, or TOAST table " ,
RelationGetRelationName ( rel ) ) ) ) ;
errmsg ( " cannot set options for relation \" %s \" " ,
RelationGetRelationName ( rel ) ) ,
errdetail_relkind_not_supported ( rel - > rd_rel - > relkind ) ) ) ;
break ;
}
@ -14176,7 +14271,7 @@ 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 ( parent_rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( AT_AddInherit , parent_rel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* Permanent rels cannot inherit from temporary ones */
if ( parent_rel - > rd_rel - > relpersistence = = RELPERSISTENCE_TEMP & &
@ -16505,17 +16600,27 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
* Don ' t allow ALTER TABLE . . SET SCHEMA on relations that can ' t be moved
* to a different schema , such as indexes and TOAST tables .
*/
if ( IsA ( stmt , AlterObjectSchemaStmt ) & &
relkind ! = RELKIND_RELATION & &
relkind ! = RELKIND_VIEW & &
relkind ! = RELKIND_MATVIEW & &
relkind ! = RELKIND_SEQUENCE & &
relkind ! = RELKIND_FOREIGN_TABLE & &
relkind ! = RELKIND_PARTITIONED_TABLE )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " \" %s \" is not a table, view, materialized view, sequence, or foreign table " ,
rv - > relname ) ) ) ;
if ( IsA ( stmt , AlterObjectSchemaStmt ) )
{
if ( relkind = = RELKIND_INDEX | | relkind = = RELKIND_PARTITIONED_INDEX )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " cannot change schema of index \" %s \" " ,
rv - > relname ) ,
errhint ( " Change the schema of the table instead. " ) ) ) ;
else if ( relkind = = RELKIND_COMPOSITE_TYPE )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " cannot change schema of composite type \" %s \" " ,
rv - > relname ) ,
errhint ( " Use ALTER TYPE instead. " ) ) ) ;
else if ( relkind = = RELKIND_TOASTVALUE )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " cannot change schema of TOAST table \" %s \" " ,
rv - > relname ) ,
errhint ( " Change the schema of the table instead. " ) ) ) ;
}
ReleaseSysCache ( tuple ) ;
}
@ -17077,7 +17182,7 @@ 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 ( attachrel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
ATSimplePermissions ( AT_AttachPartition , attachrel , ATT_TABLE | ATT_FOREIGN_TABLE ) ;
/* A partition can only have one parent */
if ( attachrel - > rd_rel - > relispartition )