@@ -607,6 +607,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
607607static List *GetParentedForeignKeyRefs(Relation partition);
608608static void ATDetachCheckNoForeignKeyRefs(Relation partition);
609609static char GetAttributeCompression(Oid atttypid, char *compression);
610+ static char GetAttributeStorage(const char *storagemode);
610611
611612
612613/* ----------------------------------------------------------------
@@ -905,6 +906,22 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
905906 if (colDef->compression)
906907 attr->attcompression = GetAttributeCompression(attr->atttypid,
907908 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+
908925 }
909926
910927 /*
@@ -6751,7 +6768,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
67516768 attribute.atttypmod = typmod;
67526769 attribute.attbyval = tform->typbyval;
67536770 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+
67556788 attribute.attcompression = GetAttributeCompression(typeOid,
67566789 colDef->compression);
67576790 attribute.attnotnull = colDef->is_not_null;
@@ -8220,7 +8253,6 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
82208253static ObjectAddress
82218254ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
82228255{
8223- char *storagemode;
82248256 char newstorage;
82258257 Relation attrelation;
82268258 HeapTuple tuple;
@@ -8229,24 +8261,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
82298261 ObjectAddress address;
82308262
82318263 Assert(IsA(newValue, String));
8232- storagemode = strVal(newValue);
82338264
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));
82508266
82518267 attrelation = table_open(AttributeRelationId, RowExclusiveLock);
82528268
@@ -18959,3 +18975,24 @@ GetAttributeCompression(Oid atttypid, char *compression)
1895918975
1896018976 return cmethod;
1896118977}
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