@@ -350,16 +350,6 @@ 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-
363353static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
364354static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
365355static void truncate_check_activity(Relation rel);
@@ -370,8 +360,7 @@ static List *MergeAttributes(List *columns, const List *supers, char relpersiste
370360 List **supnotnulls);
371361static List *MergeCheckConstraint(List *constraints, const char *name, Node *expr);
372362static void MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const ColumnDef *newdef);
373- static ColumnDef *MergeInheritedAttribute(List *inh_columns, int exist_attno, const ColumnDef *newdef,
374- bool *have_deferred_conflicts);
363+ static ColumnDef *MergeInheritedAttribute(List *inh_columns, int exist_attno, const ColumnDef *newdef);
375364static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, bool ispartition);
376365static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
377366static void StoreCatalogInheritance(Oid relationId, List *supers,
@@ -631,6 +620,7 @@ static ObjectAddress ATExecSetCompression(Relation rel,
631620 const char *column, Node *newValue, LOCKMODE lockmode);
632621
633622static void index_copy_data(Relation rel, RelFileLocator newrlocator);
623+ static const char *storage_name(char c);
634624
635625static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
636626Oid oldRelOid, void *arg);
@@ -1373,7 +1363,9 @@ BuildDescForRelation(const List *columns)
13731363att->attidentity = entry->identity;
13741364att->attgenerated = entry->generated;
13751365att->attcompression = GetAttributeCompression(att->atttypid, entry->compression);
1376- if (entry->storage_name)
1366+ if (entry->storage)
1367+ att->attstorage = entry->storage;
1368+ else if (entry->storage_name)
13771369att->attstorage = GetAttributeStorage(att->atttypid, entry->storage_name);
13781370}
13791371
@@ -2396,6 +2388,28 @@ truncate_check_activity(Relation rel)
23962388CheckTableNotInUse(rel, "TRUNCATE");
23972389}
23982390
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+
23992413/*----------
24002414 * MergeAttributes
24012415 *Returns new schema given initial schema and superclasses.
@@ -2469,7 +2483,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
24692483List *inh_columns = NIL;
24702484List *constraints = NIL;
24712485List *nnconstraints = NIL;
2472- boolhave_deferred_conflicts = false;
2486+ boolhave_bogus_defaults = false;
24732487intchild_attno;
24742488static Node bogus_marker = {0}; /* marks conflicting defaults */
24752489List *saved_columns = NIL;
@@ -2706,10 +2720,11 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
27062720 */
27072721newdef = makeColumnDef(attributeName, attribute->atttypid,
27082722 attribute->atttypmod, attribute->attcollation);
2709- newdef->storage_name =GetAttributeStorageName( attribute->attstorage) ;
2723+ newdef->storage = attribute->attstorage;
27102724newdef->generated = attribute->attgenerated;
27112725if (CompressionMethodIsValid(attribute->attcompression))
2712- newdef->compression = GetCompressionMethodName(attribute->attcompression);
2726+ newdef->compression =
2727+ pstrdup(GetCompressionMethodName(attribute->attcompression));
27132728
27142729/*
27152730 * Regular inheritance children are independent enough not to
@@ -2729,8 +2744,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
27292744/*
27302745 * Yes, try to merge the two column definitions.
27312746 */
2732- mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef,
2733- &have_deferred_conflicts);
2747+ mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef);
27342748
27352749newattmap->attnums[parent_attno - 1] = exist_attno;
27362750
@@ -2853,7 +2867,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
28532867else if (!equal(def->cooked_default, this_default))
28542868{
28552869def->cooked_default = &bogus_marker;
2856- have_deferred_conflicts = true;
2870+ have_bogus_defaults = true;
28572871}
28582872}
28592873
@@ -3063,10 +3077,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
30633077}
30643078
30653079/*
3066- * If we found any conflicting parent default values or conflicting parent
3067- *properties, check to make sure they were overridden by the child.
3080+ * If we found any conflicting parent default values, check to make sure
3081+ * they were overridden by the child.
30683082 */
3069- if (have_deferred_conflicts )
3083+ if (have_bogus_defaults )
30703084{
30713085foreach(lc, columns)
30723086{
@@ -3087,20 +3101,6 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
30873101def->colname),
30883102 errhint("To resolve the conflict, specify a default explicitly.")));
30893103}
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,18 +3250,33 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
32503250inhdef->identity = newdef->identity;
32513251
32523252/*
3253- * Child storage specification, if any, overrides inherited storage
3254- * property.
3253+ * Copy storage parameter
32553254 */
3256- if (newdef->storage_name != NULL)
3257- inhdef->storage_name = newdef->storage_name;
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))));
32583265
32593266/*
3260- * Child compression specification, if any, overrides inherited
3261- * compression property.
3267+ * Copy compression parameter
32623268 */
3263- if (newdef ->compression! = NULL)
3269+ if (inhdef ->compression= = NULL)
32643270inhdef->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+ }
32653280
32663281/*
32673282 * Merge of not-null constraints = OR 'em together
@@ -3328,10 +3343,6 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
33283343 * 'exist_attno' is the number the existing matching attribute in inh_columns.
33293344 * 'newdef' is the new parent column/attribute definition to be merged.
33303345 *
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- *
33353346 * The matching ColumnDef in 'inh_columns' list is modified and returned.
33363347 *
33373348 * Notes:
@@ -3345,8 +3356,7 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
33453356static ColumnDef *
33463357MergeInheritedAttribute(List *inh_columns,
33473358int exist_attno,
3348- const ColumnDef *newdef,
3349- bool *have_deferred_conflicts)
3359+ const ColumnDef *newdef)
33503360{
33513361char *attributeName = newdef->colname;
33523362ColumnDef *prevdef;
@@ -3393,26 +3403,28 @@ MergeInheritedAttribute(List *inh_columns,
33933403/*
33943404 * Copy/check storage parameter
33953405 */
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- }
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))));
34043416
34053417/*
34063418 * Copy/check compression parameter
34073419 */
34083420if (prevdef->compression == NULL)
34093421prevdef->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- }
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)));
34163428
34173429/*
34183430 * Check for GENERATED conflicts