@ -350,6 +350,16 @@ typedef struct ForeignTruncateInfo
# define child_dependency_type(child_is_partition) \
( ( child_is_partition ) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL )
/*
* Bogus property string to track conflict in inherited properties of a column .
* It is currently used for storage and compression specifications , but may be
* used for other string specifications in future . It can be any string which
* does not look like a valid compression or storage method . It is meant to be
* used by MergeAttributes ( ) and its minions . It is not expected to be stored
* on disk .
*/
static const char * conflicting_column_property = " *** conflicting column property *** " ;
static void truncate_check_rel ( Oid relid , Form_pg_class reltuple ) ;
static void truncate_check_perms ( Oid relid , Form_pg_class reltuple ) ;
static void truncate_check_activity ( Relation rel ) ;
@ -360,7 +370,8 @@ static List *MergeAttributes(List *columns, const List *supers, char relpersiste
List * * supnotnulls ) ;
static List * MergeCheckConstraint ( List * constraints , const char * name , Node * expr ) ;
static void MergeChildAttribute ( List * inh_columns , int exist_attno , int newcol_attno , const ColumnDef * newdef ) ;
static ColumnDef * MergeInheritedAttribute ( List * inh_columns , int exist_attno , const ColumnDef * newdef ) ;
static ColumnDef * MergeInheritedAttribute ( List * inh_columns , int exist_attno , const ColumnDef * newdef ,
bool * have_deferred_conflicts ) ;
static void MergeAttributesIntoExisting ( Relation child_rel , Relation parent_rel , bool ispartition ) ;
static void MergeConstraintsIntoExisting ( Relation child_rel , Relation parent_rel ) ;
static void StoreCatalogInheritance ( Oid relationId , List * supers ,
@ -620,7 +631,6 @@ static ObjectAddress ATExecSetCompression(Relation rel,
const char * column , Node * newValue , LOCKMODE lockmode ) ;
static void index_copy_data ( Relation rel , RelFileLocator newrlocator ) ;
static const char * storage_name ( char c ) ;
static void RangeVarCallbackForDropRelation ( const RangeVar * rel , Oid relOid ,
Oid oldRelOid , void * arg ) ;
@ -1363,9 +1373,7 @@ BuildDescForRelation(const List *columns)
att - > attidentity = entry - > identity ;
att - > attgenerated = entry - > generated ;
att - > attcompression = GetAttributeCompression ( att - > atttypid , entry - > compression ) ;
if ( entry - > storage )
att - > attstorage = entry - > storage ;
else if ( entry - > storage_name )
if ( entry - > storage_name )
att - > attstorage = GetAttributeStorage ( att - > atttypid , entry - > storage_name ) ;
}
@ -2388,28 +2396,6 @@ truncate_check_activity(Relation rel)
CheckTableNotInUse ( rel , " TRUNCATE " ) ;
}
/*
* storage_name
* returns the name corresponding to a typstorage / attstorage enum value
*/
static const char *
storage_name ( char c )
{
switch ( c )
{
case TYPSTORAGE_PLAIN :
return " PLAIN " ;
case TYPSTORAGE_EXTERNAL :
return " EXTERNAL " ;
case TYPSTORAGE_EXTENDED :
return " EXTENDED " ;
case TYPSTORAGE_MAIN :
return " MAIN " ;
default :
return " ??? " ;
}
}
/*----------
* MergeAttributes
* Returns new schema given initial schema and superclasses .
@ -2483,7 +2469,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
List * inh_columns = NIL ;
List * constraints = NIL ;
List * nnconstraints = NIL ;
bool have_bogus_defaul ts = false ;
bool have_deferred_conflic ts = false ;
int child_attno ;
static Node bogus_marker = { 0 } ; /* marks conflicting defaults */
List * saved_columns = NIL ;
@ -2720,11 +2706,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
*/
newdef = makeColumnDef ( attributeName , attribute - > atttypid ,
attribute - > atttypmod , attribute - > attcollation ) ;
newdef - > storage = attribute - > attstorage ;
newdef - > storage_name = GetAttributeStorageName ( attribute - > attstorage ) ;
newdef - > generated = attribute - > attgenerated ;
if ( CompressionMethodIsValid ( attribute - > attcompression ) )
newdef - > compression =
pstrdup ( GetCompressionMethodName ( attribute - > attcompression ) ) ;
newdef - > compression = GetCompressionMethodName ( attribute - > attcompression ) ;
/*
* Regular inheritance children are independent enough not to
@ -2744,7 +2729,8 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
/*
* Yes , try to merge the two column definitions .
*/
mergeddef = MergeInheritedAttribute ( inh_columns , exist_attno , newdef ) ;
mergeddef = MergeInheritedAttribute ( inh_columns , exist_attno , newdef ,
& have_deferred_conflicts ) ;
newattmap - > attnums [ parent_attno - 1 ] = exist_attno ;
@ -2867,7 +2853,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
else if ( ! equal ( def - > cooked_default , this_default ) )
{
def - > cooked_default = & bogus_marker ;
have_bogus_defaul ts = true ;
have_deferred_conflic ts = true ;
}
}
@ -3077,10 +3063,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
}
/*
* If we found any conflicting parent default values , check to make sure
* they were overridden by the child .
* If we found any conflicting parent default values or conflicting parent
* properties , check to make sure they were overridden by the child .
*/
if ( have_bogus_defaul ts )
if ( have_deferred_conflic ts )
{
foreach ( lc , columns )
{
@ -3101,6 +3087,20 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
def - > colname ) ,
errhint ( " To resolve the conflict, specify a default explicitly. " ) ) ) ;
}
if ( def - > compression = = conflicting_column_property )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " column \" %s \" inherits conflicting compression methods " ,
def - > colname ) ,
errhint ( " To resolve the conflict, specify a compression method explicitly. " ) ) ) ;
if ( def - > storage_name = = conflicting_column_property )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " column \" %s \" inherits conflicting storage methods " ,
def - > colname ) ,
errhint ( " To resolve the conflict, specify a storage method explicitly. " ) ) ) ;
}
}
@ -3250,33 +3250,18 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
inhdef - > identity = newdef - > identity ;
/*
* Copy storage parameter
* Child storage specification , if any , overrides inherited storage
* property .
*/
if ( inhdef - > storage = = 0 )
inhdef - > storage = newdef - > storage ;
else if ( newdef - > storage ! = 0 & & inhdef - > storage ! = newdef - > storage )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " column \" %s \" has a storage parameter conflict " ,
attributeName ) ,
errdetail ( " %s versus %s " ,
storage_name ( inhdef - > storage ) ,
storage_name ( newdef - > storage ) ) ) ) ;
if ( newdef - > storage_name ! = NULL )
inhdef - > storage_name = newdef - > storage_name ;
/*
* Copy compression parameter
* Child compression specification , if any , overrides inherited
* compression property .
*/
if ( inh def- > compression = = NULL )
if ( newdef - > compression ! = NULL )
inhdef - > compression = newdef - > compression ;
else if ( newdef - > compression ! = NULL )
{
if ( strcmp ( inhdef - > compression , newdef - > compression ) ! = 0 )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " column \" %s \" has a compression method conflict " ,
attributeName ) ,
errdetail ( " %s versus %s " , inhdef - > compression , newdef - > compression ) ) ) ;
}
/*
* Merge of not - null constraints = OR ' em together
@ -3343,6 +3328,10 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
* ' exist_attno ' is the number the existing matching attribute in inh_columns .
* ' newdef ' is the new parent column / attribute definition to be merged .
*
* Output arguments :
* ' have_deferred_conflicts ' is set to true if there is a conflict in inherited
* compression properties ; remains unchanged otherwise .
*
* The matching ColumnDef in ' inh_columns ' list is modified and returned .
*
* Notes :
@ -3356,7 +3345,8 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
static ColumnDef *
MergeInheritedAttribute ( List * inh_columns ,
int exist_attno ,
const ColumnDef * newdef )
const ColumnDef * newdef ,
bool * have_deferred_conflicts )
{
char * attributeName = newdef - > colname ;
ColumnDef * prevdef ;
@ -3403,28 +3393,26 @@ MergeInheritedAttribute(List *inh_columns,
/*
* Copy / check storage parameter
*/
if ( prevdef - > storage = = 0 )
prevdef - > storage = newdef - > storage ;
else if ( prevdef - > storage ! = newdef - > storage )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " inherited column \" %s \" has a storage parameter conflict " ,
attributeName ) ,
errdetail ( " %s versus %s " ,
storage_name ( prevdef - > storage ) ,
storage_name ( newdef - > storage ) ) ) ) ;
if ( prevdef - > storage_name = = NULL )
prevdef - > storage_name = newdef - > storage_name ;
else if ( newdef - > storage_name ! = NULL & &
strcmp ( prevdef - > storage_name , newdef - > storage_name ) ! = 0 )
{
prevdef - > storage_name = conflicting_column_property ;
* have_deferred_conflicts = true ;
}
/*
* Copy / check compression parameter
*/
if ( prevdef - > compression = = NULL )
prevdef - > compression = newdef - > compression ;
else if ( strcmp ( prevdef - > compression , newdef - > compression ) ! = 0 )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " column \" %s \" has a compression method conflict " ,
attributeName ) ,
errdetail ( " %s versus %s " , prevdef - > compression , newdef - > compression ) ) ) ;
else if ( newdef - > compression ! = NULL & &
strcmp ( prevdef - > compression , newdef - > compression ) ! = 0 )
{
prevdef - > compression = conflicting_column_property ;
* have_deferred_conflicts = true ;
}
/*
* Check for GENERATED conflicts