@@ -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,
626636 Oid oldRelOid, void *arg);
@@ -1363,9 +1373,7 @@ BuildDescForRelation(const List *columns)
13631373 att->attidentity = entry->identity;
13641374 att->attgenerated = entry->generated;
13651375 att->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)
13691377 att->attstorage = GetAttributeStorage(att->atttypid, entry->storage_name);
13701378 }
13711379
@@ -2388,28 +2396,6 @@ truncate_check_activity(Relation rel)
23882396 CheckTableNotInUse(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,
24832469 List *inh_columns = NIL;
24842470 List *constraints = NIL;
24852471 List *nnconstraints = NIL;
2486- bool have_bogus_defaults = false;
2472+ bool have_deferred_conflicts = false;
24872473 int child_attno;
24882474 static Node bogus_marker = {0}; /* marks conflicting defaults */
24892475 List *saved_columns = NIL;
@@ -2720,11 +2706,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
27202706 */
27212707 newdef = makeColumnDef(attributeName, attribute->atttypid,
27222708 attribute->atttypmod, attribute->attcollation);
2723- newdef->storage = attribute->attstorage;
2709+ newdef->storage_name = GetAttributeStorageName( attribute->attstorage) ;
27242710 newdef->generated = attribute->attgenerated;
27252711 if (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
27492735 newattmap->attnums[parent_attno - 1] = exist_attno;
27502736
@@ -2867,7 +2853,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
28672853 else if (!equal(def->cooked_default, this_default))
28682854 {
28692855 def->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 {
30853071 foreach(lc, columns)
30863072 {
@@ -3101,6 +3087,20 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
31013087 def->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
32503250 inhdef->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)
32703264 inhdef->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,
33583347 int exist_attno,
3359- const ColumnDef *newdef)
3348+ const ColumnDef *newdef,
3349+ bool *have_deferred_conflicts)
33603350{
33613351 char *attributeName = newdef->colname;
33623352 ColumnDef *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 */
34203408 if (prevdef->compression == NULL)
34213409 prevdef->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 compression method 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
0 commit comments