@@ -350,6 +350,16 @@ typedef struct ForeignTruncateInfo
350350#define child_dependency_type(child_is_partition)\
351351((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
352352
353+ /*
354+ * Bogus property string to track conflict in inherited properties of a column.
355+ * It is currently used for storage and compression specifications, but may be
356+ * used for other string specifications in future. It can be any string which
357+ * does not look like a valid compression or storage method. It is meant to be
358+ * used by MergeAttributes() and its minions. It is not expected to be stored
359+ * on disk.
360+ */
361+ static const char *conflicting_column_property = "*** conflicting column property ***";
362+
353363static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
354364static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
355365static void truncate_check_activity(Relation rel);
@@ -360,7 +370,8 @@ static List *MergeAttributes(List *columns, const List *supers, char relpersiste
360370 List **supnotnulls);
361371static List *MergeCheckConstraint(List *constraints, const char *name, Node *expr);
362372static void MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const ColumnDef *newdef);
363- static ColumnDef *MergeInheritedAttribute(List *inh_columns, int exist_attno, const ColumnDef *newdef);
373+ static ColumnDef *MergeInheritedAttribute(List *inh_columns, int exist_attno, const ColumnDef *newdef,
374+ bool *have_deferred_conflicts);
364375static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, bool ispartition);
365376static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
366377static void StoreCatalogInheritance(Oid relationId, List *supers,
@@ -620,7 +631,6 @@ static ObjectAddress ATExecSetCompression(Relation rel,
620631 const char *column, Node *newValue, LOCKMODE lockmode);
621632
622633static void index_copy_data(Relation rel, RelFileLocator newrlocator);
623- static const char *storage_name(char c);
624634
625635static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
626636Oid oldRelOid, void *arg);
@@ -1363,9 +1373,7 @@ BuildDescForRelation(const List *columns)
13631373att->attidentity = entry->identity;
13641374att->attgenerated = entry->generated;
13651375att->attcompression = GetAttributeCompression(att->atttypid, entry->compression);
1366- if (entry->storage)
1367- att->attstorage = entry->storage;
1368- else if (entry->storage_name)
1376+ if (entry->storage_name)
13691377att->attstorage = GetAttributeStorage(att->atttypid, entry->storage_name);
13701378}
13711379
@@ -2388,28 +2396,6 @@ truncate_check_activity(Relation rel)
23882396CheckTableNotInUse(rel, "TRUNCATE");
23892397}
23902398
2391- /*
2392- * storage_name
2393- * returns the name corresponding to a typstorage/attstorage enum value
2394- */
2395- static const char *
2396- storage_name(char c)
2397- {
2398- switch (c)
2399- {
2400- case TYPSTORAGE_PLAIN:
2401- return "PLAIN";
2402- case TYPSTORAGE_EXTERNAL:
2403- return "EXTERNAL";
2404- case TYPSTORAGE_EXTENDED:
2405- return "EXTENDED";
2406- case TYPSTORAGE_MAIN:
2407- return "MAIN";
2408- default:
2409- return "???";
2410- }
2411- }
2412-
24132399/*----------
24142400 * MergeAttributes
24152401 *Returns new schema given initial schema and superclasses.
@@ -2483,7 +2469,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
24832469List *inh_columns = NIL;
24842470List *constraints = NIL;
24852471List *nnconstraints = NIL;
2486- boolhave_bogus_defaults = false;
2472+ boolhave_deferred_conflicts = false;
24872473intchild_attno;
24882474static Node bogus_marker = {0}; /* marks conflicting defaults */
24892475List *saved_columns = NIL;
@@ -2720,11 +2706,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
27202706 */
27212707newdef = makeColumnDef(attributeName, attribute->atttypid,
27222708 attribute->atttypmod, attribute->attcollation);
2723- newdef->storage = attribute->attstorage;
2709+ newdef->storage_name =GetAttributeStorageName( attribute->attstorage) ;
27242710newdef->generated = attribute->attgenerated;
27252711if (CompressionMethodIsValid(attribute->attcompression))
2726- newdef->compression =
2727- pstrdup(GetCompressionMethodName(attribute->attcompression));
2712+ newdef->compression = GetCompressionMethodName(attribute->attcompression);
27282713
27292714/*
27302715 * Regular inheritance children are independent enough not to
@@ -2744,7 +2729,8 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
27442729/*
27452730 * Yes, try to merge the two column definitions.
27462731 */
2747- mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef);
2732+ mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef,
2733+ &have_deferred_conflicts);
27482734
27492735newattmap->attnums[parent_attno - 1] = exist_attno;
27502736
@@ -2867,7 +2853,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
28672853else if (!equal(def->cooked_default, this_default))
28682854{
28692855def->cooked_default = &bogus_marker;
2870- have_bogus_defaults = true;
2856+ have_deferred_conflicts = true;
28712857}
28722858}
28732859
@@ -3077,10 +3063,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
30773063}
30783064
30793065/*
3080- * If we found any conflicting parent default values, check to make sure
3081- * they were overridden by the child.
3066+ * If we found any conflicting parent default values or conflicting parent
3067+ *properties, check to make sure they were overridden by the child.
30823068 */
3083- if (have_bogus_defaults )
3069+ if (have_deferred_conflicts )
30843070{
30853071foreach(lc, columns)
30863072{
@@ -3101,6 +3087,20 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
31013087def->colname),
31023088 errhint("To resolve the conflict, specify a default explicitly.")));
31033089}
3090+
3091+ if (def->compression == conflicting_column_property)
3092+ ereport(ERROR,
3093+ (errcode(ERRCODE_DATATYPE_MISMATCH),
3094+ errmsg("column \"%s\" inherits conflicting compression methods",
3095+ def->colname),
3096+ errhint("To resolve the conflict, specify a compression method explicitly.")));
3097+
3098+ if (def->storage_name == conflicting_column_property)
3099+ ereport(ERROR,
3100+ (errcode(ERRCODE_DATATYPE_MISMATCH),
3101+ errmsg("column \"%s\" inherits conflicting storage methods",
3102+ def->colname),
3103+ errhint("To resolve the conflict, specify a storage method explicitly.")));
31043104}
31053105}
31063106
@@ -3250,33 +3250,18 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
32503250inhdef->identity = newdef->identity;
32513251
32523252/*
3253- * Copy storage parameter
3253+ * Child storage specification, if any, overrides inherited storage
3254+ * property.
32543255 */
3255- if (inhdef->storage == 0)
3256- inhdef->storage = newdef->storage;
3257- else if (newdef->storage != 0 && inhdef->storage != newdef->storage)
3258- ereport(ERROR,
3259- (errcode(ERRCODE_DATATYPE_MISMATCH),
3260- errmsg("column \"%s\" has a storage parameter conflict",
3261- attributeName),
3262- errdetail("%s versus %s",
3263- storage_name(inhdef->storage),
3264- storage_name(newdef->storage))));
3256+ if (newdef->storage_name != NULL)
3257+ inhdef->storage_name = newdef->storage_name;
32653258
32663259/*
3267- * Copy compression parameter
3260+ * Child compression specification, if any, overrides inherited
3261+ * compression property.
32683262 */
3269- if (inhdef ->compression= = NULL)
3263+ if (newdef ->compression! = NULL)
32703264inhdef->compression = newdef->compression;
3271- else if (newdef->compression != NULL)
3272- {
3273- if (strcmp(inhdef->compression, newdef->compression) != 0)
3274- ereport(ERROR,
3275- (errcode(ERRCODE_DATATYPE_MISMATCH),
3276- errmsg("column \"%s\" has a compression method conflict",
3277- attributeName),
3278- errdetail("%s versus %s", inhdef->compression, newdef->compression)));
3279- }
32803265
32813266/*
32823267 * Merge of not-null constraints = OR 'em together
@@ -3343,6 +3328,10 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
33433328 * 'exist_attno' is the number the existing matching attribute in inh_columns.
33443329 * 'newdef' is the new parent column/attribute definition to be merged.
33453330 *
3331+ * Output arguments:
3332+ * 'have_deferred_conflicts' is set to true if there is a conflict in inherited
3333+ * compression properties; remains unchanged otherwise.
3334+ *
33463335 * The matching ColumnDef in 'inh_columns' list is modified and returned.
33473336 *
33483337 * Notes:
@@ -3356,7 +3345,8 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
33563345static ColumnDef *
33573346MergeInheritedAttribute(List *inh_columns,
33583347int exist_attno,
3359- const ColumnDef *newdef)
3348+ const ColumnDef *newdef,
3349+ bool *have_deferred_conflicts)
33603350{
33613351char *attributeName = newdef->colname;
33623352ColumnDef *prevdef;
@@ -3403,28 +3393,26 @@ MergeInheritedAttribute(List *inh_columns,
34033393/*
34043394 * Copy/check storage parameter
34053395 */
3406- if (prevdef->storage == 0)
3407- prevdef->storage = newdef->storage;
3408- else if (prevdef->storage != newdef->storage)
3409- ereport(ERROR,
3410- (errcode(ERRCODE_DATATYPE_MISMATCH),
3411- errmsg("inherited column \"%s\" has a storage parameter conflict",
3412- attributeName),
3413- errdetail("%s versus %s",
3414- storage_name(prevdef->storage),
3415- storage_name(newdef->storage))));
3396+ if (prevdef->storage_name == NULL)
3397+ prevdef->storage_name = newdef->storage_name;
3398+ else if (newdef->storage_name != NULL &&
3399+ strcmp(prevdef->storage_name, newdef->storage_name) != 0)
3400+ {
3401+ prevdef->storage_name = conflicting_column_property;
3402+ *have_deferred_conflicts = true;
3403+ }
34163404
34173405/*
34183406 * Copy/check compression parameter
34193407 */
34203408if (prevdef->compression == NULL)
34213409prevdef->compression = newdef->compression;
3422- else if (strcmp(prevdef->compression, newdef->compression) !=0)
3423- ereport(ERROR,
3424- (errcode(ERRCODE_DATATYPE_MISMATCH),
3425- errmsg("column \"%s\" has a compressionmethod conflict",
3426- attributeName),
3427- errdetail("%s versus %s", prevdef->compression, newdef->compression)));
3410+ else if (newdef->compression !=NULL &&
3411+ strcmp(prevdef->compression, newdef->compression) != 0)
3412+ {
3413+ prevdef-> compression= conflicting_column_property;
3414+ *have_deferred_conflicts = true;
3415+ }
34283416
34293417/*
34303418 * Check for GENERATED conflicts