From 46d276b56f1ccbb317d5a08a8b01e048b33c0aca Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@ip-172-31-46-230.ec2.internal>
Date: Thu, 18 Sep 2025 15:36:33 +0000
Subject: [PATCH v13 2/2] Add tests for temp file logging
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Commit 41d252c82eebf7d revealed a lack of test coverage for temp file
logging. This commit adds the missing tests to improve coverage and
reliability.

Author: Sami Imseih <samimseih@gmail.com>
Author: Frédéric Yhuel <frederic.yhuel@dalibo.com>
Reviewed-by: Mircea Cadariu <cadariu.mircea@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/3d07ee43-8855-42db-97e0-bad5db82d972@dalibo.com
---
 src/test/modules/test_misc/meson.build        |   1 +
 .../modules/test_misc/t/009_log_temp_files.pl | 115 ++++++++++++++++++
 2 files changed, 116 insertions(+)
 create mode 100644 src/test/modules/test_misc/t/009_log_temp_files.pl

diff --git a/src/test/modules/test_misc/meson.build b/src/test/modules/test_misc/meson.build
index 6b1e730bf46..f258bf1ccd9 100644
--- a/src/test/modules/test_misc/meson.build
+++ b/src/test/modules/test_misc/meson.build
@@ -17,6 +17,7 @@ tests += {
       't/006_signal_autovacuum.pl',
       't/007_catcache_inval.pl',
       't/008_replslot_single_user.pl',
+      't/009_log_temp_files.pl',
     ],
   },
 }
diff --git a/src/test/modules/test_misc/t/009_log_temp_files.pl b/src/test/modules/test_misc/t/009_log_temp_files.pl
new file mode 100644
index 00000000000..3d1a25bcfa8
--- /dev/null
+++ b/src/test/modules/test_misc/t/009_log_temp_files.pl
@@ -0,0 +1,115 @@
+#
+# Verify that temporary file usage is logged with the expected statement text
+# for various query execution paths (portals, pipelines, cursors, prepared
+# statements, etc.).
+#
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+#
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+# Initialize a new PostgreSQL test cluster
+my $node = PostgreSQL::Test::Cluster->new('primary');
+$node->init();
+$node->append_conf(
+    'postgresql.conf', qq(
+work_mem = 64kB
+log_temp_files = 0
+));
+$node->start;
+
+my $log_offset = -s $node->logfile;
+
+# Setup table and populate with data
+$node->safe_psql("postgres", qq{
+CREATE UNLOGGED TABLE foo(a int);
+INSERT INTO foo(a) SELECT * FROM generate_series(1, 5000);
+});
+
+# unnamed portal test
+$node->safe_psql("postgres", qq{
+BEGIN;
+SELECT a FROM foo ORDER BY a OFFSET \$1 \\bind 4999 \\g
+SELECT 1;
+END;
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file: path.*\n.*\ STATEMENT:\s+SELECT a FROM foo ORDER BY a OFFSET \$1/s, $log_offset);
+ok("log temp with unnamed portal");
+
+# bind with implicit transaction test
+$node->safe_psql("postgres", qq{
+SELECT a FROM foo ORDER BY a OFFSET \$1 \\bind 4999 \\g
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file: path.*\n.*\ STATEMENT:\s+SELECT a FROM foo ORDER BY a OFFSET \$1/s, $log_offset);
+ok("log temp with bind and implicit transaction");
+
+# named portal test
+$node->safe_psql("postgres", qq{
+BEGIN;
+SELECT a FROM foo ORDER BY a OFFSET \$1 \\parse stmt
+\\bind_named stmt 4999 \\g
+SELECT 1;
+END;
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file: path.*\n.*\ STATEMENT:\s+SELECT a FROM foo ORDER BY a OFFSET \$1/s, $log_offset);
+ok("log temp with named portal");
+
+# pipelined query test
+$log_offset = -s $node->logfile;
+$node->safe_psql("postgres", qq{
+\\startpipeline
+SELECT a FROM foo ORDER BY a OFFSET \$1 \\bind 4999 \\sendpipeline
+SELECT 1;
+\\endpipeline
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file: path.*\n.*\ STATEMENT:\s+SELECT a FROM foo ORDER BY a OFFSET \$1/s, $log_offset);
+ok("log temp with pipelined query");
+
+# parse and bind tests
+$log_offset = -s $node->logfile;
+$node->safe_psql("postgres", qq{
+SELECT a, a, a FROM foo ORDER BY a OFFSET \$1 \\parse p1
+\\bind_named p1 4999 \\g
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file: path.*\n.*\ STATEMENT:\s+SELECT a, a, a FROM foo ORDER BY a OFFSET \$1/s, $log_offset);
+ok("log temp with parse and bind");
+
+# simple query test
+$node->safe_psql("postgres", qq{
+BEGIN;
+SELECT a FROM foo ORDER BY a OFFSET 4999;
+END;
+});
+$log_offset = $node->wait_for_log(qr/SELECT a FROM foo ORDER BY a OFFSET 4999;\n.*\ LOG:\s+temporary file: path/s, $log_offset);
+ok("log temp with simple query");
+
+# cursor test
+$node->safe_psql("postgres", qq{
+BEGIN;
+DECLARE mycur CURSOR FOR SELECT a FROM foo ORDER BY a OFFSET 4999;
+FETCH 10 FROM mycur;
+SELECT 1;
+CLOSE mycur;
+END;
+});
+$log_offset = $node->wait_for_log(qr/CLOSE mycur;\n.*\ LOG:\s+temporary file:/s, $log_offset);
+ok("log temp with cursor");
+
+# prepare/execute test
+$node->safe_psql("postgres", qq{
+BEGIN;
+PREPARE p1 AS SELECT a FROM foo ORDER BY a OFFSET 4999;
+EXECUTE p1;
+DEALLOCATE p1;
+END;
+});
+$log_offset = $node->wait_for_log(qr/LOG:\s+temporary file:/s, $log_offset);
+ok("prepare and execute cursor");
+
+# Stop the node
+$node->stop('fast');
+done_testing();
-- 
2.43.0

