Rethink definition of pg_attribute.attcompression.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 May 2021 17:24:24 +0000 (13:24 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 May 2021 17:24:27 +0000 (13:24 -0400)
Redefine '\0' (InvalidCompressionMethod) as meaning "if we need to
compress, use the current setting of default_toast_compression".
This allows '\0' to be a suitable default choice regardless of
datatype, greatly simplifying code paths that initialize tupledescs
and the like.  It seems like a more user-friendly approach as well,
because now the default compression choice doesn't migrate into table
definitions, meaning that changing default_toast_compression is
usually sufficient to flip an installation's behavior; one needn't
tediously issue per-column ALTER SET COMPRESSION commands.

Along the way, fix a few minor bugs and documentation issues
with the per-column-compression feature.  Adopt more robust
APIs for SetIndexStorageProperties and GetAttributeCompression.

Bump catversion because typical contents of attcompression will now
be different.  We could get away without doing that, but it seems
better to ensure v14 installations all agree on this.  (We already
forced initdb for beta2, anyway.)

Discussion: https://postgr.es/m/626613.1621787110@sss.pgh.pa.us

29 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/config.sgml
doc/src/sgml/func.sgml
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/create_table.sgml
doc/src/sgml/ref/pg_dump.sgml
doc/src/sgml/ref/pg_dumpall.sgml
doc/src/sgml/storage.sgml
src/backend/access/brin/brin_tuple.c
src/backend/access/common/indextuple.c
src/backend/access/common/toast_internals.c
src/backend/access/common/tupdesc.c
src/backend/access/heap/heapam_handler.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/genbki.pl
src/backend/catalog/heap.c
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/utils/misc/guc.c
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.c
src/bin/psql/describe.c
src/include/access/toast_compression.h
src/include/catalog/catversion.h
src/include/catalog/pg_attribute.h
src/test/regress/expected/compression.out
src/test/regress/expected/compression_1.out
src/test/regress/sql/compression.sql

index b26b872a06cf54dd555c8cc3e92cda6574e9a613..16493209c6387749c6a230a1f1a338c11be3a3e0 100644 (file)
        <structfield>attcompression</structfield> <type>char</type>
       </para>
       <para>
-       The current compression method of the column.  If it is an invalid
-       compression method (<literal>'\0'</literal>) then column data will not
-       be compressed.  Otherwise, <literal>'p'</literal> = pglz compression or
-       <literal>'l'</literal> = <productname>LZ4</productname> compression.
+       The current compression method of the column.  Typically this is
+       <literal>'\0'</literal> to specify use of the current default setting
+       (see <xref linkend="guc-default-toast-compression"/>).  Otherwise,
+       <literal>'p'</literal> selects pglz compression, while
+       <literal>'l'</literal> selects <productname>LZ4</productname>
+       compression.  However, this field is ignored
+       whenever <structfield>attstorage</structfield> does not allow
+       compression.
       </para></entry>
      </row>
 
index 67a0e997bb263027c930e125c83fdf74717f7f97..3b7da468b7cc2ac7d196d3ed067d1bc510e443b8 100644 (file)
@@ -8256,13 +8256,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
        <para>
         This variable sets the default
         <link linkend="storage-toast">TOAST</link>
-        compression method for columns of newly-created tables. The
-        <command>CREATE TABLE</command> statement can override this default
-        by specifying the <literal>COMPRESSION</literal> column option.
-
-        The supported compression methods are <literal>pglz</literal> and,
-        if <productname>PostgreSQL</productname> was compiled with
-        <literal>--with-lz4</literal>, <literal>lz4</literal>.
+        compression method for values of compressible columns.
+        (This can be overridden for individual columns by setting
+        the <literal>COMPRESSION</literal> column option in
+        <command>CREATE TABLE</command> or
+        <command>ALTER TABLE</command>.)
+        The supported compression methods are <literal>pglz</literal> and
+        (if <productname>PostgreSQL</productname> was compiled with
+        <option>--with-lz4</option>) <literal>lz4</literal>.
         The default is <literal>pglz</literal>.
        </para>
       </listitem>
index 3a21129021adae0b3396c3be72d374b9966fd985..08b07f561efa3c33743183d9908cd3e7d8db33a9 100644 (file)
@@ -26253,10 +26253,10 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
          <primary>pg_column_compression</primary>
         </indexterm>
         <function>pg_column_compression</function> ( <type>"any"</type> )
-        <returnvalue>integer</returnvalue>
+        <returnvalue>text</returnvalue>
        </para>
        <para>
-        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 <literal>NULL</literal>
         if the value is not compressed.
        </para></entry>
index 1431d2649befe038a35963f6efd5cab382554952..939d3fe273923912ab5b027a61d6f16d92c582fe 100644 (file)
@@ -104,7 +104,6 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
   GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] |
   UNIQUE <replaceable class="parameter">index_parameters</replaceable> |
   PRIMARY KEY <replaceable class="parameter">index_parameters</replaceable> |
