From 7f68a7e4d84ee5f1376eb4d8681773e4eaf305e3 Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Mon, 4 Nov 2024 16:21:39 -0500
Subject: [PATCH v30 5/5] Enable pg_clear_relation_stats to handle different
 default relpages.

If it comes to pass that relpages has the default of -1.0 for
partitioned tables (and indexes), then this patch will handle that.
---
 src/backend/statistics/relation_stats.c | 47 +++++++++++++------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c
index 939ad56fc2..1aab63f5d8 100644
--- a/src/backend/statistics/relation_stats.c
+++ b/src/backend/statistics/relation_stats.c
@@ -19,15 +19,12 @@
 
 #include "access/heapam.h"
 #include "catalog/indexing.h"
+#include "catalog/pg_class_d.h"
 #include "statistics/stat_utils.h"
 #include "utils/fmgrprotos.h"
 #include "utils/syscache.h"
 #include "utils/fmgroids.h"
 
-#define DEFAULT_RELPAGES Int32GetDatum(0)
-#define DEFAULT_RELTUPLES Float4GetDatum(-1.0)
-#define DEFAULT_RELALLVISIBLE Int32GetDatum(0)
-
 /*
  * Positional argument numbers, names, and types for
  * relation_statistics_update().
@@ -51,14 +48,11 @@ static struct StatsArgInfo relarginfo[] =
 	[NUM_RELATION_STATS_ARGS] = {0}
 };
 
-static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel,
-									   bool inplace);
-
 /*
  * Internal function for modifying statistics for a relation.
  */
 static bool
-relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
+relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace, bool clear)
 {
 	Oid			reloid;
 	Relation	crel;
@@ -110,9 +104,19 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
 	pgcform = (Form_pg_class) GETSTRUCT(ctup);
 
 	/* relpages */
-	if (!PG_ARGISNULL(RELPAGES_ARG))
+	if (!PG_ARGISNULL(RELPAGES_ARG) || clear)
 	{
-		int32		relpages = PG_GETARG_INT32(RELPAGES_ARG);
+		int32		relpages;
+
+		if (clear)
+			/* relpages default varies by relkind */
+			if ((crel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) ||
+				(crel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX))
+				relpages = -1;
+			else
+				relpages = 0;
+		else
+			relpages = PG_GETARG_INT32(RELPAGES_ARG);
 
 		/*
 		 * Partitioned tables may have relpages=-1. Note: for relations with
@@ -139,9 +143,9 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
 		}
 	}
 
-	if (!PG_ARGISNULL(RELTUPLES_ARG))
+	if (!PG_ARGISNULL(RELTUPLES_ARG) || clear)
 	{
-		float		reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
+		float		reltuples = (clear) ? -1.0 : PG_GETARG_FLOAT4(RELTUPLES_ARG);
 
 		if (reltuples < -1.0)
 		{
@@ -164,9 +168,9 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
 
 	}
 
-	if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
+	if (!PG_ARGISNULL(RELALLVISIBLE_ARG) || clear)
 	{
-		int32		relallvisible = PG_GETARG_INT32(RELALLVISIBLE_ARG);
+		int32		relallvisible = (clear) ? 0 : PG_GETARG_INT32(RELALLVISIBLE_ARG);
 
 		if (relallvisible < 0)
 		{
@@ -220,7 +224,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel, bool inplace)
 Datum
 pg_set_relation_stats(PG_FUNCTION_ARGS)
 {
-	relation_statistics_update(fcinfo, ERROR, false);
+	relation_statistics_update(fcinfo, ERROR, false, false);
 	PG_RETURN_VOID();
 }
 
@@ -237,14 +241,11 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
 
 	newfcinfo->args[0].value = PG_GETARG_OID(0);
 	newfcinfo->args[0].isnull = PG_ARGISNULL(0);
-	newfcinfo->args[1].value = DEFAULT_RELPAGES;
-	newfcinfo->args[1].isnull = false;
-	newfcinfo->args[2].value = DEFAULT_RELTUPLES;
-	newfcinfo->args[2].isnull = false;
-	newfcinfo->args[3].value = DEFAULT_RELALLVISIBLE;
-	newfcinfo->args[3].isnull = false;
+	newfcinfo->args[1].isnull = true;
+	newfcinfo->args[2].isnull = true;
+	newfcinfo->args[3].isnull = true;
 
-	relation_statistics_update(newfcinfo, ERROR, false);
+	relation_statistics_update(newfcinfo, ERROR, false, true);
 	PG_RETURN_VOID();
 }
 
@@ -262,7 +263,7 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS)
 										  relarginfo, WARNING))
 		result = false;
 
-	if (!relation_statistics_update(positional_fcinfo, WARNING, true))
+	if (!relation_statistics_update(positional_fcinfo, WARNING, true, false))
 		result = false;
 
 	PG_RETURN_BOOL(result);
-- 
2.47.0

