From a04aa2eb0c99227e844e1e2a158316fefcd1e11b Mon Sep 17 00:00:00 2001
From: Shinya Kato <shinya11.kato@gmail.com>
Date: Thu, 11 Jun 2026 16:17:31 +0900
Subject: [PATCH v1 4/5] Count global_temporary_table in
 pg_stat_deprecated_features

---
 doc/src/sgml/monitoring.sgml                  | 10 +++++++
 src/backend/parser/gram.y                     |  5 ++++
 .../activity/pgstat_deprecated_features.c     |  1 +
 src/include/catalog/pg_proc.dat               |  2 +-
 src/include/pgstat.h                          |  1 +
 src/test/regress/expected/stats.out           | 30 +++++++++++++++++--
 src/test/regress/sql/stats.sql                | 11 +++++++
 7 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 4e5d5cc7e84..5b556075006 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3501,6 +3501,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage
    The tracked deprecated features are:
 
    <variablelist>
+    <varlistentry>
+     <term><literal>global_temporary_table</literal></term>
+     <listitem>
+      <para>
+       Use of the deprecated <literal>GLOBAL</literal> keyword in temporary
+       table creation.
+      </para>
+     </listitem>
+    </varlistentry>
+
     <varlistentry>
      <term><literal>md5_password_auth</literal></term>
      <listitem>
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ff4e1388c55..a0325cd8d1e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -58,6 +58,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "parser/parser.h"
+#include "pgstat.h"
 #include "utils/datetime.h"
 #include "utils/xml.h"
 
@@ -3926,6 +3927,7 @@ OptTemp:	TEMPORARY					{ $$ = RELPERSISTENCE_TEMP; }
 			| LOCAL TEMP				{ $$ = RELPERSISTENCE_TEMP; }
 			| GLOBAL TEMPORARY
 				{
+					pgstat_count_deprecated_feature(PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE);
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
 							 parser_errposition(@1)));
@@ -3933,6 +3935,7 @@ OptTemp:	TEMPORARY					{ $$ = RELPERSISTENCE_TEMP; }
 				}
 			| GLOBAL TEMP
 				{
+					pgstat_count_deprecated_feature(PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE);
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
 							 parser_errposition(@1)));
@@ -13972,6 +13975,7 @@ OptTempTableName:
 				}
 			| GLOBAL TEMPORARY opt_table qualified_name
 				{
+					pgstat_count_deprecated_feature(PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE);
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
 							 parser_errposition(@1)));
@@ -13980,6 +13984,7 @@ OptTempTableName:
 				}
 			| GLOBAL TEMP opt_table qualified_name
 				{
+					pgstat_count_deprecated_feature(PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE);
 					ereport(WARNING,
 							(errmsg("GLOBAL is deprecated in temporary table creation"),
 							 parser_errposition(@1)));
diff --git a/src/backend/utils/activity/pgstat_deprecated_features.c b/src/backend/utils/activity/pgstat_deprecated_features.c
index 770ed195741..fadffc1d19d 100644
--- a/src/backend/utils/activity/pgstat_deprecated_features.c
+++ b/src/backend/utils/activity/pgstat_deprecated_features.c
@@ -27,6 +27,7 @@
  * be kept in the same order, sorted by name.
  */
 static const char *const pgstat_deprecated_feature_names[] = {
+	[PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE] = "global_temporary_table",
 	[PGSTAT_DEPRECATED_FEATURE_MD5_PASSWORD_AUTH] = "md5_password_auth",
 	[PGSTAT_DEPRECATED_FEATURE_MD5_PASSWORD_SET] = "md5_password_set",
 };
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index ab4df79e1ef..6d11271d095 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6070,7 +6070,7 @@
   prosrc => 'pg_stat_get_lock' },
 
 { oid => '8987', descr => 'statistics: deprecated feature usage',
-  proname => 'pg_stat_get_deprecated_features', prorows => '2',
+  proname => 'pg_stat_get_deprecated_features', prorows => '3',
   proretset => 't', provolatile => 'v', proparallel => 'r',
   prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int8,timestamptz,timestamptz}',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 8c483ea05f6..90bc163cc00 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -276,6 +276,7 @@ typedef struct PgStat_CheckpointerStats
 /* Deprecated features counted by pg_stat_deprecated_features */
 typedef enum PgStat_DeprecatedFeature
 {
+	PGSTAT_DEPRECATED_FEATURE_GLOBAL_TEMPORARY_TABLE,
 	PGSTAT_DEPRECATED_FEATURE_MD5_PASSWORD_AUTH,
 	PGSTAT_DEPRECATED_FEATURE_MD5_PASSWORD_SET,
 } PgStat_DeprecatedFeature;
diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out
index ecf5f210c59..50e5e18ef0b 100644
--- a/src/test/regress/expected/stats.out
+++ b/src/test/regress/expected/stats.out
@@ -1078,6 +1078,29 @@ SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHER
 (1 row)
 
 -- Test deprecated feature usage statistics
+-- Creating a temporary table with the deprecated GLOBAL keyword must be
+-- counted, in addition to emitting a warning.
+SELECT usage_count AS deprecated_global_temp_count
+  FROM pg_stat_deprecated_features WHERE name = 'global_temporary_table' \gset
+CREATE GLOBAL TEMPORARY TABLE stats_global_temp (a int);
+WARNING:  GLOBAL is deprecated in temporary table creation
+LINE 1: CREATE GLOBAL TEMPORARY TABLE stats_global_temp (a int);
+               ^
+DROP TABLE stats_global_temp;
+SELECT pg_stat_force_next_flush();
+ pg_stat_force_next_flush 
+--------------------------
+ 
+(1 row)
+
+SELECT usage_count = :deprecated_global_temp_count + 1 AS incremented,
+       last_used IS NOT NULL AS has_last_used
+  FROM pg_stat_deprecated_features WHERE name = 'global_temporary_table';
+ incremented | has_last_used 
+-------------+---------------
+ t           | t
+(1 row)
+
 -- Setting an MD5-encrypted password must be counted even when
 -- md5_password_warnings is disabled.
 SET md5_password_warnings = off;
@@ -1144,11 +1167,12 @@ SELECT stats_reset > :'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpoi
 
 -- The deprecated features view should list the expected features
 SELECT name FROM pg_stat_deprecated_features ORDER BY name COLLATE "C";
-       name        
--------------------
+          name          
+------------------------
+ global_temporary_table
  md5_password_auth
  md5_password_set
-(2 rows)
+(3 rows)
 
 -- Test that reset_shared with deprecated_features specified as the stats type works
 SELECT max(stats_reset) AS deprecated_features_reset_ts FROM pg_stat_deprecated_features \gset
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index bf88b08c4cf..24e196212af 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -500,6 +500,17 @@ SELECT stats_reset > :'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHER
 
 -- Test deprecated feature usage statistics
 
+-- Creating a temporary table with the deprecated GLOBAL keyword must be
+-- counted, in addition to emitting a warning.
+SELECT usage_count AS deprecated_global_temp_count
+  FROM pg_stat_deprecated_features WHERE name = 'global_temporary_table' \gset
+CREATE GLOBAL TEMPORARY TABLE stats_global_temp (a int);
+DROP TABLE stats_global_temp;
+SELECT pg_stat_force_next_flush();
+SELECT usage_count = :deprecated_global_temp_count + 1 AS incremented,
+       last_used IS NOT NULL AS has_last_used
+  FROM pg_stat_deprecated_features WHERE name = 'global_temporary_table';
+
 -- Setting an MD5-encrypted password must be counted even when
 -- md5_password_warnings is disabled.
 SET md5_password_warnings = off;
-- 
2.47.3

