diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 124 |
1 files changed, 47 insertions, 77 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 11e91c4ad33..028e8ac46b3 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -601,7 +601,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTbl); static List *GetParentedForeignKeyRefs(Relation partition); static void ATDetachCheckNoForeignKeyRefs(Relation partition); -static char GetAttributeCompression(Form_pg_attribute att, char *compression); +static char GetAttributeCompression(Oid atttypid, char *compression); /* ---------------------------------------------------------------- @@ -897,17 +897,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, if (colDef->generated) attr->attgenerated = colDef->generated; - /* - * lookup attribute's compression method and store it in the - * attr->attcompression. - */ - if (relkind == RELKIND_RELATION || - relkind == RELKIND_PARTITIONED_TABLE || - relkind == RELKIND_MATVIEW) - attr->attcompression = - GetAttributeCompression(attr, colDef->compression); - else - attr->attcompression = InvalidCompressionMethod; + if (colDef->compression) + attr->attcompression = GetAttributeCompression(attr->atttypid, + colDef->compression); } /* @@ -6602,13 +6594,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.attbyval = tform->typbyval; attribute.attalign = tform->typalign; attribute.attstorage = tform->typstorage; - /* do not set compression in views etc */ - if (rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - attribute.attcompression = GetAttributeCompression(&attribute, - colDef->compression); - else - attribute.attcompression = InvalidCompressionMethod; + attribute.attcompression = GetAttributeCompression(typeOid, + colDef->compression); attribute.attnotnull = colDef->is_not_null; attribute.atthasdef = false; attribute.atthasmissing = false; @@ -7995,23 +7982,24 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, /* * Helper function for ATExecSetStorage and ATExecSetCompression * - * Set the attcompression and/or attstorage for the respective index attribute - * if the respective input values are valid. + * Set the attstorage and/or attcompression fields for index columns + * associated with the specified table column. */ static void SetIndexStorageProperties(Relation rel, Relation attrelation, - AttrNumber attnum, char newcompression, - char newstorage, LOCKMODE lockmode) + AttrNumber attnum, + bool setstorage, char newstorage, + bool setcompression, char newcompression, + LOCKMODE lockmode) { - HeapTuple tuple; ListCell *lc; - Form_pg_attribute attrtuple; foreach(lc, RelationGetIndexList(rel)) { Oid indexoid = lfirst_oid(lc); Relation indrel; AttrNumber indattnum = 0; + HeapTuple tuple; indrel = index_open(indexoid, lockmode); @@ -8034,14 +8022,14 @@ SetIndexStorageProperties(Relation rel, Relation attrelation, if (HeapTupleIsValid(tuple)) { - attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); + Form_pg_attribute attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); - if (CompressionMethodIsValid(newcompression)) - attrtuple->attcompression = newcompression; - - if (newstorage != '\0') + if (setstorage) attrtuple->attstorage = newstorage; + if (setcompression) + attrtuple->attcompression = newcompression; + CatalogTupleUpdate(attrelation, &tuple->t_self, tuple); InvokeObjectPostAlterHook(RelationRelationId, @@ -8134,8 +8122,9 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc * matching behavior of index.c ConstructTupleDescriptor()). */ SetIndexStorageProperties(rel, attrelation, attnum, - InvalidCompressionMethod, - newstorage, lockmode); + true, newstorage, + false, 0, + lockmode); table_close(attrelation, RowExclusiveLock); @@ -12299,23 +12288,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, attTup->attbyval = tform->typbyval; attTup->attalign = tform->typalign; attTup->attstorage = tform->typstorage; - - /* Setup attribute compression */ - if (rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - { - /* - * No compression for plain/external storage, otherwise, default - * compression method if it is not already set, refer comments atop - * attcompression parameter in pg_attribute.h. - */ - if (!IsStorageCompressible(tform->typstorage)) - attTup->attcompression = InvalidCompressionMethod; - else if (!CompressionMethodIsValid(attTup->attcompression)) - attTup->attcompression = GetDefaultToastCompression(); - } - else - attTup->attcompression = InvalidCompressionMethod; + attTup->attcompression = InvalidCompressionMethod; ReleaseSysCache(typeTuple); @@ -15613,7 +15586,6 @@ ATExecSetCompression(AlteredTableInfo *tab, Form_pg_attribute atttableform; AttrNumber attnum; char *compression; - char typstorage; char cmethod; ObjectAddress address; @@ -15638,17 +15610,11 @@ ATExecSetCompression(AlteredTableInfo *tab, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot alter system column \"%s\"", column))); - typstorage = get_typstorage(atttableform->atttypid); - - /* prevent from setting compression methods for uncompressible type */ - if (!IsStorageCompressible(typstorage)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("column data type %s does not support compression", - format_type_be(atttableform->atttypid)))); - - /* get the attribute compression method. */ - cmethod = GetAttributeCompression(atttableform, compression); + /* + * Check that column type is compressible, then get the attribute + * compression method code + */ + cmethod = GetAttributeCompression(atttableform->atttypid, compression); /* update pg_attribute entry */ atttableform->attcompression = cmethod; @@ -15662,7 +15628,10 @@ ATExecSetCompression(AlteredTableInfo *tab, * Apply the change to indexes as well (only for simple index columns, * matching behavior of index.c ConstructTupleDescriptor()). */ - SetIndexStorageProperties(rel, attrel, attnum, cmethod, '\0', lockmode); + SetIndexStorageProperties(rel, attrel, attnum, + false, 0, + true, cmethod, + lockmode); heap_freetuple(tuple); @@ -18612,29 +18581,30 @@ ATDetachCheckNoForeignKeyRefs(Relation partition) * resolve column compression specification to compression method. */ static char -GetAttributeCompression(Form_pg_attribute att, char *compression) +GetAttributeCompression(Oid atttypid, char *compression) { - char typstorage = get_typstorage(att->atttypid); char cmethod; + if (compression == NULL || strcmp(compression, "default") == 0) + return InvalidCompressionMethod; + /* - * No compression for plain/external storage, refer comments atop - * attcompression parameter in pg_attribute.h + * To specify a nondefault method, the column data type must be toastable. + * Note this says nothing about whether the column's attstorage setting + * permits compression; we intentionally allow attstorage and + * attcompression to be independent. But with a non-toastable type, + * attstorage could not be set to a value that would permit compression. + * + * We don't actually need to enforce this, since nothing bad would happen + * if attcompression were non-default; it would never be consulted. But + * it seems more user-friendly to complain about a certainly-useless + * attempt to set the property. */ - if (!IsStorageCompressible(typstorage)) - { - if (compression == NULL) - return InvalidCompressionMethod; - + if (!TypeIsToastable(atttypid)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("column data type %s does not support compression", - format_type_be(att->atttypid)))); - } - - /* fallback to default compression if it's not specified */ - if (compression == NULL) - return GetDefaultToastCompression(); + format_type_be(atttypid)))); cmethod = CompressionNameToMethod(compression); if (!CompressionMethodIsValid(cmethod)) |