diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/brin/brin_tuple.c | 5 | ||||
-rw-r--r-- | src/backend/access/common/indextuple.c | 13 | ||||
-rw-r--r-- | src/backend/access/common/toast_internals.c | 6 | ||||
-rw-r--r-- | src/backend/access/common/tupdesc.c | 7 | ||||
-rw-r--r-- | src/backend/access/heap/heapam_handler.c | 12 | ||||
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 7 | ||||
-rw-r--r-- | src/backend/catalog/genbki.pl | 4 | ||||
-rw-r--r-- | src/backend/catalog/heap.c | 2 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 124 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 38 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 8 |
11 files changed, 93 insertions, 133 deletions
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c index ee05372f795..09e563b1f08 100644 --- a/src/backend/access/brin/brin_tuple.c +++ b/src/backend/access/brin/brin_tuple.c @@ -232,11 +232,10 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, * same compression method. Otherwise we have to use the * default method. */ - if (att->atttypid == atttype->type_id && - CompressionMethodIsValid(att->attcompression)) + if (att->atttypid == atttype->type_id) compression = att->attcompression; else - compression = GetDefaultToastCompression(); + compression = InvalidCompressionMethod; cvalue = toast_compress_datum(value, compression); diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index 52125604113..8df882da7a7 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -104,18 +104,9 @@ index_form_tuple(TupleDesc tupleDescriptor, att->attstorage == TYPSTORAGE_MAIN)) { Datum cvalue; - char compression = att->attcompression; - /* - * If the compression method is not valid, use the default. We - * don't expect this to happen for regular index columns, which - * inherit the setting from the corresponding table column, but we - * do expect it to happen whenever an expression is indexed. - */ - if (!CompressionMethodIsValid(compression)) - compression = GetDefaultToastCompression(); - - cvalue = toast_compress_datum(untoasted_values[i], compression); + cvalue = toast_compress_datum(untoasted_values[i], + att->attcompression); if (DatumGetPointer(cvalue) != NULL) { diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c index 8d2a9964c3f..c7b9ade5742 100644 --- a/src/backend/access/common/toast_internals.c +++ b/src/backend/access/common/toast_internals.c @@ -53,10 +53,12 @@ toast_compress_datum(Datum value, char cmethod) Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value))); Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); - Assert(CompressionMethodIsValid(cmethod)); - valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); + /* If the compression method is not valid, use the current default */ + if (!CompressionMethodIsValid(cmethod)) + cmethod = default_toast_compression; + /* * Call appropriate compression routine for the compression method. */ diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index affbc509bdc..4c63bd4dc64 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -642,10 +642,7 @@ TupleDescInitEntry(TupleDesc desc, att->attbyval = typeForm->typbyval; att->attalign = typeForm->typalign; att->attstorage = typeForm->typstorage; - if (IsStorageCompressible(typeForm->typstorage)) - att->attcompression = GetDefaultToastCompression(); - else - att->attcompression = InvalidCompressionMethod; + att->attcompression = InvalidCompressionMethod; att->attcollation = typeForm->typcollation; ReleaseSysCache(tuple); @@ -711,7 +708,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attbyval = false; att->attalign = TYPALIGN_INT; att->attstorage = TYPSTORAGE_EXTENDED; - att->attcompression = GetDefaultToastCompression(); + att->attcompression = InvalidCompressionMethod; att->attcollation = DEFAULT_COLLATION_OID; break; diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 8e6e8d51698..e2cd79ec546 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -2483,10 +2483,10 @@ reform_and_rewrite_tuple(HeapTuple tuple, * perform the compression here; we just need to decompress. That * will trigger recompression later on. */ - struct varlena *new_value; ToastCompressionId cmid; char cmethod; + char targetmethod; new_value = (struct varlena *) DatumGetPointer(values[i]); cmid = toast_get_compression_id(new_value); @@ -2495,7 +2495,7 @@ reform_and_rewrite_tuple(HeapTuple tuple, if (cmid == TOAST_INVALID_COMPRESSION_ID) continue; - /* convert compression id to compression method */ + /* convert existing compression id to compression method */ switch (cmid) { case TOAST_PGLZ_COMPRESSION_ID: @@ -2506,10 +2506,16 @@ reform_and_rewrite_tuple(HeapTuple tuple, break; default: elog(ERROR, "invalid compression method id %d", cmid); + cmethod = '\0'; /* keep compiler quiet */ } + /* figure out what the target method is */ + targetmethod = TupleDescAttr(newTupDesc, i)->attcompression; + if (!CompressionMethodIsValid(targetmethod)) + targetmethod = default_toast_compression; + /* if compression method doesn't match then detoast the value */ - if (TupleDescAttr(newTupDesc, i)->attcompression != cmethod) + if (targetmethod != cmethod) { values[i] = PointerGetDatum(detoast_attr(new_value)); values_free[i] = true; diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 62abd008ccf..94ab5ca0954 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -701,6 +701,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; attrtypes[attnum]->attalign = Ap->am_typ.typalign; attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; + attrtypes[attnum]->attcompression = InvalidCompressionMethod; attrtypes[attnum]->attcollation = Ap->am_typ.typcollation; /* if an array type, assume 1-dimensional attribute */ if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0) @@ -715,6 +716,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->attbyval = TypInfo[typeoid].byval; attrtypes[attnum]->attalign = TypInfo[typeoid].align; attrtypes[attnum]->attstorage = TypInfo[typeoid].storage; + attrtypes[attnum]->attcompression = InvalidCompressionMethod; attrtypes[attnum]->attcollation = TypInfo[typeoid].collation; /* if an array type, assume 1-dimensional attribute */ if (TypInfo[typeoid].elem != InvalidOid && @@ -724,11 +726,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->attndims = 0; } - if (IsStorageCompressible(attrtypes[attnum]->attstorage)) - attrtypes[attnum]->attcompression = GetDefaultToastCompression(); - else - attrtypes[attnum]->attcompression = InvalidCompressionMethod; - /* * If a system catalog column is collation-aware, force it to use C * collation, so that its behavior is independent of the database's diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index 112b3affdfd..f893ae4f453 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -899,9 +899,7 @@ sub morph_row_for_pgattr $row->{attbyval} = $type->{typbyval}; $row->{attalign} = $type->{typalign}; $row->{attstorage} = $type->{typstorage}; - - $row->{attcompression} = - $type->{typstorage} ne 'p' && $type->{typstorage} ne 'e' ? 'p' : '\0'; + $row->{attcompression} = '\0'; # set attndims if it's an array type $row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0'; diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 3dfe2e8a565..afa830d9248 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1719,8 +1719,6 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) /* Unset this so no one tries to look up the generation expression */ attStruct->attgenerated = '\0'; - attStruct->attcompression = InvalidCompressionMethod; - /* * Change the column name to something that isn't likely to conflict */ 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)) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index aaf1a51f685..9ee90e3f13a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -561,6 +561,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <node> TableConstraint TableLikeClause %type <ival> TableLikeOptionList TableLikeOption +%type <str> column_compression opt_column_compression %type <list> ColQualList %type <node> ColConstraint ColConstraintElem ConstraintAttr %type <ival> key_actions key_delete key_match key_update key_action @@ -609,7 +610,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <list> hash_partbound %type <defelt> hash_partbound_elem -%type <str> optColumnCompression /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -2302,6 +2302,15 @@ alter_table_cmd: n->def = (Node *) makeString($6); $$ = (Node *)n; } + /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET COMPRESSION <cm> */ + | ALTER opt_column ColId SET column_compression + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetCompression; + n->name = $3; + n->def = (Node *) makeString($5); + $$ = (Node *)n; + } /* ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ... AS IDENTITY ... */ | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList { @@ -2346,15 +2355,6 @@ alter_table_cmd: n->missing_ok = true; $$ = (Node *)n; } - /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET (COMPRESSION <cm>) */ - | ALTER opt_column ColId SET optColumnCompression - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetCompression; - n->name = $3; - n->def = (Node *) makeString($5); - $$ = (Node *)n; - } /* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */ | DROP opt_column IF_P EXISTS ColId opt_drop_behavior { @@ -3462,7 +3462,7 @@ TypedTableElement: | TableConstraint { $$ = $1; } ; -columnDef: ColId Typename optColumnCompression create_generic_options ColQualList +columnDef: ColId Typename opt_column_compression create_generic_options ColQualList { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; @@ -3522,13 +3522,15 @@ columnOptions: ColId ColQualList } ; -optColumnCompression: - COMPRESSION name - { - $$ = $2; - } - | /*EMPTY*/ { $$ = NULL; } - ; +column_compression: + COMPRESSION ColId { $$ = $2; } + | COMPRESSION DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_compression: + column_compression { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; ColQualList: ColQualList ColConstraint { $$ = lappend($1, $2); } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ee731044b63..87bc6887046 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4651,13 +4651,13 @@ static struct config_enum ConfigureNamesEnum[] = { {"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default compression for new columns."), - NULL, - GUC_IS_NAME + gettext_noop("Sets the default compression method for compressible values."), + NULL }, &default_toast_compression, TOAST_PGLZ_COMPRESSION, - default_toast_compression_options, NULL, NULL + default_toast_compression_options, + NULL, NULL, NULL }, { |