-  COMPRESSION <replaceable class="parameter">compression_method</replaceable> |
   REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
     [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
 [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
@@ -391,24 +390,27 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     </term>
     <listitem>
      <para>
-      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
       <command>VACUUM FULL</command> or <command>CLUSTER</command>, or restored
-      with <application>pg_restore</application>, then all tuples are rewritten
-      with the configured compression methods.
-
-      Also, note that when data is inserted from another relation (for example,
-      by <command>INSERT ... SELECT</command>), 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 <application>pg_restore</application>, then all values are rewritten
+      with the configured compression method.
+      However, when data is inserted from another relation (for example,
+      by <command>INSERT ... SELECT</command>), 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 <literal>pglz</literal> and <literal>lz4</literal>.
-      <literal>lz4</literal> is available only if <literal>--with-lz4</literal>
-      was used when building <productname>PostgreSQL</productname>.
+      (<literal>lz4</literal> is available only if <option>--with-lz4</option>
+      was used when building <productname>PostgreSQL</productname>.)  In
+      addition, <replaceable class="parameter">compression_method</replaceable>
+      can be <literal>default</literal>, which selects the default behavior of
+      consulting the <xref linkend="guc-default-toast-compression"/> setting
+      at the time of data insertion to determine the method to use.
      </para>
     </listitem>
    </varlistentry>
index a8c5e4028af0e3235367b56993bb9a19e1205c1e..c6d0a35e5066aa01214c83315b433b17ea616388 100644 (file)
@@ -22,7 +22,7 @@ PostgreSQL documentation
  <refsynopsisdiv>
 <synopsis>
 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable> ( [
-  { <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable>collation</replaceable> ] [ COMPRESSION <replaceable>compression_method</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+  { <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COMPRESSION <replaceable>compression_method</replaceable> ] [ COLLATE <replaceable>collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
     | <replaceable>table_constraint</replaceable>
     | LIKE <replaceable>source_table</replaceable> [ <replaceable>like_option</replaceable> ... ] }
     [, ... ]
@@ -293,17 +293,22 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     <listitem>
      <para>
       The <literal>COMPRESSION</literal> 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 <xref linkend="sql-altertable"/> 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 <literal>main</literal> or <literal>extended</literal>.
+      (See <xref linkend="sql-altertable"/> 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 <literal>pglz</literal> and
-      <literal>lz4</literal>.  <literal>lz4</literal> is available only if
-      <literal>--with-lz4</literal> was used when building
-      <productname>PostgreSQL</productname>. The default
-      is <literal>pglz</literal>.
+      <literal>lz4</literal>.  (<literal>lz4</literal> is available only if
+      <option>--with-lz4</option> was used when building
+      <productname>PostgreSQL</productname>.)  In addition,
+      <replaceable class="parameter">compression_method</replaceable>
+      can be <literal>default</literal> to explicitly specify the default
+      behavior, which is to consult the
+      <xref linkend="guc-default-toast-compression"/> setting at the time of
+      data insertion to determine the method to use.
      </para>
     </listitem>
    </varlistentry>
index 67c2cbbec62e2307f8ec46a9968c728406b2d1fe..5ddadc11f2eee15d92d766efbe0454d05826b122 100644 (file)
@@ -975,8 +975,8 @@ PostgreSQL documentation
        <para>
         Do not output commands to set <acronym>TOAST</acronym> 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.
        </para>
       </listitem>
      </varlistentry>
index 805c47d5c1e56a9a62a5afe68cfc573fc70aff8b..ddffbf85edbc0318f370753a9a79364da5d772f8 100644 (file)
@@ -464,12 +464,12 @@ PostgreSQL documentation
        <para>
         Do not output commands to set <acronym>TOAST</acronym> 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.
        </para>
       </listitem>
      </varlistentry>
-     
+
      <varlistentry>
       <term><option>--no-unlogged-table-data</option></term>
       <listitem>
index bfccda77afde496229e075e3e7012f3d55d25715..7136bbe7a32fde278f0afc3bae5e8a58ee1f0c5b 100644 (file)
@@ -376,6 +376,16 @@ but the varlena header does not tell whether it has occurred &mdash;
 the content of the <acronym>TOAST</acronym> pointer tells that, instead.
 </para>
 
+<para>
+The compression technique used for either in-line or out-of-line compressed
+data can be selected for each column by setting
+the <literal>COMPRESSION</literal> column option in <command>CREATE
+TABLE</command> or <command>ALTER TABLE</command>.  The default for columns
+with no explicit setting is to consult the
+<xref linkend="guc-default-toast-compression"/> parameter at the time data is
+inserted.
+</para>
+
 <para>
 As mentioned, there are multiple types of <acronym>TOAST</acronym> pointer datums.
 The oldest and most common type is a pointer to out-of-line data stored in
@@ -392,13 +402,6 @@ useful for avoiding copying and redundant processing of large data values.
 Further details appear in <xref linkend="storage-toast-inmemory"/>.
 </para>
 
-<para>
-The compression technique used for either in-line or out-of-line compressed
-data can be selected using the <literal>COMPRESSION</literal> option on a per-column
-basis when creating a table. The default for columns with no explicit setting
-is taken from the value of <xref linkend="guc-default-toast-compression" />.
-</para>
-
 <sect2 id="storage-toast-ondisk">
  <title>Out-of-Line, On-Disk TOAST Storage</title>
 
index ee05372f795c4182c8da570efc9a718b46c849ca..09e563b1f0828d733ea9ae219601136c50e9233d 100644 (file)
@@ -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);
 
index 521256041135bc3c80d478fa5e4cdcbbdc84a38f..8df882da7a7802b88bd7fa2f9a49b95a6c10ed34 100644 (file)
@@ -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)
            {
index 8d2a9964c3f5724ce5a78737ebe9e2b5fa2632de..c7b9ade5742a4b23c12330da9294a0ec9a1e971d 100644 (file)
@@ -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.
     */
index affbc509bdc681b3294f46762962984b40be79cd..4c63bd4dc641f276456c5ebb1a49e53f8411ecb3 100644 (file)
@@ -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;
 
index 8e6e8d51698063cd765b2de6c718ae5ab23bfdb7..e2cd79ec5463772081ff67e1b4485beb78514508 100644 (file)
@@ -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;
index 62abd008ccf0065c55a5a207d498440684d0ad8c..94ab5ca0954831412c8ee5dbcb52177951e27a75 100644 (file)
@@ -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
index 112b3affdfd750ccb78e724d16bfbe927cfe57b0..f893ae4f4532885d96369b7812371d146c512147 100644 (file)
@@ -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';
index 3dfe2e8a565e2f963476676cd1ff617d6410477c..afa830d92485a6662bce33d2e5b32ba2c8a1d049 100644 (file)
@@ -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
         */
index 11e91c4ad33f36a7c5313855451904f85ea135c0..028e8ac46b33516ed75a974777e4078aa40db18b 100644 (file)
@@ -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))
index aaf1a51f685ae8a8b9977a07bd267b202cbe76e3..9ee90e3f13a40d786e8a925ef7602f85a1d66bb2 100644 (file)
@@ -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); }
index ee731044b63951b52b7d0e68e36f0e72857cffd5..87bc68870469c83b520f0a0448a4e8330ee6a986 100644 (file)
@@ -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
    },
 
    {
index fc054af5ba18ce53c6bbf63e47be6c2d77a2f524..3c1cd858a8580d64535eb521322cc42e5eabb74b 100644 (file)
@@ -208,8 +208,6 @@ typedef struct Archive
 
    /* 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 */
index 86de26a4bf0ce884899d9283d6825f36803efd78..6b046e7734d330389cb6db1fdba64b6cc3f8ce97 100644 (file)
@@ -86,7 +86,6 @@ static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam);
 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);
