@@ -350,6 +350,16 @@ typedef struct ForeignTruncateInfo
350
350
#define child_dependency_type(child_is_partition) \
351
351
((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
352
352
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
+
353
363
static void truncate_check_rel(Oid relid, Form_pg_class reltuple);
354
364
static void truncate_check_perms(Oid relid, Form_pg_class reltuple);
355
365
static void truncate_check_activity(Relation rel);
@@ -360,7 +370,8 @@ static List *MergeAttributes(List *columns, const List *supers, char relpersiste
360
370
List **supnotnulls);
361
371
static List *MergeCheckConstraint(List *constraints, const char *name, Node *expr);
362
372
static 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);
364
375
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, bool ispartition);
365
376
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
366
377
static void StoreCatalogInheritance(Oid relationId, List *supers,
@@ -620,7 +631,6 @@ static ObjectAddress ATExecSetCompression(Relation rel,
620
631
const char *column, Node *newValue, LOCKMODE lockmode);
621
632
622
633
static void index_copy_data(Relation rel, RelFileLocator newrlocator);
623
- static const char *storage_name(char c);
624
634
625
635
static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
626
636
Oid oldRelOid, void *arg);
@@ -1363,9 +1373,7 @@ BuildDescForRelation(const List *columns)
1363
1373
att->attidentity = entry->identity;
1364
1374
att->attgenerated = entry->generated;
1365
1375
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)
1369
1377
att->attstorage = GetAttributeStorage(att->atttypid, entry->storage_name);
1370
1378
}
1371
1379
@@ -2388,28 +2396,6 @@ truncate_check_activity(Relation rel)
2388
2396
CheckTableNotInUse(rel, "TRUNCATE");
2389
2397
}
2390
2398
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
-
2413
2399
/*----------
2414
2400
* MergeAttributes
2415
2401
* Returns new schema given initial schema and superclasses.
@@ -2483,7 +2469,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
2483
2469
List *inh_columns = NIL;
2484
2470
List *constraints = NIL;
2485
2471
List *nnconstraints = NIL;
2486
- bool have_bogus_defaults = false;
2472
+ bool have_deferred_conflicts = false;
2487
2473
int child_attno;
2488
2474
static Node bogus_marker = {0}; /* marks conflicting defaults */
2489
2475
List *saved_columns = NIL;
@@ -2720,11 +2706,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
2720
2706
*/
2721
2707
newdef = makeColumnDef(attributeName, attribute->atttypid,
2722
2708
attribute->atttypmod, attribute->attcollation);
2723
- newdef->storage = attribute->attstorage;
2709
+ newdef->storage_name = GetAttributeStorageName( attribute->attstorage) ;
2724
2710
newdef->generated = attribute->attgenerated;
2725
2711
if (CompressionMethodIsValid(attribute->attcompression))
2726
- newdef->compression =
2727
- pstrdup(GetCompressionMethodName(attribute->attcompression));
2712
+ newdef->compression = GetCompressionMethodName(attribute->attcompression);
2728
2713
2729
2714
/*
2730
2715
* Regular inheritance children are independent enough not to
@@ -2744,7 +2729,8 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
2744
2729
/*
2745
2730
* Yes, try to merge the two column definitions.
2746
2731
*/
2747
- mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef);
2732
+ mergeddef = MergeInheritedAttribute(inh_columns, exist_attno, newdef,
2733
+ &have_deferred_conflicts);
2748
2734
2749
2735
newattmap->attnums[parent_attno - 1] = exist_attno;
2750
2736
@@ -2867,7 +2853,7 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
2867
2853
else if (!equal(def->cooked_default, this_default))
2868
2854
{
2869
2855
def->cooked_default = &bogus_marker;
2870
- have_bogus_defaults = true;
2856
+ have_deferred_conflicts = true;
2871
2857
}
2872
2858
}
2873
2859
@@ -3077,10 +3063,10 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
3077
3063
}
3078
3064
3079
3065
/*
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.
3082
3068
*/
3083
- if (have_bogus_defaults )
3069
+ if (have_deferred_conflicts )
3084
3070
{
3085
3071
foreach(lc, columns)
3086
3072
{
@@ -3101,6 +3087,20 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
3101
3087
def->colname),
3102
3088
errhint("To resolve the conflict, specify a default explicitly.")));
3103
3089
}
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.")));
3104
3104
}
3105
3105
}
3106
3106
@@ -3250,33 +3250,18 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
3250
3250
inhdef->identity = newdef->identity;
3251
3251
3252
3252
/*
3253
- * Copy storage parameter
3253
+ * Child storage specification, if any, overrides inherited storage
3254
+ * property.
3254
3255
*/
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;
3265
3258
3266
3259
/*
3267
- * Copy compression parameter
3260
+ * Child compression specification, if any, overrides inherited
3261
+ * compression property.
3268
3262
*/
3269
- if (inhdef ->compression = = NULL)
3263
+ if (newdef ->compression ! = NULL)
3270
3264
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
- }
3280
3265
3281
3266
/*
3282
3267
* Merge of not-null constraints = OR 'em together
@@ -3343,6 +3328,10 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
3343
3328
* 'exist_attno' is the number the existing matching attribute in inh_columns.
3344
3329
* 'newdef' is the new parent column/attribute definition to be merged.
3345
3330
*
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
+ *
3346
3335
* The matching ColumnDef in 'inh_columns' list is modified and returned.
3347
3336
*
3348
3337
* Notes:
@@ -3356,7 +3345,8 @@ MergeChildAttribute(List *inh_columns, int exist_attno, int newcol_attno, const
3356
3345
static ColumnDef *
3357
3346
MergeInheritedAttribute(List *inh_columns,
3358
3347
int exist_attno,
3359
- const ColumnDef *newdef)
3348
+ const ColumnDef *newdef,
3349
+ bool *have_deferred_conflicts)
3360
3350
{
3361
3351
char *attributeName = newdef->colname;
3362
3352
ColumnDef *prevdef;
@@ -3403,28 +3393,26 @@ MergeInheritedAttribute(List *inh_columns,
3403
3393
/*
3404
3394
* Copy/check storage parameter
3405
3395
*/
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
+ }
3416
3404
3417
3405
/*
3418
3406
* Copy/check compression parameter
3419
3407
*/
3420
3408
if (prevdef->compression == NULL)
3421
3409
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
+ }
3428
3416
3429
3417
/*
3430
3418
* Check for GENERATED conflicts
0 commit comments