Allow pg_set_relation_stats() to set relpages to -1.
authorJeff Davis <[email protected]>
Fri, 18 Oct 2024 17:44:15 +0000 (10:44 -0700)
committerJeff Davis <[email protected]>
Fri, 18 Oct 2024 17:44:15 +0000 (10:44 -0700)
While the default value for relpages is 0, if a partitioned table with
at least one child has been analyzed, then the partititoned table will
have a relpages value of -1.

Author: Corey Huinker
Discussion: https://postgr.es/m/CADkLM=fajh1Lpcyr_XsMmq-9Z=SGk-u+_Zeac7Pt0RAN3uiVCg@mail.gmail.com

doc/src/sgml/func.sgml
src/backend/statistics/relation_stats.c
src/test/regress/expected/stats_import.out
src/test/regress/sql/stats_import.sql

index f8a0d76d12bf143473da2740399cd3f93fe5dc52..ad663c94d775992d66642f9e8f12e7cc622d7e6a 100644 (file)
@@ -30197,7 +30197,7 @@ DETAIL:  Make sure pg_wal_replay_wait() isn't called within a transaction with a
         </para>
         <para>
          The value of <structfield>relpages</structfield> must be greater than
-         or equal to <literal>0</literal>,
+         or equal to <literal>-1</literal>,
          <structfield>reltuples</structfield> must be greater than or equal to
          <literal>-1.0</literal>, and <structfield>relallvisible</structfield>
          must be greater than or equal to <literal>0</literal>.
index 26f15061e895ed5cf67918fd83b41ca82c439d24..1a6d1640c30a65c91db956c7bd73d5a457170f18 100644 (file)
@@ -99,11 +99,16 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
    {
        int32       relpages = PG_GETARG_INT32(RELPAGES_ARG);
 
-       if (relpages < 0)
+       /*
+        * Partitioned tables may have relpages=-1. Note: for relations with
+        * no storage, relpages=-1 is not used consistently, but must be
+        * supported here.
+        */
+       if (relpages < -1)
        {
            ereport(elevel,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                    errmsg("relpages cannot be < 0")));
+                    errmsg("relpages cannot be < -1")));
            table_close(crel, RowExclusiveLock);
            return false;
        }
index cd1b80aa43ab92b5364d6c777bb0c2ee28256daa..495e9b034856ad0e558f06db7fea50e16579adc6 100644 (file)
@@ -135,9 +135,45 @@ SELECT
         'stats_import.testview'::regclass);
 ERROR:  cannot modify statistics for relation "testview"
 DETAIL:  This operation is not supported for views.
+--  relpages may be -1 for partitioned tables
+CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
+CREATE TABLE stats_import.part_child_1
+  PARTITION OF stats_import.part_parent
+  FOR VALUES FROM (0) TO (10);
+ANALYZE stats_import.part_parent;
+SELECT relpages
+FROM pg_class
+WHERE oid = 'stats_import.part_parent'::regclass;
+ relpages 
+----------
+       -1
+(1 row)
+
+-- although partitioned tables have no storage, setting relpages to a
+-- positive value is still allowed
+SELECT
+    pg_catalog.pg_set_relation_stats(
+        relation => 'stats_import.part_parent'::regclass,
+        relpages => 2::integer);
+ pg_set_relation_stats 
+-----------------------
+ t
+(1 row)
+
+-- nothing stops us from setting it to -1
+SELECT
+    pg_catalog.pg_set_relation_stats(
+        relation => 'stats_import.part_parent'::regclass,
+        relpages => -1::integer);
+ pg_set_relation_stats 
+-----------------------
+ t
+(1 row)
+
 DROP SCHEMA stats_import CASCADE;
-NOTICE:  drop cascades to 4 other objects
+NOTICE:  drop cascades to 5 other objects
 DETAIL:  drop cascades to type stats_import.complex_type
 drop cascades to table stats_import.test
 drop cascades to sequence stats_import.testseq
 drop cascades to view stats_import.testview
+drop cascades to table stats_import.part_parent
index 3e9f6d91241cf1f514a0909ab29792ba224c8290..108b0c4558665d6416c216c1f9d1b135b26828a2 100644 (file)
@@ -95,4 +95,29 @@ SELECT
     pg_catalog.pg_clear_relation_stats(
         'stats_import.testview'::regclass);
 
+--  relpages may be -1 for partitioned tables
+CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
+CREATE TABLE stats_import.part_child_1
+  PARTITION OF stats_import.part_parent
+  FOR VALUES FROM (0) TO (10);
+
+ANALYZE stats_import.part_parent;
+
+SELECT relpages
+FROM pg_class
+WHERE oid = 'stats_import.part_parent'::regclass;
+
+-- although partitioned tables have no storage, setting relpages to a
+-- positive value is still allowed
+SELECT
+    pg_catalog.pg_set_relation_stats(
+        relation => 'stats_import.part_parent'::regclass,
+        relpages => 2::integer);
+
+-- nothing stops us from setting it to -1
+SELECT
+    pg_catalog.pg_set_relation_stats(
+        relation => 'stats_import.part_parent'::regclass,
+        relpages => -1::integer);
+
 DROP SCHEMA stats_import CASCADE;