@ -1259,7 +1259,8 @@ ExecuteTruncate(TruncateStmt *stmt)
else if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE )
ereport ( ERROR ,
( errcode ( ERRCODE_WRONG_OBJECT_TYPE ) ,
errmsg ( " must truncate child tables too " ) ) ) ;
errmsg ( " cannot truncate only a partitioned table " ) ,
errhint ( " Do not specify the ONLY keyword, or use truncate only on the partitions directly. " ) ) ) ;
}
/*
@ -5578,14 +5579,20 @@ static void
ATPrepDropNotNull ( Relation rel , bool recurse , bool recursing )
{
/*
* If the parent is a partitioned table , like check constraints , NOT NULL
* constraints must be dropped from child tables .
* If the parent is a partitioned table , like check constraints , we do
* not support removing the NOT NULL while partitions exist .
*/
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE & &
! recurse & & ! recursing )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " constraint must be dropped from child tables too " ) ) ) ;
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE )
{
PartitionDesc partdesc = RelationGetPartitionDesc ( rel ) ;
Assert ( partdesc ! = NULL ) ;
if ( partdesc - > nparts > 0 & & ! recurse & & ! recursing )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " cannot remove constraint from only the partitioned table when partitions exist " ) ,
errhint ( " Do not specify the ONLY keyword. " ) ) ) ;
}
}
static ObjectAddress
ATExecDropNotNull ( Relation rel , const char * colName , LOCKMODE lockmode )
@ -5746,13 +5753,19 @@ ATPrepSetNotNull(Relation rel, bool recurse, bool recursing)
{
/*
* If the parent is a partitioned table , like check constraints , NOT NULL
* constraints must be added to the child tables .
* constraints must be added to the child tables . Complain if requested
* otherwise and partitions exist .
*/
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE & &
! recurse & & ! recursing )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " constraint must be added to child tables too " ) ) ) ;
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE )
{
PartitionDesc partdesc = RelationGetPartitionDesc ( rel ) ;
if ( partdesc & & partdesc - > nparts > 0 & & ! recurse & & ! recursing )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " cannot add constraint to only the partitioned table when partitions exist " ) ,
errhint ( " Do not specify the ONLY keyword. " ) ) ) ;
}
}
static ObjectAddress
@ -6547,7 +6560,8 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE & & ! recurse )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " column must be dropped from child tables too " ) ) ) ;
errmsg ( " cannot drop column from only the partitioned table when partitions exist " ) ,
errhint ( " Do not specify the ONLY keyword. " ) ) ) ;
attr_rel = heap_open ( AttributeRelationId , RowExclusiveLock ) ;
foreach ( child , children )
@ -8561,16 +8575,6 @@ ATExecDropConstraint(Relation rel, const char *constrName,
}
}
/*
* In case of a partitioned table , the constraint must be dropped from the
* partitions too . There is no such thing as NO INHERIT constraints in
* case of partitioned tables .
*/
if ( ! recurse & & rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " constraint must be dropped from child tables too " ) ) ) ;
/*
* Propagate to children as appropriate . Unlike most other ALTER
* routines , we have to do this one level of recursion at a time ; we can ' t
@ -8581,6 +8585,18 @@ ATExecDropConstraint(Relation rel, const char *constrName,
else
children = NIL ;
/*
* For a partitioned table , if partitions exist and we are told not to
* recurse , it ' s a user error . It doesn ' t make sense to have a constraint
* be defined only on the parent , especially if it ' s a partitioned table .
*/
if ( rel - > rd_rel - > relkind = = RELKIND_PARTITIONED_TABLE & &
children ! = NIL & & ! recurse )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_TABLE_DEFINITION ) ,
errmsg ( " cannot remove constraint from only the partitioned table when partitions exist " ) ,
errhint ( " Do not specify the ONLY keyword. " ) ) ) ;
foreach ( child , children )
{
Oid childrelid = lfirst_oid ( child ) ;