@@ -2638,8 +2637,6 @@ ReadToc(ArchiveHandle *AH)
            processStdStringsEntry(AH, te);
        else if (strcmp(te->desc, "SEARCHPATH") == 0)
            processSearchPathEntry(AH, te);
-       else if (strcmp(te->desc, "TOASTCOMPRESSION") == 0)
-           processToastCompressionEntry(AH, te);
    }
 }
 
@@ -2697,29 +2694,6 @@ processSearchPathEntry(ArchiveHandle *AH, TocEntry *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)
 {
@@ -2779,8 +2753,7 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
    /* 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;
 
    /*
@@ -3103,11 +3076,6 @@ _doSetFixedOutputState(ArchiveHandle *AH)
    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");
 
index 339c3937180f9cdcb9a89fcb7b6926ecc3974686..8f53cc7c3b87132ef271c2304bbe65fe24a74938 100644 (file)
@@ -276,7 +276,6 @@ static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
 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,
@@ -925,13 +924,11 @@ main(int argc, char **argv)
     */
 
    /*
-    * 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)
@@ -3398,58 +3395,6 @@ dumpSearchPath(Archive *AH)
    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:
@@ -16399,29 +16344,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
            }
 
            /*
-            * 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)
            {
@@ -16440,14 +16363,34 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
                        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)
index 3e39fdb54529725853b791016b21e381ec6f8ba4..195f8d8cd2d32e406f82ab6b3002217d45d86b2a 100644 (file)
@@ -1636,9 +1636,9 @@ describeOneTableDetails(const char *schemaname,
                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
    {
@@ -2055,7 +2055,7 @@ describeOneTableDetails(const char *schemaname,
        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 ||
@@ -2259,7 +2259,7 @@ describeOneTableDetails(const char *schemaname,
        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);
@@ -2273,7 +2273,7 @@ describeOneTableDetails(const char *schemaname,
                              false, false);
        }
 
-       /* Column compression. */
+       /* Column compression, if relevant */
        if (attcompression_col >= 0)
        {
            char       *compression = PQgetvalue(res, i, attcompression_col);
index 9e2c1cbe1a68eb683b6234f47bac207be010458a..c992ece4c4accdc742ca21682515127412f92be9 100644 (file)
 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 used.
+ * only 2 bits available in the places where this is stored.
  */
 typedef enum ToastCompressionId
 {
@@ -42,8 +42,9 @@ 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'
@@ -51,19 +52,6 @@ typedef enum ToastCompressionId
 
 #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);
index 958f12e66a14e3b5e285e2f3ae9bf6a61efe210e..9fe49fa2911d6841906650ed35aa4fe90320e428 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202105231
+#define CATALOG_VERSION_NO 202105271
 
 #endif
index 1e260162146167931513e928d7f16cb949f9d247..603392fe81b044924dca618cf51f708e01e6d36c 100644 (file)
@@ -126,8 +126,12 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
    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');
 
index 61e97cb33cec347e8e83a78cee3174b9eeac9b6a..5c645e46500b7c7ef713c54e0a68ab8eac8d972a 100644 (file)
@@ -53,7 +53,7 @@ SELECT * INTO cmmove1 FROM cmdata;
                                         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 
@@ -146,7 +146,7 @@ ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar;
                                               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
@@ -158,6 +158,7 @@ ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer;
 --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 
@@ -179,12 +180,12 @@ SELECT pg_column_compression(f1) FROM cmdata2;
 (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 compressmv(x) AS SELECT * FROM cmdata1;
+\d+ compressmv
+                                Materialized view "public.compressmv"
  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;
@@ -196,7 +197,7 @@ SELECT pg_column_compression(f1) FROM cmdata1;
  lz4
 (2 rows)
 
-SELECT pg_column_compression(x) FROM mv;
+SELECT pg_column_compression(x) FROM compressmv;
  pg_column_compression 
 -----------------------
  lz4
@@ -222,7 +223,7 @@ SELECT pg_column_compression(f1) FROM cmpart2;
  pglz
 (1 row)
 
--- test compression with inheritence, error
+-- test compression with inheritance, error
 CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
 NOTICE:  merging multiple inherited definitions of column "f1"
 ERROR:  column "f1" has a compression method conflict
@@ -239,14 +240,6 @@ SET default_toast_compression = 'I do not exist compression';
 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;
@@ -266,10 +259,17 @@ SELECT pg_column_compression(f1) FROM cmdata;
  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         |              | 
@@ -277,7 +277,7 @@ View definition:
  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
index d03d6255ae378b5b94b548f49290403500ef6250..aac96037fcf860f19f8f8c0a95fdd7480aa3b890 100644 (file)
@@ -50,7 +50,7 @@ SELECT * INTO cmmove1 FROM cmdata;
                                         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 
@@ -144,7 +144,7 @@ ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar;
                                               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
@@ -156,6 +156,7 @@ ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer;
 --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 
@@ -177,18 +178,18 @@ SELECT pg_column_compression(f1) FROM cmdata2;
 (1 row)
 
 -- test compression with materialized view
-CREATE MATERIALIZED VIEW mv(x) AS SELECT * FROM cmdata1;
+CREATE MATERIALIZED VIEW compressmv(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 compressmv(x) AS SELECT * FROM cmdata1;
+                                                               ^
+\d+ compressmv
 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 compressmv;
+ERROR:  relation "compressmv" does not exist
+LINE 1: SELECT pg_column_compression(x) FROM compressmv;
                                              ^
 -- test compression with partition
 CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
@@ -217,7 +218,7 @@ SELECT pg_column_compression(f1) FROM cmpart2;
 -----------------------
 (0 rows)
 
--- test compression with inheritence, error
+-- test compression with inheritance, error
 CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
 ERROR:  relation "cmdata1" does not exist
 CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
@@ -234,14 +235,6 @@ HINT:  Available values: pglz.
 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;
@@ -264,11 +257,18 @@ SELECT pg_column_compression(f1) FROM cmdata;
  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;
index 76d1776d832988027cd453322d20bfd74ddcdcb3..35557c1f7de11e4f30c81d0b0079f5031edde981 100644 (file)
@@ -69,6 +69,7 @@ ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer;
 --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
@@ -76,10 +77,10 @@ INSERT INTO cmdata2 VALUES (repeat('123456789', 800));
 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 compressmv(x) AS SELECT * FROM cmdata1;
+\d+ compressmv
 SELECT pg_column_compression(f1) FROM cmdata1;
-SELECT pg_column_compression(x) FROM mv;
+SELECT pg_column_compression(x) FROM compressmv;
 
 -- test compression with partition
 CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1);
@@ -92,7 +93,7 @@ INSERT INTO cmpart VALUES (repeat('123456789', 4004));
 SELECT pg_column_compression(f1) FROM cmpart1;
 SELECT pg_column_compression(f1) FROM cmpart2;
 
--- test compression with inheritence, error
+-- test compression with inheritance, error
 CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
 CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
 
@@ -100,9 +101,6 @@ 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
@@ -111,11 +109,14 @@ INSERT INTO cmdata VALUES (repeat('123456789', 4004));
 \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;