From d59bd4e724c9693c31f45da1a806108fae03d18b Mon Sep 17 00:00:00 2001
From: Zhong ShiHao <zhong950419@gmail.com>
Date: Sun, 6 Sep 2026 20:11:38 -0400
Subject: [PATCH] Test create_upper_paths_hook for UPPERREL_PARTIAL_GROUP_AGG

Have test_extensible register create_upper_paths_hook and report when it
is called for the partially grouped relation.  Nothing in the tree
registered this hook before, so none of its call sites had any coverage.
---
 src/test/modules/test_extensible/Makefile     |  2 +-
 .../test_extensible/expected/partial_agg.out  | 17 ++++++++++++++
 src/test/modules/test_extensible/meson.build  |  1 +
 .../test_extensible/sql/partial_agg.sql       | 14 +++++++++++
 .../modules/test_extensible/test_extensible.c | 23 +++++++++++++++++++
 5 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 src/test/modules/test_extensible/expected/partial_agg.out
 create mode 100644 src/test/modules/test_extensible/sql/partial_agg.sql

diff --git a/src/test/modules/test_extensible/Makefile b/src/test/modules/test_extensible/Makefile
index 4c696eda6c0..a0a65779ce9 100644
--- a/src/test/modules/test_extensible/Makefile
+++ b/src/test/modules/test_extensible/Makefile
@@ -9,7 +9,7 @@ PGFILEDESC = "test_extensible - test module for extensible node and custom scan"
 EXTENSION = test_extensible
 DATA = test_extensible--1.0.sql
 
-REGRESS = test_extensible
+REGRESS = test_extensible partial_agg
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/src/test/modules/test_extensible/expected/partial_agg.out b/src/test/modules/test_extensible/expected/partial_agg.out
new file mode 100644
index 00000000000..f7335f1bc8e
--- /dev/null
+++ b/src/test/modules/test_extensible/expected/partial_agg.out
@@ -0,0 +1,17 @@
+-- create_upper_paths_hook must be fired for UPPERREL_PARTIAL_GROUP_AGG when
+-- the planner considers partial aggregation.
+LOAD 'test_extensible';
+CREATE TABLE test_extensible_agg_tbl (a int, b int);
+INSERT INTO test_extensible_agg_tbl SELECT i % 3, i FROM generate_series(1, 10) i;
+SET min_parallel_table_scan_size = 0;
+SET max_parallel_workers_per_gather = 2;
+SELECT a, sum(b) FROM test_extensible_agg_tbl GROUP BY a ORDER BY a;
+NOTICE:  create_upper_paths_hook: UPPERREL_PARTIAL_GROUP_AGG
+ a | sum 
+---+-----
+ 0 |  18
+ 1 |  22
+ 2 |  15
+(3 rows)
+
+DROP TABLE test_extensible_agg_tbl;
diff --git a/src/test/modules/test_extensible/meson.build b/src/test/modules/test_extensible/meson.build
index 54c571f30b6..a09852e8d67 100644
--- a/src/test/modules/test_extensible/meson.build
+++ b/src/test/modules/test_extensible/meson.build
@@ -28,6 +28,7 @@ tests += {
   'regress': {
     'sql': [
       'test_extensible',
+      'partial_agg',
     ],
   },
 }
diff --git a/src/test/modules/test_extensible/sql/partial_agg.sql b/src/test/modules/test_extensible/sql/partial_agg.sql
new file mode 100644
index 00000000000..ebe4e2fea2c
--- /dev/null
+++ b/src/test/modules/test_extensible/sql/partial_agg.sql
@@ -0,0 +1,14 @@
+-- create_upper_paths_hook must be fired for UPPERREL_PARTIAL_GROUP_AGG when
+-- the planner considers partial aggregation.
+
+LOAD 'test_extensible';
+
+CREATE TABLE test_extensible_agg_tbl (a int, b int);
+INSERT INTO test_extensible_agg_tbl SELECT i % 3, i FROM generate_series(1, 10) i;
+
+SET min_parallel_table_scan_size = 0;
+SET max_parallel_workers_per_gather = 2;
+
+SELECT a, sum(b) FROM test_extensible_agg_tbl GROUP BY a ORDER BY a;
+
+DROP TABLE test_extensible_agg_tbl;
diff --git a/src/test/modules/test_extensible/test_extensible.c b/src/test/modules/test_extensible/test_extensible.c
index 2a1344f28d5..165a2a1af59 100644
--- a/src/test/modules/test_extensible/test_extensible.c
+++ b/src/test/modules/test_extensible/test_extensible.c
@@ -25,6 +25,7 @@
 #include "nodes/readfuncs.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
+#include "optimizer/planner.h"
 #include "optimizer/restrictinfo.h"
 #include "utils/builtins.h"
 #include "utils/guc.h"
@@ -422,6 +423,25 @@ test_set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
 	add_path(rel, (Path *) cpath);
 }
 
+static create_upper_paths_hook_type prev_create_upper_paths_hook = NULL;
+
+/*
+ * Report the upper planning stages we are called for.  Only partial
+ * aggregation is interesting here; the other stages have always fired the
+ * hook.
+ */
+static void
+test_create_upper_paths(PlannerInfo *root, UpperRelationKind stage,
+						RelOptInfo *input_rel, RelOptInfo *output_rel,
+						void *extra)
+{
+	if (prev_create_upper_paths_hook)
+		prev_create_upper_paths_hook(root, stage, input_rel, output_rel, extra);
+
+	if (stage == UPPERREL_PARTIAL_GROUP_AGG)
+		elog(NOTICE, "create_upper_paths_hook: UPPERREL_PARTIAL_GROUP_AGG");
+}
+
 /*
  * test_get_extensible_node_methods
  *
@@ -565,4 +585,7 @@ _PG_init(void)
 	/* Install the path-list hook to inject CustomPaths for the test table */
 	prev_set_rel_pathlist_hook = set_rel_pathlist_hook;
 	set_rel_pathlist_hook = test_set_rel_pathlist;
+
+	prev_create_upper_paths_hook = create_upper_paths_hook;
+	create_upper_paths_hook = test_create_upper_paths;
 }
-- 
2.37.1 (Apple Git-137.1)

