Add relallfrozen to pg_class
authorMelanie Plageman <[email protected]>
Mon, 3 Mar 2025 16:18:05 +0000 (11:18 -0500)
committerMelanie Plageman <[email protected]>
Mon, 3 Mar 2025 16:18:05 +0000 (11:18 -0500)
Add relallfrozen, an estimate of the number of pages marked all-frozen
in the visibility map.

pg_class already has relallvisible, an estimate of the number of pages
in the relation marked all-visible in the visibility map. This is used
primarily for planning.

relallfrozen, together with relallvisible, is useful for estimating the
outstanding number of all-visible but not all-frozen pages in the
relation for the purposes of scheduling manual VACUUMs and tuning vacuum
freeze parameters.

A future commit will use relallfrozen to trigger more frequent vacuums
on insert-focused workloads with significant volume of frozen data.

Bump catalog version

Author: Melanie Plageman <[email protected]>
Reviewed-by: Nathan Bossart <[email protected]>
Reviewed-by: Robert Treat <[email protected]>
Reviewed-by: Corey Huinker <[email protected]>
Reviewed-by: Greg Sabino Mullane <[email protected]>
Discussion: https://postgr.es/m/flat/CAAKRu_aj-P7YyBz_cPNwztz6ohP%2BvWis%3Diz3YcomkB3NpYA--w%40mail.gmail.com

14 files changed:
doc/src/sgml/catalogs.sgml
src/backend/access/heap/vacuumlazy.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/analyze.c
src/backend/commands/cluster.c
src/backend/commands/vacuum.c
src/backend/statistics/relation_stats.c
src/backend/utils/cache/relcache.c
src/include/catalog/catversion.h
src/include/catalog/pg_class.h
src/include/commands/vacuum.h
src/test/regress/expected/stats_import.out
src/test/regress/sql/stats_import.sql

index ee59a7e15d0656d899b90f20443f6173fb439928..9a21a0d6f157c9277732fa25b8ffa21e6cdf0a73 100644 (file)
@@ -2066,6 +2066,26 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>relallfrozen</structfield> <type>int4</type>
+      </para>
+      <para>
+       Number of pages that are marked all-frozen in the table's visibility
+       map.  This is only an estimate and can be used along with
+       <structfield>relallvisible</structfield> for scheduling vacuums and
+       tuning <link linkend="runtime-config-vacuum-freezing">vacuum's freezing
+       behavior</link>.
+
+       It is updated by
+       <link linkend="sql-vacuum"><command>VACUUM</command></link>,
+       <link linkend="sql-analyze"><command>ANALYZE</command></link>,
+       and a few DDL commands such as
+       <link linkend="sql-createindex"><command>CREATE INDEX</command></link>.
+      </para></entry>
+     </row>
+
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>reltoastrelid</structfield> <type>oid</type>
index 1af18a78a2b1dd862d16145a7666ad29417a8477..3b91d02605a00eec91dffc4741e68ddcb8cf104e 100644 (file)
@@ -623,7 +623,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
                minmulti_updated;
    BlockNumber orig_rel_pages,
                new_rel_pages,
-               new_rel_allvisible;
+               new_rel_allvisible,
+               new_rel_allfrozen;
    PGRUsage    ru0;
    TimestampTz starttime = 0;
    PgStat_Counter startreadtime = 0,
@@ -898,10 +899,18 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
     * pg_class.relpages to
     */
    new_rel_pages = vacrel->rel_pages;  /* After possible rel truncation */
-   visibilitymap_count(rel, &new_rel_allvisible, NULL);
+   visibilitymap_count(rel, &new_rel_allvisible, &new_rel_allfrozen);
    if (new_rel_allvisible > new_rel_pages)
        new_rel_allvisible = new_rel_pages;
 
