@@ -593,7 +593,7 @@ static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKM
593
593
static void ATExecGenericOptions(Relation rel, List *options);
594
594
static void ATExecSetRowSecurity(Relation rel, bool rls);
595
595
static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls);
596
- static ObjectAddress ATExecSetCompression(AlteredTableInfo *tab, Relation rel,
596
+ static ObjectAddress ATExecSetCompression(Relation rel,
597
597
const char *column, Node *newValue, LOCKMODE lockmode);
598
598
599
599
static void index_copy_data(Relation rel, RelFileLocator newrlocator);
@@ -633,6 +633,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
633
633
static List *GetParentedForeignKeyRefs(Relation partition);
634
634
static void ATDetachCheckNoForeignKeyRefs(Relation partition);
635
635
static char GetAttributeCompression(Oid atttypid, char *compression);
636
+ static char GetAttributeStorage(Oid atttypid, const char *storagemode);
636
637
637
638
638
639
/* ----------------------------------------------------------------
@@ -931,6 +932,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
931
932
if (colDef->compression)
932
933
attr->attcompression = GetAttributeCompression(attr->atttypid,
933
934
colDef->compression);
935
+
936
+ if (colDef->storage_name)
937
+ attr->attstorage = GetAttributeStorage(attr->atttypid, colDef->storage_name);
934
938
}
935
939
936
940
/*
@@ -4963,8 +4967,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
4963
4967
case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
4964
4968
address = ATExecSetStorage(rel, cmd->name, cmd->def, lockmode);
4965
4969
break;
4966
- case AT_SetCompression:
4967
- address = ATExecSetCompression(tab, rel, cmd->name, cmd->def,
4970
+ case AT_SetCompression: /* ALTER COLUMN SET COMPRESSION */
4971
+ address = ATExecSetCompression(rel, cmd->name, cmd->def,
4968
4972
lockmode);
4969
4973
break;
4970
4974
case AT_DropColumn: /* DROP COLUMN */
@@ -6820,7 +6824,10 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
6820
6824
attribute.atttypmod = typmod;
6821
6825
attribute.attbyval = tform->typbyval;
6822
6826
attribute.attalign = tform->typalign;
6823
- attribute.attstorage = tform->typstorage;
6827
+ if (colDef->storage_name)
6828
+ attribute.attstorage = GetAttributeStorage(typeOid, colDef->storage_name);
6829
+ else
6830
+ attribute.attstorage = tform->typstorage;
6824
6831
attribute.attcompression = GetAttributeCompression(typeOid,
6825
6832
colDef->compression);
6826
6833
attribute.attnotnull = colDef->is_not_null;
@@ -8263,33 +8270,12 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
8263
8270
static ObjectAddress
8264
8271
ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
8265
8272
{
8266
- char *storagemode;
8267
- char newstorage;
8268
8273
Relation attrelation;
8269
8274
HeapTuple tuple;
8270
8275
Form_pg_attribute attrtuple;
8271
8276
AttrNumber attnum;
8272
8277
ObjectAddress address;
8273
8278
8274
- storagemode = strVal(newValue);
8275
-
8276
- if (pg_strcasecmp(storagemode, "plain") == 0)
8277
- newstorage = TYPSTORAGE_PLAIN;
8278
- else if (pg_strcasecmp(storagemode, "external") == 0)
8279
- newstorage = TYPSTORAGE_EXTERNAL;
8280
- else if (pg_strcasecmp(storagemode, "extended") == 0)
8281
- newstorage = TYPSTORAGE_EXTENDED;
8282
- else if (pg_strcasecmp(storagemode, "main") == 0)
8283
- newstorage = TYPSTORAGE_MAIN;
8284
- else
8285
- {
8286
- ereport(ERROR,
8287
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8288
- errmsg("invalid storage type \"%s\"",
8289
- storagemode)));
8290
- newstorage = 0; /* keep compiler quiet */
8291
- }
8292
-
8293
8279
attrelation = table_open(AttributeRelationId, RowExclusiveLock);
8294
8280
8295
8281
tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
@@ -8308,35 +8294,25 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
8308
8294
errmsg("cannot alter system column \"%s\"",
8309
8295
colName)));
8310
8296
8311
- /*
8312
- * safety check: do not allow toasted storage modes unless column datatype
8313
- * is TOAST-aware.
8314
- */
8315
- if (newstorage == TYPSTORAGE_PLAIN || TypeIsToastable(attrtuple->atttypid))
8316
- attrtuple->attstorage = newstorage;
8317
- else
8318
- ereport(ERROR,
8319
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8320
- errmsg("column data type %s can only have storage PLAIN",
8321
- format_type_be(attrtuple->atttypid))));
8297
+ attrtuple->attstorage = GetAttributeStorage(attrtuple->atttypid, strVal(newValue));
8322
8298
8323
8299
CatalogTupleUpdate(attrelation, &tuple->t_self, tuple);
8324
8300
8325
8301
InvokeObjectPostAlterHook(RelationRelationId,
8326
8302
RelationGetRelid(rel),
8327
8303
attrtuple->attnum);
8328
8304
8329
- heap_freetuple(tuple);
8330
-
8331
8305
/*
8332
8306
* Apply the change to indexes as well (only for simple index columns,
8333
8307
* matching behavior of index.c ConstructTupleDescriptor()).
8334
8308
*/
8335
8309
SetIndexStorageProperties(rel, attrelation, attnum,
8336
- true, newstorage ,
8310
+ true, attrtuple->attstorage ,
8337
8311
false, 0,
8338
8312
lockmode);
8339
8313
8314
+ heap_freetuple(tuple);
8315
+
8340
8316
table_close(attrelation, RowExclusiveLock);
8341
8317
8342
8318
ObjectAddressSubSet(address, RelationRelationId,
@@ -16156,8 +16132,7 @@ ATExecGenericOptions(Relation rel, List *options)
16156
16132
* Return value is the address of the modified column
16157
16133
*/
16158
16134
static ObjectAddress
16159
- ATExecSetCompression(AlteredTableInfo *tab,
16160
- Relation rel,
16135
+ ATExecSetCompression(Relation rel,
16161
16136
const char *column,
16162
16137
Node *newValue,
16163
16138
LOCKMODE lockmode)
@@ -19287,3 +19262,38 @@ GetAttributeCompression(Oid atttypid, char *compression)
19287
19262
19288
19263
return cmethod;
19289
19264
}
19265
+
19266
+ /*
19267
+ * resolve column storage specification
19268
+ */
19269
+ static char
19270
+ GetAttributeStorage(Oid atttypid, const char *storagemode)
19271
+ {
19272
+ char cstorage = 0;
19273
+
19274
+ if (pg_strcasecmp(storagemode, "plain") == 0)
19275
+ cstorage = TYPSTORAGE_PLAIN;
19276
+ else if (pg_strcasecmp(storagemode, "external") == 0)
19277
+ cstorage = TYPSTORAGE_EXTERNAL;
19278
+ else if (pg_strcasecmp(storagemode, "extended") == 0)
19279
+ cstorage = TYPSTORAGE_EXTENDED;
19280
+ else if (pg_strcasecmp(storagemode, "main") == 0)
19281
+ cstorage = TYPSTORAGE_MAIN;
19282
+ else
19283
+ ereport(ERROR,
19284
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
19285
+ errmsg("invalid storage type \"%s\"",
19286
+ storagemode)));
19287
+
19288
+ /*
19289
+ * safety check: do not allow toasted storage modes unless column datatype
19290
+ * is TOAST-aware.
19291
+ */
19292
+ if (!(cstorage == TYPSTORAGE_PLAIN || TypeIsToastable(atttypid)))
19293
+ ereport(ERROR,
19294
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
19295
+ errmsg("column data type %s can only have storage PLAIN",
19296
+ format_type_be(atttypid))));
19297
+
19298
+ return cstorage;
19299
+ }
0 commit comments