aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c124
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))