@@ -607,6 +607,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
607
607
static List *GetParentedForeignKeyRefs(Relation partition);
608
608
static void ATDetachCheckNoForeignKeyRefs(Relation partition);
609
609
static char GetAttributeCompression(Oid atttypid, char *compression);
610
+ static char GetAttributeStorage(const char *storagemode);
610
611
611
612
612
613
/* ----------------------------------------------------------------
@@ -905,6 +906,22 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
905
906
if (colDef->compression)
906
907
attr->attcompression = GetAttributeCompression(attr->atttypid,
907
908
colDef->compression);
909
+
910
+ if (colDef->storage_name)
911
+ {
912
+ attr->attstorage = GetAttributeStorage(colDef->storage_name);
913
+ /*
914
+ * safety check: do not allow toasted storage modes unless column datatype
915
+ * is TOAST-aware.
916
+ */
917
+ if (!(attr->attstorage == TYPSTORAGE_PLAIN ||
918
+ TypeIsToastable(attr->atttypid)))
919
+ ereport(ERROR,
920
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
921
+ errmsg("column data type %s can only have storage PLAIN",
922
+ format_type_be(attr->atttypid))));
923
+ }
924
+
908
925
}
909
926
910
927
/*
@@ -6751,7 +6768,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
6751
6768
attribute.atttypmod = typmod;
6752
6769
attribute.attbyval = tform->typbyval;
6753
6770
attribute.attalign = tform->typalign;
6754
- attribute.attstorage = tform->typstorage;
6771
+ if (colDef->storage_name)
6772
+ {
6773
+ attribute.attstorage = GetAttributeStorage(colDef->storage_name);
6774
+ /*
6775
+ * safety check: do not allow toasted storage modes unless column datatype
6776
+ * is TOAST-aware.
6777
+ */
6778
+ if (!(attribute.attstorage == TYPSTORAGE_PLAIN ||
6779
+ TypeIsToastable(attribute.atttypid)))
6780
+ ereport(ERROR,
6781
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6782
+ errmsg("column data type %s can only have storage PLAIN",
6783
+ format_type_be(attribute.atttypid))));
6784
+ }
6785
+ else
6786
+ attribute.attstorage = tform->typstorage;
6787
+
6755
6788
attribute.attcompression = GetAttributeCompression(typeOid,
6756
6789
colDef->compression);
6757
6790
attribute.attnotnull = colDef->is_not_null;
@@ -8220,7 +8253,6 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
8220
8253
static ObjectAddress
8221
8254
ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
8222
8255
{
8223
- char *storagemode;
8224
8256
char newstorage;
8225
8257
Relation attrelation;
8226
8258
HeapTuple tuple;
@@ -8229,24 +8261,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
8229
8261
ObjectAddress address;
8230
8262
8231
8263
Assert(IsA(newValue, String));
8232
- storagemode = strVal(newValue);
8233
8264
8234
- if (pg_strcasecmp(storagemode, "plain") == 0)
8235
- newstorage = TYPSTORAGE_PLAIN;
8236
- else if (pg_strcasecmp(storagemode, "external") == 0)
8237
- newstorage = TYPSTORAGE_EXTERNAL;
8238
- else if (pg_strcasecmp(storagemode, "extended") == 0)
8239
- newstorage = TYPSTORAGE_EXTENDED;
8240
- else if (pg_strcasecmp(storagemode, "main") == 0)
8241
- newstorage = TYPSTORAGE_MAIN;
8242
- else
8243
- {
8244
- ereport(ERROR,
8245
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8246
- errmsg("invalid storage type \"%s\"",
8247
- storagemode)));
8248
- newstorage = 0; /* keep compiler quiet */
8249
- }
8265
+ newstorage = GetAttributeStorage(strVal(newValue));
8250
8266
8251
8267
attrelation = table_open(AttributeRelationId, RowExclusiveLock);
8252
8268
@@ -18959,3 +18975,24 @@ GetAttributeCompression(Oid atttypid, char *compression)
18959
18975
18960
18976
return cmethod;
18961
18977
}
18978
+
18979
+ static char
18980
+ GetAttributeStorage(const char *storagemode)
18981
+ {
18982
+ if (pg_strcasecmp(storagemode, "plain") == 0)
18983
+ return TYPSTORAGE_PLAIN;
18984
+ else if (pg_strcasecmp(storagemode, "external") == 0)
18985
+ return TYPSTORAGE_EXTERNAL;
18986
+ else if (pg_strcasecmp(storagemode, "extended") == 0)
18987
+ return TYPSTORAGE_EXTENDED;
18988
+ else if (pg_strcasecmp(storagemode, "main") == 0)
18989
+ return TYPSTORAGE_MAIN;
18990
+ else
18991
+ {
18992
+ ereport(ERROR,
18993
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
18994
+ errmsg("invalid storage type \"%s\"",
18995
+ storagemode)));
18996
+ return 0; /* keep compiler quiet */
18997
+ }
18998
+ }
0 commit comments