On Fri, 2024-10-18 at 15:14 -0400, Tom Lane wrote:
> If we are going to put data into reltuples but not relpages,
> I think I agree with setting relpages to -1 to signify
> "unknown" (analogously to -1 for reltuples). Otherwise it
> looks like the table has infinite tuple density, which is
> likely to bollix something somewhere.
That's a good point.
I attached a patch that creates partitioned tables with relpages=-1,
and updates the docs.
It's awkward to cast back and forth between BlockNumber and int32, so I
updated the signature of vac_update_relstats() as well.
Regards,
Jeff Davis
From 34241c8a9e18c0e945dd38a2858676d52facc898 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Tue, 22 Oct 2024 10:04:11 -0700
Subject: [PATCH v1] Be more consistent about relpages for partitioned tables.
Use -1 for relpages, and document it.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/catalogs.sgml | 3 ++-
src/backend/catalog/heap.c | 5 ++++-
src/backend/commands/vacuum.c | 9 +++++----
src/include/commands/vacuum.h | 2 +-
4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 964c819a02..19b7bbd4a8 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2033,7 +2033,8 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<symbol>BLCKSZ</symbol>). This is only an estimate used by the
planner. 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>.
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>. For partitioned
+ tables, <structfield>relpages</structfield> is <literal>-1</literal>.
</para></entry>
</row>
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 0078a12f26..d21bf0b7da 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -987,7 +987,10 @@ AddNewRelationTuple(Relation pg_class_desc,
new_rel_reltup = new_rel_desc->rd_rel;
/* The relation is empty */
- new_rel_reltup->relpages = 0;
+ if (relkind == RELKIND_PARTITIONED_TABLE)
+ new_rel_reltup->relpages = -1;
+ else
+ new_rel_reltup->relpages = 0;
new_rel_reltup->reltuples = -1;
new_rel_reltup->relallvisible = 0;
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index ac8f5d9c25..eff65b7714 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1402,13 +1402,14 @@ vac_estimate_reltuples(Relation relation,
* always allowable.
*
* Note: num_tuples should count only *live* tuples, since
- * pg_class.reltuples is defined that way.
+ * pg_class.reltuples is defined that way. Also, num_pages is signed,
+ * because partitioned tables have relpages of -1.
*
* This routine is shared by VACUUM and ANALYZE.
*/
void
vac_update_relstats(Relation relation,
- BlockNumber num_pages, double num_tuples,
+ int32 num_pages, double num_tuples,
BlockNumber num_all_visible_pages,
bool hasindex, TransactionId frozenxid,
MultiXactId minmulti,
@@ -1444,9 +1445,9 @@ vac_update_relstats(Relation relation,
/* Apply statistical updates, if any, to copied tuple */
dirty = false;
- if (pgcform->relpages != (int32) num_pages)
+ if (pgcform->relpages != num_pages)
{
- pgcform->relpages = (int32) num_pages;
+ pgcform->relpages = num_pages;
dirty = true;
}
if (pgcform->reltuples != (float4) num_tuples)
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 759f9a87d3..ee3522ef8b 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -326,7 +326,7 @@ extern double vac_estimate_reltuples(Relation relation,
BlockNumber scanned_pages,
double scanned_tuples);
extern void vac_update_relstats(Relation relation,
- BlockNumber num_pages,
+ int32 num_pages,
double num_tuples,
BlockNumber num_all_visible_pages,
bool hasindex,
--
2.34.1