attcompression char
- The current compression method of the column. If it is an invalid
- compression method ('\0' ) then column data will not
- be compressed. Otherwise, 'p' = pglz compression or
+ The current compression method of the column. Typically this is
+ '\0' to specify use of the current default setting
+ (see ). Otherwise,
+ 'p' selects pglz compression, while
+ compression. However, this field is ignored
+ whenever attstorage does not allow
+ compression.
This variable sets the default
TOAST
- compression method for columns of newly-created tables. The
- CREATE TABLE statement can override this default
- by specifying the COMPRESSION column option.
-
- The supported compression methods are pglz and,
- if
PostgreSQL was compiled with
- --with-lz4 , lz4 .
+ compression method for values of compressible columns.
+ (This can be overridden for individual columns by setting
+ the COMPRESSION column option in
+ CREATE TABLE or
+ ALTER TABLE .)
+ The supported compression methods are pglz and
+ (if
PostgreSQL was compiled with
+ --with-lz4 ) lz4 .
The default is pglz .
pg_column_compression ( "any" )
- integer
+ text
- Shows the compression algorithm that was used to compress a
+ Shows the compression algorithm that was used to compress
an individual variable-length value. Returns NULL
if the value is not compressed.
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
UNIQUE index_parameters |
PRIMARY KEY index_parameters |
- COMPRESSION compression_method |
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
- This sets the compression method to be used for data inserted into a column.
-
+ This form sets the compression method for a column, determining how
+ values inserted in future will be compressed (if the storage mode
+ permits compression at all).
This does not cause the table to be rewritten, so existing data may still
be compressed with other compression methods. If the table is rewritten with
VACUUM FULL or CLUSTER , or restored
- with
pg_restore , then all tuples are rewritten
- with the configured compression methods.
-
- Also, note that when data is inserted from another relation (for example,
- by INSERT ... SELECT ), tuples from the source data are
- not necessarily detoasted, and any previously compressed data is retained
- with its existing compression method, rather than recompressing with the
- compression methods of the target columns.
-
+ with
pg_restore , then all values are rewritten
+ with the configured compression method.
+ However, when data is inserted from another relation (for example,
+ by INSERT ... SELECT ), values from the source table are
+ not necessarily detoasted, so any previously compressed data may retain
+ its existing compression method, rather than being recompressed with the
+ compression method of the target column.
The supported compression
methods are pglz and lz4 .
- lz4 is available only if --with-lz4
- was used when building
PostgreSQL .
+ (lz4 is available only if --with-lz4
+ was used when building
PostgreSQL .) In
+ addition, compression_method
+ can be default , which selects the default behavior of
+ consulting the setting
+ at the time of data insertion to determine the method to use.
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
- { column_name data_type [ COLLATE collation ] [ COMPRESSION compression_method ] [ column_constraint [ ... ] ]
+ { column_name data_type [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ]
| table_constraint
| LIKE source_table [ like_option ... ] }
[, ... ]
The COMPRESSION clause sets the compression method
- for a column. Compression is supported only for variable-width data
- types, and is used only for columns whose storage type is main or
- extended. (See for information on
- column storage types.) Setting this property for a partitioned table
+ for the column. Compression is supported only for variable-width data
+ types, and is used only when the column's storage mode
+ is main or extended .
+ (See for information on
+ column storage modes.) Setting this property for a partitioned table
has no direct effect, because such tables have no storage of their own,
- but the configured value is inherited by newly-created partitions.
+ but the configured value will be inherited by newly-created partitions.
The supported compression methods are pglz and
- lz4 . lz4 is available only if
- --with-lz4 was used when building
-
PostgreSQL . The default
- is pglz .
+ lz4 . (lz4 is available only if
+ --with-lz4 was used when building
+
PostgreSQL .) In addition,
+ compression_method
+ can be default to explicitly specify the default
+ behavior, which is to consult the
+ setting at the time of
+ data insertion to determine the method to use.
Do not output commands to set
TOAST compression
methods.
- With this option, all objects will be created using whichever
- compression method is the default during restore .
+ With this option, all columns will be restored with the default
+ compression setting .
Do not output commands to set
TOAST compression
methods.
- With this option, all objects will be created using whichever
- compression method is the default during restore .
+ With this option, all columns will be restored with the default
+ compression setting .
-
+
--no-unlogged-table-data
the content of the
TOAST pointer tells that, instead.
+The compression technique used for either in-line or out-of-line compressed
+data can be selected for each column by setting
+the COMPRESSION column option in CREATE
+TABLE or ALTER TABLE . The default for columns
+with no explicit setting is to consult the
+ parameter at the time data is
+inserted.
+
+
As mentioned, there are multiple types of
TOAST pointer datums.
The oldest and most common type is a pointer to out-of-line data stored in
Further details appear in .
-The compression technique used for either in-line or out-of-line compressed
-data can be selected using the COMPRESSION option on a per-column
-basis when creating a table. The default for columns with no explicit setting
-is taken from the value of .
-
-
Out-of-Line, On-Disk TOAST Storage
* 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);
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)
{
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.
*/
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);
att->attbyval = false;
att->attalign = TYPALIGN_INT;
att->attstorage = TYPSTORAGE_EXTENDED;
- att->attcompression = GetDefaultToastCompression() ;
+ att->attcompression = InvalidCompressionMethod ;
att->attcollation = DEFAULT_COLLATION_OID;
break;
* 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);
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:
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;
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)
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 &&
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
$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';
/* 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
*/
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);
/* ----------------------------------------------------------------
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);
}
/*
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;
/*
* 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);
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,
* matching behavior of index.c ConstructTupleDescriptor()).
*/
SetIndexStorageProperties(rel, attrelation, attnum,
- InvalidCompressionMethod,
- newstorage, lockmode);
+ true, newstorage,
+ false, 0,
+ lockmode);
table_close(attrelation, RowExclusiveLock);
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);
Form_pg_attribute atttableform;
AttrNumber attnum;
char *compression;
- char typstorage;
char cmethod;
ObjectAddress address;
(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;
* 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);
* 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))
%type TableConstraint TableLikeClause
%type TableLikeOptionList TableLikeOption
+%type column_compression opt_column_compression
%type ColQualList
%type ColConstraint ColConstraintElem ConstraintAttr
%type key_actions key_delete key_match key_update key_action
%type hash_partbound
%type hash_partbound_elem
-%type optColumnCompression
/*
* Non-keyword token types. These are hard-wired into the "flex" lexer.
n->def = (Node *) makeString($6);
$$ = (Node *)n;
}
+ /* ALTER TABLE ALTER [COLUMN] SET COMPRESSION */
+ | 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 ALTER [COLUMN] ADD GENERATED ... AS IDENTITY ... */
| ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
{
n->missing_ok = true;
$$ = (Node *)n;
}
- /* ALTER TABLE ALTER [COLUMN] SET (COMPRESSION ) */
- | 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 DROP [COLUMN] IF EXISTS [RESTRICT|CASCADE] */
| DROP opt_column IF_P EXISTS ColId opt_drop_behavior
{
| TableConstraint { $$ = $1; }
;
-columnDef: ColId Typename optColumnC ompression create_generic_options ColQualList
+columnDef: ColId Typename opt_column_c ompression create_generic_options ColQualList
{
ColumnDef *n = makeNode(ColumnDef);
n->colname = $1;
}
;
-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); }
{
{"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
},
{
/* other important stuff */
char *searchpath; /* search_path to set during restore */
- char *default_toast_compression; /* default TOAST compression to
- * set during restore */
char *use_role; /* Issue SET ROLE to this */
/* error handling */
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te);
-static void processToastCompressionEntry(ArchiveHandle *AH, TocEntry *te);
static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH);
static RestorePass _tocEntryRestorePass(TocEntry *te);
static bool _tocEntryIsACL(TocEntry *te);
processStdStringsEntry(AH, te);
else if (strcmp(te->desc, "SEARCHPATH") == 0)
processSearchPathEntry(AH, te);
- else if (strcmp(te->desc, "TOASTCOMPRESSION") == 0)
- processToastCompressionEntry(AH, te);
}
}
AH->public.searchpath = pg_strdup(te->defn);
}
-static void
-processToastCompressionEntry(ArchiveHandle *AH, TocEntry *te)
-{
- /* te->defn should have the form SET default_toast_compression = 'x'; */
- char *defn = pg_strdup(te->defn);
- char *ptr1;
- char *ptr2 = NULL;
-
- ptr1 = strchr(defn, '\'');
- if (ptr1)
- ptr2 = strchr(++ptr1, '\'');
- if (ptr2)
- {
- *ptr2 = '\0';
- AH->public.default_toast_compression = pg_strdup(ptr1);
- }
- else
- fatal("invalid TOASTCOMPRESSION item: %s",
- te->defn);
-
- free(defn);
-}
-
static void
StrictNamesCheck(RestoreOptions *ropt)
{
/* These items are treated specially */
if (strcmp(te->desc, "ENCODING") == 0 ||
strcmp(te->desc, "STDSTRINGS") == 0 ||
- strcmp(te->desc, "SEARCHPATH") == 0 ||
- strcmp(te->desc, "TOASTCOMPRESSION") == 0)
+ strcmp(te->desc, "SEARCHPATH") == 0)
return REQ_SPECIAL;
/*
if (AH->public.searchpath)
ahprintf(AH, "%s", AH->public.searchpath);
- /* Select the dump-time default_toast_compression */
- if (AH->public.default_toast_compression)
- ahprintf(AH, "SET default_toast_compression = '%s';\n",
- AH->public.default_toast_compression);
-
/* Make sure function checking is disabled */
ahprintf(AH, "SET check_function_bodies = false;\n");
static void dumpEncoding(Archive *AH);
static void dumpStdStrings(Archive *AH);
static void dumpSearchPath(Archive *AH);
-static void dumpToastCompression(Archive *AH);
static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
PQExpBuffer upgrade_buffer,
Oid pg_type_oid,
*/
/*
- * First the special entries for ENCODING, STDSTRINGS, SEARCHPATH and
- * TOASTCOMPRESSION.
+ * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
*/
dumpEncoding(fout);
dumpStdStrings(fout);
dumpSearchPath(fout);
- dumpToastCompression(fout);
/* The database items are always next, unless we don't want them at all */
if (dopt.outputCreateDB)
destroyPQExpBuffer(path);
}
-/*
- * dumpToastCompression: save the dump-time default TOAST compression in the
- * archive
- */
-static void
-dumpToastCompression(Archive *AH)
-{
- char *toast_compression;
- PQExpBuffer qry;
-
- if (AH->dopt->no_toast_compression)
- {
- /* we don't intend to dump the info, so no need to fetch it either */
- return;
- }
-
- if (AH->remoteVersion < 140000)
- {
- /* pre-v14, the only method was pglz */
- toast_compression = pg_strdup("pglz");
- }
- else
- {
- PGresult *res;
-
- res = ExecuteSqlQueryForSingleRow(AH, "SHOW default_toast_compression");
- toast_compression = pg_strdup(PQgetvalue(res, 0, 0));
- PQclear(res);
- }
-
- qry = createPQExpBuffer();
- appendPQExpBufferStr(qry, "SET default_toast_compression = ");
- appendStringLiteralAH(qry, toast_compression, AH);
- appendPQExpBufferStr(qry, ";\n");
-
- pg_log_info("saving default_toast_compression = %s", toast_compression);
-
- ArchiveEntry(AH, nilCatalogId, createDumpId(),
- ARCHIVE_OPTS(.tag = "TOASTCOMPRESSION",
- .description = "TOASTCOMPRESSION",
- .section = SECTION_PRE_DATA,
- .createStmt = qry->data));
-
- /*
- * Also save it in AH->default_toast_compression, in case we're doing
- * plain text dump.
- */
- AH->default_toast_compression = toast_compression;
-
- destroyPQExpBuffer(qry);
-}
-
/*
* getBlobs:
}
/*
- * Dump per-column attributes.
- */
- if (tbinfo->attoptions[j][0] != '\0')
- appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
- foreign, qualrelname,
- fmtId(tbinfo->attnames[j]),
- tbinfo->attoptions[j]);
-
- /*
- * Dump per-column fdw options.
- */
- if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
- tbinfo->attfdwoptions[j][0] != '\0')
- appendPQExpBuffer(q,
- "ALTER FOREIGN TABLE %s ALTER COLUMN %s OPTIONS (\n"
- " %s\n"
- ");\n",
- qualrelname,
- fmtId(tbinfo->attnames[j]),
- tbinfo->attfdwoptions[j]);
-
- /*
- * Dump per-column compression, if different from default.
+ * Dump per-column compression, if it's been set.
*/
if (!dopt->no_toast_compression)
{
break;
}
- if (cmname != NULL &&
- (fout->default_toast_compression == NULL ||
- strcmp(cmname, fout->default_toast_compression) != 0))
+ if (cmname != NULL)
appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
foreign, qualrelname,
fmtId(tbinfo->attnames[j]),
cmname);
}
+
+ /*
+ * Dump per-column attributes.
+ */
+ if (tbinfo->attoptions[j][0] != '\0')
+ appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
+ foreign, qualrelname,
+ fmtId(tbinfo->attnames[j]),
+ tbinfo->attoptions[j]);
+
+ /*
+ * Dump per-column fdw options.
+ */
+ if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
+ tbinfo->attfdwoptions[j][0] != '\0')
+ appendPQExpBuffer(q,
+ "ALTER FOREIGN TABLE %s ALTER COLUMN %s OPTIONS (\n"
+ " %s\n"
+ ");\n",
+ qualrelname,
+ fmtId(tbinfo->attnames[j]),
+ tbinfo->attfdwoptions[j]);
} /* end loop over columns */
if (ftoptions)
indexdef_col = -1,
fdwopts_col = -1,
attstorage_col = -1,
+ attcompression_col = -1,
attstattarget_col = -1,
- attdescr_col = -1,
- attcompression_col = -1;
+ attdescr_col = -1;
int numrows;
struct
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
- /* compression info */
+ /* compression info, if relevant to relkind */
if (pset.sversion >= 140000 &&
!pset.hide_compression &&
(tableinfo.relkind == RELKIND_RELATION ||
if (fdwopts_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, fdwopts_col), false, false);
- /* Storage and Description */
+ /* Storage mode, if relevant */
if (attstorage_col >= 0)
{
char *storage = PQgetvalue(res, i, attstorage_col);
false, false);
}
- /* Column compression. */
+ /* Column compression, if relevant */
if (attcompression_col >= 0)
{
char *compression = PQgetvalue(res, i, attcompression_col);
extern int default_toast_compression;
/*
- * Built-in compression method-id . The toast compression header will store
+ * Built-in compression method ID . The toast compression header will store
* this in the first 2 bits of the raw length. These built-in compression
- * method-id are directly mapped to the built-in compression methods.
+ * method IDs are directly mapped to the built-in compression methods.
*
* Don't use these values for anything other than understanding the meaning
* of the raw bits from a varlena; in particular, if the goal is to identify
* a compression method, use the constants TOAST_PGLZ_COMPRESSION, etc.
* below. We might someday support more than 4 compression methods, but
* we can never have more than 4 values in this enum, because there are
- * only 2 bits available in the places where this is us ed.
+ * only 2 bits available in the places where this is stor ed.
*/
typedef enum ToastCompressionId
{
} ToastCompressionId;
/*
- * Built-in compression methods. pg_attribute will store this in the
- * attcompression column.
+ * Built-in compression methods. pg_attribute will store these in the
+ * attcompression column. In attcompression, InvalidCompressionMethod
+ * denotes the default behavior.
*/
#define TOAST_PGLZ_COMPRESSION 'p'
#define TOAST_LZ4_COMPRESSION 'l'
#define CompressionMethodIsValid(cm) ((cm) != InvalidCompressionMethod)
-#define IsStorageCompressible(storage) ((storage) != TYPSTORAGE_PLAIN && \
- (storage) != TYPSTORAGE_EXTERNAL)
-
-/*
- * GetDefaultToastCompression -- get the default toast compression method
- *
- * This exists to hide the use of the default_toast_compression GUC variable.
- */
-static inline char
-GetDefaultToastCompression(void)
-{
- return (char) default_toast_compression;
-}
/* pglz compression/decompression routines */
extern struct varlena *pglz_compress_datum(const struct varlena *value);
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 20210523 1
+#define CATALOG_VERSION_NO 20210527 1
#endif
char attstorage;
/*
- * Compression method. Must be InvalidCompressionMethod if and only if
- * typstorage is 'plain' or 'external'.
+ * attcompression sets the current compression method of the attribute.
+ * Typically this is InvalidCompressionMethod ('\0') to specify use of the
+ * current default setting (see default_toast_compression). Otherwise,
+ * 'p' selects pglz compression, while 'l' selects LZ4 compression.
+ * However, this field is ignored whenever attstorage does not allow
+ * compression.
*/
char attcompression BKI_DEFAULT('\0');
Table "public.cmmove1"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | text | | | | extended | pglz | |
+ f1 | text | | | | extended | | |
SELECT pg_column_compression(f1) FROM cmmove1;
pg_column_compression
Table "public.cmdata2"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+-------------------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | character varying | | | | extended | pglz | |
+ f1 | character varying | | | | extended | | |
ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer;
\d+ cmdata2
--changing column storage should not impact the compression method
--but the data should not be compressed
ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar;
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz;
\d+ cmdata2
Table "public.cmdata2"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
(1 row)
-- test compression with materialized view
-CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
-\d+ mv
- Materialized view "public. mv"
+CREATE MATERIALIZED VIEW compress mv(x) AS SELECT * FROM cmdata1;
+\d+ compress mv
+ Materialized view "public.compress mv"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+------+-----------+----------+---------+----------+-------------+--------------+-------------
- x | text | | | | extended | pglz | |
+ x | text | | | | extended | | |
View definition:
SELECT cmdata1.f1 AS x
FROM cmdata1;
lz4
(2 rows)
-SELECT pg_column_compression(x) FROM mv;
+SELECT pg_column_compression(x) FROM compress mv;
pg_column_compression
-----------------------
lz4
pglz
(1 row)
--- test compression with inherite nce, error
+-- test compression with inherita nce, error
CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
NOTICE: merging multiple inherited definitions of column "f1"
ERROR: column "f1" has a compression method conflict
ERROR: invalid value for parameter "default_toast_compression": "I do not exist compression"
HINT: Available values: pglz, lz4.
SET default_toast_compression = 'lz4';
-DROP TABLE cmdata2;
-CREATE TABLE cmdata2 (f1 text);
-\d+ cmdata2
- Table "public.cmdata2"
- Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
---------+------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | text | | | | extended | lz4 | |
-
SET default_toast_compression = 'pglz';
-- test alter compression method
ALTER TABLE cmdata ALTER COLUMN f1 SET COMPRESSION lz4;
lz4
(2 rows)
--- test alter compression method for the materialized view
-ALTER MATERIALIZED VIEW mv ALTER COLUMN x SET COMPRESSION lz4;
-\d+ mv
- Materialized view "public.mv"
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default;
+\d+ cmdata2
+ Table "public.cmdata2"
+ Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
+--------+-------------------+-----------+----------+---------+---------+-------------+--------------+-------------
+ f1 | character varying | | | | plain | | |
+
+-- test alter compression method for materialized views
+ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4;
+\d+ compressmv
+ Materialized view "public.compressmv"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+------+-----------+----------+---------+----------+-------------+--------------+-------------
x | text | | | | extended | lz4 | |
SELECT cmdata1.f1 AS x
FROM cmdata1;
--- test alter compression method for the partitioned table
+-- test alter compression method for partitioned tables
ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz;
ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4;
-- new data should be compressed with the current compression method
Table "public.cmmove1"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | text | | | | extended | pglz | |
+ f1 | text | | | | extended | | |
SELECT pg_column_compression(f1) FROM cmmove1;
pg_column_compression
Table "public.cmdata2"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+-------------------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | character varying | | | | extended | pglz | |
+ f1 | character varying | | | | extended | | |
ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer;
\d+ cmdata2
--changing column storage should not impact the compression method
--but the data should not be compressed
ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar;
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz;
\d+ cmdata2
Table "public.cmdata2"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
(1 row)
-- test compression with materialized view
-CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+CREATE MATERIALIZED VIEW compress mv(x) AS SELECT * FROM cmdata1;
ERROR: relation "cmdata1" does not exist
-LINE 1: CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
- ^
-\d+ mv
+LINE 1: ...TE MATERIALIZED VIEW compress mv(x) AS SELECT * FROM cmdata1;
+ ^
+\d+ compress mv
SELECT pg_column_compression(f1) FROM cmdata1;
ERROR: relation "cmdata1" does not exist
LINE 1: SELECT pg_column_compression(f1) FROM cmdata1;
^
-SELECT pg_column_compression(x) FROM mv;
-ERROR: relation "mv" does not exist
-LINE 1: SELECT pg_column_compression(x) FROM mv;
+SELECT pg_column_compression(x) FROM compress mv;
+ERROR: relation "compress mv" does not exist
+LINE 1: SELECT pg_column_compression(x) FROM compress mv;
^
-- test compression with partition
CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
-----------------------
(0 rows)
--- test compression with inherite nce, error
+-- test compression with inherita nce, error
CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
ERROR: relation "cmdata1" does not exist
CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
SET default_toast_compression = 'lz4';
ERROR: invalid value for parameter "default_toast_compression": "lz4"
HINT: Available values: pglz.
-DROP TABLE cmdata2;
-CREATE TABLE cmdata2 (f1 text);
-\d+ cmdata2
- Table "public.cmdata2"
- Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
---------+------+-----------+----------+---------+----------+-------------+--------------+-------------
- f1 | text | | | | extended | pglz | |
-
SET default_toast_compression = 'pglz';
-- test alter compression method
ALTER TABLE cmdata ALTER COLUMN f1 SET COMPRESSION lz4;
pglz
(2 rows)
--- test alter compression method for the materialized view
-ALTER MATERIALIZED VIEW mv ALTER COLUMN x SET COMPRESSION lz4;
-ERROR: relation "mv" does not exist
-\d+ mv
--- test alter compression method for the partitioned table
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default;
+\d+ cmdata2
+ Table "public.cmdata2"
+ Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
+--------+-------------------+-----------+----------+---------+---------+-------------+--------------+-------------
+ f1 | character varying | | | | plain | | |
+
+-- test alter compression method for materialized views
+ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4;
+ERROR: relation "compressmv" does not exist
+\d+ compressmv
+-- test alter compression method for partitioned tables
ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz;
ERROR: relation "cmpart1" does not exist
ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4;
--changing column storage should not impact the compression method
--but the data should not be compressed
ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar;
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz;
\d+ cmdata2
ALTER TABLE cmdata2 ALTER COLUMN f1 SET STORAGE plain;
\d+ cmdata2
SELECT pg_column_compression(f1) FROM cmdata2;
-- test compression with materialized view
-CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
-\d+ mv
+CREATE MATERIALIZED VIEW compress mv(x) AS SELECT * FROM cmdata1;
+\d+ compress mv
SELECT pg_column_compression(f1) FROM cmdata1;
-SELECT pg_column_compression(x) FROM mv;
+SELECT pg_column_compression(x) FROM compress mv;
-- test compression with partition
CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
SELECT pg_column_compression(f1) FROM cmpart1;
SELECT pg_column_compression(f1) FROM cmpart2;
--- test compression with inherite nce, error
+-- test compression with inherita nce, error
CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
SET default_toast_compression = '';
SET default_toast_compression = 'I do not exist compression';
SET default_toast_compression = 'lz4';
-DROP TABLE cmdata2;
-CREATE TABLE cmdata2 (f1 text);
-\d+ cmdata2
SET default_toast_compression = 'pglz';
-- test alter compression method
\d+ cmdata
SELECT pg_column_compression(f1) FROM cmdata;
--- test alter compression method for the materialized view
-ALTER MATERIALIZED VIEW mv ALTER COLUMN x SET COMPRESSION lz4;
-\d+ mv
+ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default;
+\d+ cmdata2
+
+-- test alter compression method for materialized views
+ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4;
+\d+ compressmv
--- test alter compression method for the partitioned table
+-- test alter compression method for partitioned tables
ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz;
ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4;