From 7520cc211a6f4a78514c6f32ddc7eb185365e50a Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-46-230.ec2.internal>
Date: Tue, 20 Jan 2026 23:25:52 +0000
Subject: [PATCH v1 1/1] pg_stat_statements: Add missing tests for nested
 statements

This adds tests to verify nesting_level is set correctly when tracking
nested queries in pgss_planner and pgss_ExecutorFinish.
---
 .../expected/level_tracking.out               | 62 +++++++++++++++++++
 .../pg_stat_statements/sql/level_tracking.sql | 35 +++++++++++
 2 files changed, 97 insertions(+)

diff --git a/contrib/pg_stat_statements/expected/level_tracking.out b/contrib/pg_stat_statements/expected/level_tracking.out
index 8e8388dd5cb..71a55421f03 100644
--- a/contrib/pg_stat_statements/expected/level_tracking.out
+++ b/contrib/pg_stat_statements/expected/level_tracking.out
@@ -1535,6 +1535,68 @@ SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLA
  t        |     1 |    1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
 (8 rows)
 
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+ t 
+---
+ t
+(1 row)
+
+SET pg_stat_statements.track_planning = TRUE;
+SELECT PLUS_THREE(8);
+ plus_three 
+------------
+         11
+(1 row)
+
+SELECT PLUS_THREE(10);
+ plus_three 
+------------
+         13
+(1 row)
+
+SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ toplevel | calls | rows | plans |                                             query                                             
+----------+-------+------+-------+-----------------------------------------------------------------------------------------------
+ t        |     2 |    2 |     2 | SELECT PLUS_THREE($1)
+ f        |     2 |    2 |     2 | SELECT i + 3 LIMIT 1
+ t        |     1 |    1 |     0 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
+ t        |     0 |    0 |     1 | SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements ORDER BY query COLLATE "C"
+(4 rows)
+
+RESET pg_stat_statements.track_planning;
+-- AFTER trigger SQL - top-level tracking.
+SET pg_stat_statements.track = 'all';
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+ t 
+---
+ t
+(1 row)
+
+CREATE TABLE test_trigger (id int, name text);
+CREATE TABLE audit_table (table_name text, action text, row_id int);
+CREATE OR REPLACE FUNCTION audit_trigger_func()
+RETURNS TRIGGER AS $$
+BEGIN
+    INSERT INTO audit_table VALUES ('test_trigger', TG_OP, NEW.id);
+    RETURN NULL;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER audit_after_trigger
+    AFTER INSERT ON test_trigger
+    FOR EACH ROW EXECUTE FUNCTION audit_trigger_func();
+INSERT INTO test_trigger VALUES (1, 'test1');
+INSERT INTO test_trigger VALUES (2, 'test2');
+SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ toplevel | calls | rows | plans |                        query                        
+----------+-------+------+-------+-----------------------------------------------------
+ f        |     2 |    2 |     0 | INSERT INTO audit_table VALUES ($15, TG_OP, NEW.id)
+ t        |     2 |    2 |     0 | INSERT INTO test_trigger VALUES ($1, $2)
+ t        |     1 |    1 |     0 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
+(3 rows)
+
+DROP TRIGGER audit_after_trigger ON test_trigger;
+DROP FUNCTION audit_trigger_func();
+DROP TABLE audit_table, test_trigger;
 --
 -- pg_stat_statements.track = none
 --
diff --git a/contrib/pg_stat_statements/sql/level_tracking.sql b/contrib/pg_stat_statements/sql/level_tracking.sql
index 86f007e8552..b3bd0ddabf2 100644
--- a/contrib/pg_stat_statements/sql/level_tracking.sql
+++ b/contrib/pg_stat_statements/sql/level_tracking.sql
@@ -431,6 +431,41 @@ SELECT PLUS_THREE(8);
 SELECT PLUS_THREE(10);
 
 SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+
+SET pg_stat_statements.track_planning = TRUE;
+
+SELECT PLUS_THREE(8);
+SELECT PLUS_THREE(10);
+
+SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+RESET pg_stat_statements.track_planning;
+
+-- AFTER trigger SQL - all-level tracking.
+SET pg_stat_statements.track = 'all';
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+
+CREATE TABLE test_trigger (id int, name text);
+CREATE TABLE audit_table (table_name text, action text, row_id int);
+CREATE OR REPLACE FUNCTION audit_trigger_func()
+RETURNS TRIGGER AS $$
+BEGIN
+    INSERT INTO audit_table VALUES ('test_trigger', TG_OP, NEW.id);
+    RETURN NULL;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER audit_after_trigger
+    AFTER INSERT ON test_trigger
+    FOR EACH ROW EXECUTE FUNCTION audit_trigger_func();
+
+INSERT INTO test_trigger VALUES (1, 'test1');
+INSERT INTO test_trigger VALUES (2, 'test2');
+
+SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements ORDER BY query COLLATE "C";
+
+DROP TRIGGER audit_after_trigger ON test_trigger;
+DROP FUNCTION audit_trigger_func();
+DROP TABLE audit_table, test_trigger;
 
 --
 -- pg_stat_statements.track = none
-- 
2.43.0

