From 8db21b5a5af2f25b3ab5026e4f2ee6c0ceecdac5 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 10 Feb 2026 08:13:46 -0500
Subject: [PATCH v17 2/5] Replace get_relation_info_hook with
 build_simple_rel_hook.

For a long time, PostgreSQL has had a get_relation_info_hook which
plugins can use to editorialize on the information that
get_relation_info obtains from the catalogs. However, this hook is
only called for baserels of type RTE_RELATION, and there is
potential utility in a similar call back for other types of
RTEs. This might have had utility even before commit
4020b370f214315b8c10430301898ac21658143f added pgs_mask to
RelOptInfo, but it certainly has utility now.

So, move the callback up one level, deleting get_relation_info_hook and
adding build_simple_rel_hook instead. The new callback is called just
slightly later than before and with slightly different arguments, but it
should be fairly straightforward to adjust existing code that currentyy
uses get_relation_info_hook: the values previously available as
relationObjectId and inhparent are now available via rte->relid and
rte->inh, and calls where rte->rtekind != RTE_RELATION can be ignored if
desired.
---
 src/backend/optimizer/util/plancat.c | 14 --------------
 src/backend/optimizer/util/relnode.c | 15 +++++++++++++++
 src/include/optimizer/pathnode.h     |  6 ++++++
 src/include/optimizer/plancat.h      |  8 --------
 4 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index d63e7390be7..b2fbd6a082b 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -57,9 +57,6 @@
 /* GUC parameter */
 int			constraint_exclusion = CONSTRAINT_EXCLUSION_PARTITION;
 
-/* Hook for plugins to get control in get_relation_info() */
-get_relation_info_hook_type get_relation_info_hook = NULL;
-
 typedef struct NotnullHashEntry
 {
 	Oid			relid;			/* OID of the relation */
@@ -571,17 +568,6 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 		set_relation_partition_info(root, rel, relation);
 
 	table_close(relation, NoLock);
-
-	/*
-	 * Allow a plugin to editorialize on the info we obtained from the
-	 * catalogs.  Actions might include altering the assumed relation size,
-	 * removing an index, or adding a hypothetical index to the indexlist.
-	 *
-	 * An extension can also modify rel->pgs_mask here to control path
-	 * generation.
-	 */
-	if (get_relation_info_hook)
-		(*get_relation_info_hook) (root, relationObjectId, inhparent, rel);
 }
 
 /*
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index a714c83f1ba..4a89eda0142 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -47,6 +47,9 @@ typedef struct JoinHashEntry
 	RelOptInfo *join_rel;
 } JoinHashEntry;
 
+/* Hook for plugins to get control in build_simple_rel() */
+build_simple_rel_hook_type build_simple_rel_hook = NULL;
+
 /* Hook for plugins to get control during joinrel setup */
 joinrel_setup_hook_type joinrel_setup_hook = NULL;
 
@@ -394,6 +397,18 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
 			break;
 	}
 
+	/*
+	 * Allow a plugin to editorialize on the new RelOptInfo. This could
+	 * involve editorializing on the information which get_relation_info
+	 * obtained from the catalogs, such as altering the assumed relation size,
+	 * removing an index, or adding a hypothetical index to the indexlist.
+	 *
+	 * An extension can also modify rel->pgs_mask here to control path
+	 * generation.
+	 */
+	if (build_simple_rel_hook)
+		(*build_simple_rel_hook) (root, rel, rte);
+
 	/*
 	 * We must apply the partially filled in RelOptInfo before calling
 	 * apply_child_basequals due to some transformations within that function
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index cf8a654fa53..8297870cf7e 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -17,6 +17,12 @@
 #include "nodes/bitmapset.h"
 #include "nodes/pathnodes.h"
 
+/* Hook for plugins to get control in get_relation_info() */
+typedef void (*build_simple_rel_hook_type) (PlannerInfo *root,
+											RelOptInfo *rel,
+											RangeTblEntry *rte);
+extern PGDLLIMPORT build_simple_rel_hook_type build_simple_rel_hook;
+
 /*
  * Everything in subpaths or partial_subpaths will become part of the
  * Append node's subpaths list. Partial and non-partial subpaths can be
diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h
index 8d7cc6d9886..09baf1a6916 100644
--- a/src/include/optimizer/plancat.h
+++ b/src/include/optimizer/plancat.h
@@ -17,14 +17,6 @@
 #include "nodes/pathnodes.h"
 #include "utils/relcache.h"
 
-/* Hook for plugins to get control in get_relation_info() */
-typedef void (*get_relation_info_hook_type) (PlannerInfo *root,
-											 Oid relationObjectId,
-											 bool inhparent,
-											 RelOptInfo *rel);
-extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook;
-
-
 extern void get_relation_info(PlannerInfo *root, Oid relationObjectId,
 							  bool inhparent, RelOptInfo *rel);
 
-- 
2.51.0

