@@ -625,6 +625,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
625625static List *GetParentedForeignKeyRefs(Relation partition);
626626static void ATDetachCheckNoForeignKeyRefs(Relation partition);
627627static char GetAttributeCompression(Oid atttypid, char *compression);
628+ static char GetAttributeStorage(const char *storagemode);
628629
629630
630631/* ----------------------------------------------------------------
@@ -923,6 +924,22 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
923924 if (colDef->compression)
924925 attr->attcompression = GetAttributeCompression(attr->atttypid,
925926 colDef->compression);
927+
928+ if (colDef->storage_name)
929+ {
930+ attr->attstorage = GetAttributeStorage(colDef->storage_name);
931+ /*
932+ * safety check: do not allow toasted storage modes unless column datatype
933+ * is TOAST-aware.
934+ */
935+ if (!(attr->attstorage == TYPSTORAGE_PLAIN ||
936+ TypeIsToastable(attr->atttypid)))
937+ ereport(ERROR,
938+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
939+ errmsg("column data type %s can only have storage PLAIN",
940+ format_type_be(attr->atttypid))));
941+ }
942+
926943 }
927944
928945 /*
@@ -6769,7 +6786,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
67696786 attribute.atttypmod = typmod;
67706787 attribute.attbyval = tform->typbyval;
67716788 attribute.attalign = tform->typalign;
6772- attribute.attstorage = tform->typstorage;
6789+ if (colDef->storage_name)
6790+ {
6791+ attribute.attstorage = GetAttributeStorage(colDef->storage_name);
6792+ /*
6793+ * safety check: do not allow toasted storage modes unless column datatype
6794+ * is TOAST-aware.
6795+ */
6796+ if (!(attribute.attstorage == TYPSTORAGE_PLAIN ||
6797+ TypeIsToastable(attribute.atttypid)))
6798+ ereport(ERROR,
6799+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6800+ errmsg("column data type %s can only have storage PLAIN",
6801+ format_type_be(attribute.atttypid))));
6802+ }
6803+ else
6804+ attribute.attstorage = tform->typstorage;
6805+
67736806 attribute.attcompression = GetAttributeCompression(typeOid,
67746807 colDef->compression);
67756808 attribute.attnotnull = colDef->is_not_null;
@@ -8238,7 +8271,6 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
82388271static ObjectAddress
82398272ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
82408273{
8241- char *storagemode;
82428274 char newstorage;
82438275 Relation attrelation;
82448276 HeapTuple tuple;
@@ -8247,24 +8279,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
82478279 ObjectAddress address;
82488280
82498281 Assert(IsA(newValue, String));
8250- storagemode = strVal(newValue);
82518282
8252- if (pg_strcasecmp(storagemode, "plain") == 0)
8253- newstorage = TYPSTORAGE_PLAIN;
8254- else if (pg_strcasecmp(storagemode, "external") == 0)
8255- newstorage = TYPSTORAGE_EXTERNAL;
8256- else if (pg_strcasecmp(storagemode, "extended") == 0)
8257- newstorage = TYPSTORAGE_EXTENDED;
8258- else if (pg_strcasecmp(storagemode, "main") == 0)
8259- newstorage = TYPSTORAGE_MAIN;
8260- else
8261- {
8262- ereport(ERROR,
8263- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8264- errmsg("invalid storage type \"%s\"",
8265- storagemode)));
8266- newstorage = 0; /* keep compiler quiet */
8267- }
8283+ newstorage = GetAttributeStorage(strVal(newValue));
82688284
82698285 attrelation = table_open(AttributeRelationId, RowExclusiveLock);
82708286
@@ -19239,3 +19255,24 @@ GetAttributeCompression(Oid atttypid, char *compression)
1923919255
1924019256 return cmethod;
1924119257}
19258+
19259+ static char
19260+ GetAttributeStorage(const char *storagemode)
19261+ {
19262+ if (pg_strcasecmp(storagemode, "plain") == 0)
19263+ return TYPSTORAGE_PLAIN;
19264+ else if (pg_strcasecmp(storagemode, "external") == 0)
19265+ return TYPSTORAGE_EXTERNAL;
19266+ else if (pg_strcasecmp(storagemode, "extended") == 0)
19267+ return TYPSTORAGE_EXTENDED;
19268+ else if (pg_strcasecmp(storagemode, "main") == 0)
19269+ return TYPSTORAGE_MAIN;
19270+ else
19271+ {
19272+ ereport(ERROR,
19273+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
19274+ errmsg("invalid storage type \"%s\"",
19275+ storagemode)));
19276+ return 0; /* keep compiler quiet */
19277+ }
19278+ }
0 commit comments