@ -593,7 +593,7 @@ static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKM
static void ATExecGenericOptions ( Relation rel , List * options ) ;
static void ATExecSetRowSecurity ( Relation rel , bool rls ) ;
static void ATExecForceNoForceRowSecurity ( Relation rel , bool force_rls ) ;
static ObjectAddress ATExecSetCompression ( AlteredTableInfo * tab , Relation rel ,
static ObjectAddress ATExecSetCompression ( Relation rel ,
const char * column , Node * newValue , LOCKMODE lockmode ) ;
static void index_copy_data ( Relation rel , RelFileLocator newrlocator ) ;
@ -633,6 +633,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
static List * GetParentedForeignKeyRefs ( Relation partition ) ;
static void ATDetachCheckNoForeignKeyRefs ( Relation partition ) ;
static char GetAttributeCompression ( Oid atttypid , char * compression ) ;
static char GetAttributeStorage ( Oid atttypid , const char * storagemode ) ;
/* ----------------------------------------------------------------
@ -931,6 +932,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
if ( colDef - > compression )
attr - > attcompression = GetAttributeCompression ( attr - > atttypid ,
colDef - > compression ) ;
if ( colDef - > storage_name )
attr - > attstorage = GetAttributeStorage ( attr - > atttypid , colDef - > storage_name ) ;
}
/*
@ -4963,8 +4967,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
case AT_SetStorage : /* ALTER COLUMN SET STORAGE */
address = ATExecSetStorage ( rel , cmd - > name , cmd - > def , lockmode ) ;
break ;
case AT_SetCompression :
address = ATExecSetCompression ( tab , rel , cmd - > name , cmd - > def ,
case AT_SetCompression : /* ALTER COLUMN SET COMPRESSION */
address = ATExecSetCompression ( rel , cmd - > name , cmd - > def ,
lockmode ) ;
break ;
case AT_DropColumn : /* DROP COLUMN */
@ -6820,7 +6824,10 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
attribute . atttypmod = typmod ;
attribute . attbyval = tform - > typbyval ;
attribute . attalign = tform - > typalign ;
attribute . attstorage = tform - > typstorage ;
if ( colDef - > storage_name )
attribute . attstorage = GetAttributeStorage ( typeOid , colDef - > storage_name ) ;
else
attribute . attstorage = tform - > typstorage ;
attribute . attcompression = GetAttributeCompression ( typeOid ,
colDef - > compression ) ;
attribute . attnotnull = colDef - > is_not_null ;
@ -8263,33 +8270,12 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
static ObjectAddress
ATExecSetStorage ( Relation rel , const char * colName , Node * newValue , LOCKMODE lockmode )
{
char * storagemode ;
char newstorage ;
Relation attrelation ;
HeapTuple tuple ;
Form_pg_attribute attrtuple ;
AttrNumber attnum ;
ObjectAddress address ;
storagemode = strVal ( newValue ) ;
if ( pg_strcasecmp ( storagemode , " plain " ) = = 0 )
newstorage = TYPSTORAGE_PLAIN ;
else if ( pg_strcasecmp ( storagemode , " external " ) = = 0 )
newstorage = TYPSTORAGE_EXTERNAL ;
else if ( pg_strcasecmp ( storagemode , " extended " ) = = 0 )
newstorage = TYPSTORAGE_EXTENDED ;
else if ( pg_strcasecmp ( storagemode , " main " ) = = 0 )
newstorage = TYPSTORAGE_MAIN ;
else
{
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " invalid storage type \" %s \" " ,
storagemode ) ) ) ;
newstorage = 0 ; /* keep compiler quiet */
}
attrelation = table_open ( AttributeRelationId , RowExclusiveLock ) ;
tuple = SearchSysCacheCopyAttName ( RelationGetRelid ( rel ) , colName ) ;
@ -8308,17 +8294,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
errmsg ( " cannot alter system column \" %s \" " ,
colName ) ) ) ;
/*
* safety check : do not allow toasted storage modes unless column datatype
* is TOAST - aware .
*/
if ( newstorage = = TYPSTORAGE_PLAIN | | TypeIsToastable ( attrtuple - > atttypid ) )
attrtuple - > attstorage = newstorage ;
else
ereport ( ERROR ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
errmsg ( " column data type %s can only have storage PLAIN " ,
format_type_be ( attrtuple - > atttypid ) ) ) ) ;
attrtuple - > attstorage = GetAttributeStorage ( attrtuple - > atttypid , strVal ( newValue ) ) ;
CatalogTupleUpdate ( attrelation , & tuple - > t_self , tuple ) ;
@ -8326,17 +8302,17 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
RelationGetRelid ( rel ) ,
attrtuple - > attnum ) ;
heap_freetuple ( tuple ) ;
/*
* Apply the change to indexes as well ( only for simple index columns ,
* matching behavior of index . c ConstructTupleDescriptor ( ) ) .
*/
SetIndexStorageProperties ( rel , attrelation , attnum ,
true , new storage,
true , attrtuple - > att storage,
false , 0 ,
lockmode ) ;
heap_freetuple ( tuple ) ;
table_close ( attrelation , RowExclusiveLock ) ;
ObjectAddressSubSet ( address , RelationRelationId ,
@ -16156,8 +16132,7 @@ ATExecGenericOptions(Relation rel, List *options)
* Return value is the address of the modified column
*/
static ObjectAddress
ATExecSetCompression ( AlteredTableInfo * tab ,
Relation rel ,
ATExecSetCompression ( Relation rel ,
const char * column ,
Node * newValue ,
LOCKMODE lockmode )
@ -19287,3 +19262,38 @@ GetAttributeCompression(Oid atttypid, char *compression)
return cmethod ;
}
/*
* resolve column storage specification
*/
static char
GetAttributeStorage ( Oid atttypid , const char * storagemode )
{
char cstorage = 0 ;
if ( pg_strcasecmp ( storagemode , " plain " ) = = 0 )
cstorage = TYPSTORAGE_PLAIN ;
else if ( pg_strcasecmp ( storagemode , " external " ) = = 0 )
cstorage = TYPSTORAGE_EXTERNAL ;
else if ( pg_strcasecmp ( storagemode , " extended " ) = = 0 )
cstorage = TYPSTORAGE_EXTENDED ;
else if ( pg_strcasecmp ( storagemode , " main " ) = = 0 )
cstorage = TYPSTORAGE_MAIN ;
else
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " invalid storage type \" %s \" " ,
storagemode ) ) ) ;
/*
* safety check : do not allow toasted storage modes unless column datatype
* is TOAST - aware .
*/
if ( ! ( cstorage = = TYPSTORAGE_PLAIN | | TypeIsToastable ( atttypid ) ) )
ereport ( ERROR ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
errmsg ( " column data type %s can only have storage PLAIN " ,
format_type_be ( atttypid ) ) ) ) ;
return cstorage ;
}