+   /*
+    * An all-frozen block _must_ be all-visible. As such, clamp the count of
+    * all-frozen blocks to the count of all-visible blocks. This matches the
+    * clamping of relallvisible above.
+    */
+   if (new_rel_allfrozen > new_rel_allvisible)
+       new_rel_allfrozen = new_rel_allvisible;
+
    /*
     * Now actually update rel's pg_class entry.
     *
@@ -910,7 +919,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
     * scan every page that isn't skipped using the visibility map.
     */
    vac_update_relstats(rel, new_rel_pages, vacrel->new_live_tuples,
-                       new_rel_allvisible, vacrel->nindexes > 0,
+                       new_rel_allvisible, new_rel_allfrozen,
+                       vacrel->nindexes > 0,
                        vacrel->NewRelfrozenXid, vacrel->NewRelminMxid,
                        &frozenxid_updated, &minmulti_updated, false);
 
@@ -3720,7 +3730,7 @@ update_relstats_all_indexes(LVRelState *vacrel)
        vac_update_relstats(indrel,
                            istat->num_pages,
                            istat->num_index_tuples,
-                           0,
+                           0, 0,
                            false,
                            InvalidTransactionId,
                            InvalidMultiXactId,
index 956f196fc95c3317df8ffc7dcc91a4a94b6e9ecd..7ef6f0f1cbafd4d4401c29d84efd9ab4f44318c2 100644 (file)
@@ -924,6 +924,7 @@ InsertPgClassTuple(Relation pg_class_desc,
    values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
    values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
    values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
+   values[Anum_pg_class_relallfrozen - 1] = Int32GetDatum(rd_rel->relallfrozen);
    values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
    values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
    values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
@@ -994,6 +995,7 @@ AddNewRelationTuple(Relation pg_class_desc,
    new_rel_reltup->relpages = 0;
    new_rel_reltup->reltuples = -1;
    new_rel_reltup->relallvisible = 0;
+   new_rel_reltup->relallfrozen = 0;
 
    /* Sequences always have a known size */
    if (relkind == RELKIND_SEQUENCE)
index f37b990c81d911b5678d3b74072d8af9b5813ce7..8e1741c81f5b308106d169a8476ba641c3b8a7f2 100644 (file)
@@ -2793,8 +2793,8 @@ FormIndexDatum(IndexInfo *indexInfo,
  * hasindex: set relhasindex to this value
  * reltuples: if >= 0, set reltuples to this value; else no change
  *
- * If reltuples >= 0, relpages and relallvisible are also updated (using
- * RelationGetNumberOfBlocks() and visibilitymap_count()).
+ * If reltuples >= 0, relpages, relallvisible, and relallfrozen are also
+ * updated (using RelationGetNumberOfBlocks() and visibilitymap_count()).
  *
  * NOTE: an important side-effect of this operation is that an SI invalidation
  * message is sent out to all backends --- including me --- causing relcache
@@ -2812,6 +2812,7 @@ index_update_stats(Relation rel,
    bool        update_stats;
    BlockNumber relpages = 0;   /* keep compiler quiet */
    BlockNumber relallvisible = 0;
+   BlockNumber relallfrozen = 0;
    Oid         relid = RelationGetRelid(rel);
    Relation    pg_class;
    ScanKeyData key[1];
@@ -2851,7 +2852,7 @@ index_update_stats(Relation rel,
        relpages = RelationGetNumberOfBlocks(rel);
 
        if (rel->rd_rel->relkind != RELKIND_INDEX)
-           visibilitymap_count(rel, &relallvisible, NULL);
+           visibilitymap_count(rel, &relallvisible, &relallfrozen);
    }
 
    /*
@@ -2924,6 +2925,11 @@ index_update_stats(Relation rel,
            rd_rel->relallvisible = (int32) relallvisible;
            dirty = true;
        }
+       if (rd_rel->relallfrozen != (int32) relallfrozen)
+       {
+           rd_rel->relallfrozen = (int32) relallfrozen;
+           dirty = true;
+       }
    }
 
    /*
index cd75954951b91ae9d51d8d8004559aa149ef1cc7..2b5fbdcbd82b228d2a27102ad0f73e733668d771 100644 (file)
@@ -630,12 +630,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
     */
    if (!inh)
    {
-       BlockNumber relallvisible;
+       BlockNumber relallvisible = 0;
+       BlockNumber relallfrozen = 0;
 
        if (RELKIND_HAS_STORAGE(onerel->rd_rel->relkind))
-           visibilitymap_count(onerel, &relallvisible, NULL);
-       else
-           relallvisible = 0;
+           visibilitymap_count(onerel, &relallvisible, &relallfrozen);
 
        /*
         * Update pg_class for table relation.  CCI first, in case acquirefunc
@@ -646,6 +645,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
                            relpages,
                            totalrows,
                            relallvisible,
+                           relallfrozen,
                            hasindex,
                            InvalidTransactionId,
                            InvalidMultiXactId,
@@ -662,7 +662,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
            vac_update_relstats(Irel[ind],
                                RelationGetNumberOfBlocks(Irel[ind]),
                                totalindexrows,
-                               0,
+                               0, 0,
                                false,
                                InvalidTransactionId,
                                InvalidMultiXactId,
@@ -678,7 +678,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
         */
        CommandCounterIncrement();
        vac_update_relstats(onerel, -1, totalrows,
-                           0, hasindex, InvalidTransactionId,
+                           0, 0, hasindex, InvalidTransactionId,
                            InvalidMultiXactId,
                            NULL, NULL,
                            in_outer_xact);
index 99193f5c886dab73599ca52558e4df3779cc04a2..54a08e4102e14ec352b33340a3094951387819fd 100644 (file)
@@ -1226,6 +1226,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
        int32       swap_pages;
        float4      swap_tuples;
        int32       swap_allvisible;
+       int32       swap_allfrozen;
 
        swap_pages = relform1->relpages;
        relform1->relpages = relform2->relpages;
@@ -1238,6 +1239,10 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
        swap_allvisible = relform1->relallvisible;
        relform1->relallvisible = relform2->relallvisible;
        relform2->relallvisible = swap_allvisible;
+
+       swap_allfrozen = relform1->relallfrozen;
+       relform1->relallfrozen = relform2->relallfrozen;
+       relform2->relallfrozen = swap_allfrozen;
    }
 
    /*
index 0239d9bae6526f8ff7a7d82aca1e9a1d8f803b75..e81c9a8aba3e1e7a078200d159ae113fe2027be1 100644 (file)
@@ -1427,6 +1427,7 @@ void
 vac_update_relstats(Relation relation,
                    BlockNumber num_pages, double num_tuples,
                    BlockNumber num_all_visible_pages,
+                   BlockNumber num_all_frozen_pages,
                    bool hasindex, TransactionId frozenxid,
                    MultiXactId minmulti,
                    bool *frozenxid_updated, bool *minmulti_updated,
@@ -1476,6 +1477,11 @@ vac_update_relstats(Relation relation,
        pgcform->relallvisible = (int32) num_all_visible_pages;
        dirty = true;
    }
+   if (pgcform->relallfrozen != (int32) num_all_frozen_pages)
+   {
+       pgcform->relallfrozen = (int32) num_all_frozen_pages;
+       dirty = true;
+   }
 
    /* Apply DDL updates, but not inside an outer transaction (see above) */
 
index 11b1ef2dbc2ef12b4a6607a7aeb789cc93243f70..2c1cea3fc80f1ee3586055450616e456b4b12ccc 100644 (file)
@@ -36,6 +36,7 @@ enum relation_stats_argnum
    RELPAGES_ARG,
    RELTUPLES_ARG,
    RELALLVISIBLE_ARG,
+   RELALLFROZEN_ARG,
    NUM_RELATION_STATS_ARGS
 };
 
@@ -45,6 +46,7 @@ static struct StatsArgInfo relarginfo[] =
    [RELPAGES_ARG] = {"relpages", INT4OID},
    [RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
    [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
+   [RELALLFROZEN_ARG] = {"relallfrozen", INT4OID},
    [NUM_RELATION_STATS_ARGS] = {0}
 };
 
@@ -65,11 +67,13 @@ relation_statistics_update(FunctionCallInfo fcinfo)
    bool        update_reltuples = false;
    BlockNumber relallvisible = 0;
    bool        update_relallvisible = false;
+   BlockNumber relallfrozen = 0;
+   bool        update_relallfrozen = false;
    HeapTuple   ctup;
    Form_pg_class pgcform;
-   int         replaces[3] = {0};
-   Datum       values[3] = {0};
-   bool        nulls[3] = {0};
+   int         replaces[4] = {0};
+   Datum       values[4] = {0};
+   bool        nulls[4] = {0};
    int         nreplaces = 0;
 
    if (!PG_ARGISNULL(RELPAGES_ARG))
@@ -98,6 +102,12 @@ relation_statistics_update(FunctionCallInfo fcinfo)
        update_relallvisible = true;
    }
 
+   if (!PG_ARGISNULL(RELALLFROZEN_ARG))
+   {
+       relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG);
+       update_relallfrozen = true;
+   }
+
    stats_check_required_arg(fcinfo, relarginfo, RELATION_ARG);
    reloid = PG_GETARG_OID(RELATION_ARG);
 
@@ -148,6 +158,13 @@ relation_statistics_update(FunctionCallInfo fcinfo)
        nreplaces++;
    }
 
+   if (update_relallfrozen && relallfrozen != pgcform->relallfrozen)
+   {
+       replaces[nreplaces] = Anum_pg_class_relallfrozen;
+       values[nreplaces] = UInt32GetDatum(relallfrozen);
+       nreplaces++;
+   }
+
    if (nreplaces > 0)
    {
        TupleDesc   tupdesc = RelationGetDescr(crel);
@@ -176,9 +193,9 @@ relation_statistics_update(FunctionCallInfo fcinfo)
 Datum
 pg_clear_relation_stats(PG_FUNCTION_ARGS)
 {
-   LOCAL_FCINFO(newfcinfo, 4);
+   LOCAL_FCINFO(newfcinfo, 5);
 
-   InitFunctionCallInfoData(*newfcinfo, NULL, 4, InvalidOid, NULL, NULL);
+   InitFunctionCallInfoData(*newfcinfo, NULL, 5, InvalidOid, NULL, NULL);
 
    newfcinfo->args[0].value = PG_GETARG_OID(0);
    newfcinfo->args[0].isnull = PG_ARGISNULL(0);
@@ -188,6 +205,8 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
    newfcinfo->args[2].isnull = false;
    newfcinfo->args[3].value = UInt32GetDatum(0);
    newfcinfo->args[3].isnull = false;
+   newfcinfo->args[4].value = UInt32GetDatum(0);
+   newfcinfo->args[4].isnull = false;
 
    relation_statistics_update(newfcinfo);
    PG_RETURN_VOID();
index 398114373e9f690d224bce1a87e238cc6ab9c74e..d1ae761b3f6e39a43848be45941e7a8d60c85f7f 100644 (file)
@@ -1928,6 +1928,7 @@ formrdesc(const char *relationName, Oid relationReltype,
    relation->rd_rel->relpages = 0;
    relation->rd_rel->reltuples = -1;
    relation->rd_rel->relallvisible = 0;
+   relation->rd_rel->relallfrozen = 0;
    relation->rd_rel->relkind = RELKIND_RELATION;
    relation->rd_rel->relnatts = (int16) natts;
 
@@ -3885,6 +3886,7 @@ RelationSetNewRelfilenumber(Relation relation, char persistence)
            classform->relpages = 0;    /* it's empty until further notice */
            classform->reltuples = -1;
            classform->relallvisible = 0;
+           classform->relallfrozen = 0;
        }
        classform->relfrozenxid = freezeXid;
        classform->relminmxid = minmulti;
index 12163ae94be6a01c8ec857ef82c10ddd9afdf810..f0962e17b3384332509ad9f9ab7a93b6fee5aa45 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202502242
+#define CATALOG_VERSION_NO 202503031
 
 #endif
index f0d612ca48776bf58ed2f21c82064fc5224afd94..fa96ba07bf495e3f1a88a9e6ee84e6e7a404c575 100644 (file)
@@ -68,6 +68,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
    /* # of all-visible blocks (not always up-to-date) */
    int32       relallvisible BKI_DEFAULT(0);
 
+   /* # of all-frozen blocks (not always up-to-date) */
+   int32       relallfrozen BKI_DEFAULT(0);
+
    /* OID of toast table; 0 if none */
    Oid         reltoastrelid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
index 1571a66c6bf038d8250327157e875d1a02b0c1f0..baacc63f590969e92b11314f08846ac45029ee05 100644 (file)
@@ -349,6 +349,7 @@ extern void vac_update_relstats(Relation relation,
                                BlockNumber num_pages,
                                double num_tuples,
                                BlockNumber num_all_visible_pages,
+                               BlockNumber num_all_frozen_pages,
                                bool hasindex,
                                TransactionId frozenxid,
                                MultiXactId minmulti,
index 1f150f7b08d956d1380091e7650c2f5232d0b2c2..4df287e547f489f63103d183cba30d647ecec27d 100644 (file)
@@ -14,12 +14,12 @@ CREATE TABLE stats_import.test(
 ) WITH (autovacuum_enabled = false);
 CREATE INDEX test_i ON stats_import.test(id);
 -- starting stats
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-        0 |        -1 |             0
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+        0 |        -1 |             0 |            0
 (1 row)
 
 BEGIN;
@@ -68,12 +68,12 @@ SELECT
  
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-        0 |        -1 |             0
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+        0 |        -1 |             0 |            0
 (1 row)
 
 --  relpages may be -1 for partitioned tables
@@ -170,18 +170,19 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 2::integer);
  pg_restore_relation_stats 
 ---------------------------
  t
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-       17 |       400 |             4
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       17 |       400 |             4 |            2
 (1 row)
 
 -- ok: just relpages
@@ -194,12 +195,12 @@ SELECT pg_restore_relation_stats(
  t
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-       16 |       400 |             4
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       16 |       400 |             4 |            2
 (1 row)
 
 -- ok: just reltuples
@@ -212,12 +213,12 @@ SELECT pg_restore_relation_stats(
  t
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-       16 |       500 |             4
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       16 |       500 |             4 |            2
 (1 row)
 
 -- ok: just relallvisible
@@ -230,12 +231,30 @@ SELECT pg_restore_relation_stats(
  t
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-       16 |       500 |             5
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       16 |       500 |             5 |            2
+(1 row)
+
+-- ok: just relallfrozen
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relallfrozen', 3::integer);
+ pg_restore_relation_stats 
+---------------------------
+ t
+(1 row)
+
+SELECT relpages, reltuples, relallvisible, relallfrozen
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       16 |       500 |             5 |            3
 (1 row)
 
 -- warn: bad relpages type
@@ -244,19 +263,20 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', 'nope'::text,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 WARNING:  argument "relpages" has type "text", expected type "integer"
  pg_restore_relation_stats 
 ---------------------------
  f
 (1 row)
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible 
-----------+-----------+---------------
-       16 |       400 |             4
+ relpages | reltuples | relallvisible | relallfrozen 
+----------+-----------+---------------+--------------
+       16 |       400 |             4 |            3
 (1 row)
 
 -- invalid relkinds for statistics
@@ -992,7 +1012,8 @@ SELECT * FROM pg_catalog.pg_restore_relation_stats(
     'version', '180000'::integer,
     'relpages', '11'::integer,
     'reltuples', '10000'::real,
-    'relallvisible', '0'::integer
+    'relallvisible', '0'::integer,
+    'relallfrozen', '0'::integer
 );
  pg_restore_relation_stats 
 ---------------------------
@@ -1194,7 +1215,8 @@ SELECT pg_catalog.pg_restore_relation_stats(
         'relation', 0::oid,
         'relpages', 17::integer,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 WARNING:  argument "relation" has type "oid", expected type "regclass"
 ERROR:  "relation" cannot be NULL
 --- error: relation not found
@@ -1202,7 +1224,8 @@ SELECT pg_catalog.pg_restore_relation_stats(
         'relation', 0::regclass,
         'relpages', 17::integer,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 ERROR:  could not open relation with OID 0
 -- warn and error: unrecognized argument name
 SELECT pg_restore_relation_stats(
@@ -1219,7 +1242,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         NULL, '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 ERROR:  name at variadic position 5 is NULL
 -- error: argument name is an integer
 SELECT pg_restore_relation_stats(
@@ -1227,7 +1251,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         17, '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 ERROR:  name at variadic position 5 has type "integer", expected type "text"
 -- error: odd number of variadic arguments cannot be pairs
 SELECT pg_restore_relation_stats(
@@ -1235,6 +1260,7 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
+        'relallfrozen', 3::integer,
         'relallvisible');
 ERROR:  variadic arguments must be name/value pairs
 HINT:  Provide an even number of variadic arguments that can be divided into pairs.
@@ -1244,7 +1270,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 ERROR:  could not open relation with OID 0
 -- error: object does not exist
 SELECT pg_catalog.pg_restore_attribute_stats(
index 8c183bceb8aa0742e818f1873724b571de485374..febda3d18d9741839a033fd93ec305ecc08aa6a4 100644 (file)
@@ -18,7 +18,7 @@ CREATE TABLE stats_import.test(
 CREATE INDEX test_i ON stats_import.test(id);
 
 -- starting stats
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -49,7 +49,7 @@ SELECT
     pg_catalog.pg_clear_relation_stats(
         'stats_import.test'::regclass);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -120,9 +120,10 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 2::integer);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -132,7 +133,7 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '16'::integer);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -142,7 +143,7 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'reltuples', '500'::real);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -152,7 +153,17 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relallvisible', 5::integer);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
+FROM pg_class
+WHERE oid = 'stats_import.test'::regclass;
+
+-- ok: just relallfrozen
+SELECT pg_restore_relation_stats(
+        'relation', 'stats_import.test'::regclass,
+        'version', 150000::integer,
+        'relallfrozen', 3::integer);
+
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -162,9 +173,10 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', 'nope'::text,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
-SELECT relpages, reltuples, relallvisible
+SELECT relpages, reltuples, relallvisible, relallfrozen
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
@@ -680,7 +692,8 @@ SELECT * FROM pg_catalog.pg_restore_relation_stats(
     'version', '180000'::integer,
     'relpages', '11'::integer,
     'reltuples', '10000'::real,
-    'relallvisible', '0'::integer
+    'relallvisible', '0'::integer,
+    'relallfrozen', '0'::integer
 );
 
 -- Generate statistics on table with data
@@ -850,14 +863,16 @@ SELECT pg_catalog.pg_restore_relation_stats(
         'relation', 0::oid,
         'relpages', 17::integer,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
 --- error: relation not found
 SELECT pg_catalog.pg_restore_relation_stats(
         'relation', 0::regclass,
         'relpages', 17::integer,
         'reltuples', 400.0::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
 -- warn and error: unrecognized argument name
 SELECT pg_restore_relation_stats(
@@ -873,7 +888,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         NULL, '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
 -- error: argument name is an integer
 SELECT pg_restore_relation_stats(
@@ -881,7 +897,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         17, '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
 -- error: odd number of variadic arguments cannot be pairs
 SELECT pg_restore_relation_stats(
@@ -889,6 +906,7 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
+        'relallfrozen', 3::integer,
         'relallvisible');
 
 -- error: object doesn't exist
@@ -897,7 +915,8 @@ SELECT pg_restore_relation_stats(
         'version', 150000::integer,
         'relpages', '17'::integer,
         'reltuples', 400::real,
-        'relallvisible', 4::integer);
+        'relallvisible', 4::integer,
+        'relallfrozen', 3::integer);
 
 -- error: object does not exist
 SELECT pg_catalog.pg_restore_attribute_stats(