From 4dec197062fa2d4676de902b7c0f7a6c7e096acc Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Mon, 16 Sep 2024 05:58:23 -0400
Subject: [PATCH v29 3/7] Add relkind check to stats_lock_check_privileges().

Prevent statistics modificaton functions from operating on relation
kinds that cannot store statistics. This includes all of the kinds that
can be ANALYZEd, plus index types.
---
 src/backend/statistics/stats_utils.c       | 14 ++++++++++++++
 src/test/regress/expected/stats_import.out | 15 ++++++++++++++-
 src/test/regress/sql/stats_import.sql      | 10 ++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/backend/statistics/stats_utils.c b/src/backend/statistics/stats_utils.c
index f51144d4ac..4780e98c17 100644
--- a/src/backend/statistics/stats_utils.c
+++ b/src/backend/statistics/stats_utils.c
@@ -135,6 +135,20 @@ void
 stats_lock_check_privileges(Oid reloid)
 {
 	Relation	rel = relation_open(reloid, ShareUpdateExclusiveLock);
+	const char	relkind = rel->rd_rel->relkind;
+
+	/* All of the types that can be used with ANALYZE, plus indexes */
+	if (relkind != RELKIND_RELATION &&
+		relkind != RELKIND_INDEX &&
+		relkind != RELKIND_MATVIEW &&
+		relkind != RELKIND_FOREIGN_TABLE &&
+		relkind != RELKIND_PARTITIONED_TABLE &&
+		relkind != RELKIND_PARTITIONED_INDEX)
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot modify statistics for relations of kind '%c'", relkind)));
+	}
 
 	if (rel->rd_rel->relisshared)
 		ereport(ERROR,
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index 951dd6a10e..61223949f6 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -122,7 +122,20 @@ WHERE oid = 'stats_import.test'::regclass;
         0 |        -1 |             0
 (1 row)
 
+-- invalid relkinds for statistics
+CREATE SEQUENCE stats_import.testseq;
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+SELECT
+    pg_catalog.pg_clear_relation_stats(
+        'stats_import.testseq'::regclass);
+ERROR:  cannot modify statistics for relations of kind 'S'
+SELECT
+    pg_catalog.pg_clear_relation_stats(
+        'stats_import.testview'::regclass);
+ERROR:  cannot modify statistics for relations of kind 'v'
 DROP SCHEMA stats_import CASCADE;
-NOTICE:  drop cascades to 2 other objects
+NOTICE:  drop cascades to 4 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
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 40199dd453..3e9f6d9124 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -85,4 +85,14 @@ SELECT relpages, reltuples, relallvisible
 FROM pg_class
 WHERE oid = 'stats_import.test'::regclass;
 
+-- invalid relkinds for statistics
+CREATE SEQUENCE stats_import.testseq;
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+SELECT
+    pg_catalog.pg_clear_relation_stats(
+        'stats_import.testseq'::regclass);
+SELECT
+    pg_catalog.pg_clear_relation_stats(
+        'stats_import.testview'::regclass);
+
 DROP SCHEMA stats_import CASCADE;
-- 
2.46.0

