From 4de7e463713c8c15c128e703caf11033e85221dd Mon Sep 17 00:00:00 2001
From: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Date: Thu, 2 Jul 2026 14:58:42 +0200
Subject: Test tracing of cancel requests

Enable PGTRACE for cancel test of libpq_pipeline to test the tracing of
cancel requests. PGTRACEAPPEND needs to be enabled as cancel requests
are sent from a new connection, and we want to append the new traced
requests to the existing trace file.

The main connection and monitor connection are PQuntraced to avoid
having multiple connections writing to the same trace file.
---
 .../modules/libpq_pipeline/libpq_pipeline.c   | 11 +++++
 .../libpq_pipeline/t/001_libpq_pipeline.pl    |  8 +++-
 .../libpq_pipeline/traces/cancel.trace        | 45 +++++++++++++++++++
 3 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 src/test/modules/libpq_pipeline/traces/cancel.trace

diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c b/src/test/modules/libpq_pipeline/libpq_pipeline.c
index e7526e46d46..e75fad13443 100644
--- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
+++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
@@ -300,11 +300,22 @@ test_cancel(PGconn *conn)
 	if (PQsetnonblocking(conn, 1) != 0)
 		pg_fatal("failed to set nonblocking mode: %s", PQerrorMessage(conn));
 
+	/*
+	 * We need to avoid having multiple processes writing in the same trace,
+	 * and we want to trace the cancel request, so untrace the main connection
+	 */
+	PQuntrace(conn);
+
 	/*
 	 * Make a separate connection to the database to monitor the query on the
 	 * main connection.
 	 */
 	monitorConn = copy_connection(conn);
+
+	/*
+	 * Also untrace the connection to leave trace file to cancel requests
+	 */
+	PQuntrace(monitorConn);
 	Assert(PQstatus(monitorConn) == CONNECTION_OK);
 
 	/* test PQcancel */
diff --git a/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl b/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
index 31cd1795f55..c5d8edd343e 100644
--- a/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
+++ b/src/test/modules/libpq_pipeline/t/001_libpq_pipeline.pl
@@ -39,7 +39,7 @@ for my $testname (@tests)
 	my $cmptrace = grep(/^$testname$/,
 		qw(simple_pipeline nosync multi_pipelines prepared singlerow
 		  pipeline_abort pipeline_idle transaction
-		  disallowed_in_pipeline)) > 0;
+		  disallowed_in_pipeline cancel)) > 0;
 
 	# For a bunch of tests, generate a libpq trace file too.
 	my $traceout =
@@ -47,12 +47,18 @@ for my $testname (@tests)
 
 	local $ENV{PGTRACE};
 	local $ENV{PGTRACEFLAGS};
+	local $ENV{PGTRACEAPPEND};
 	if ($cmptrace)
 	{
 		$ENV{PGTRACE}      = $traceout;
+		# Set trace flags to PQTRACE_SUPPRESS_TIMESTAMPS | PQTRACE_REGRESS_MODE
 		$ENV{PGTRACEFLAGS} = 3;
+		# cancel test opens new connections to send the cancel requests. Enable
+		# append mode to avoid clearing the file with every new connection.
+		$ENV{PGTRACEAPPEND} = 1 if $testname eq 'cancel';
 	} else {
 		delete $ENV{PGTRACE};
+		delete $ENV{PGTRACEFLAGS};
 	}
 
 	# Execute the test using the latest protocol version.
diff --git a/src/test/modules/libpq_pipeline/traces/cancel.trace b/src/test/modules/libpq_pipeline/traces/cancel.trace
new file mode 100644
index 00000000000..b6bd5c915e7
--- /dev/null
+++ b/src/test/modules/libpq_pipeline/traces/cancel.trace
@@ -0,0 +1,45 @@
+F	NN	StartupMessage	 3 2 "user" "SSSS" "database" "SSSS" "application_name" "SSSS"
+B	NN	ParameterStatus	 "IntervalStyle" "SSSS"
+B	NN	ParameterStatus	 "search_path" "SSSS"
+B	NN	ParameterStatus	 "is_superuser" "SSSS"
+B	NN	ParameterStatus	 "standard_conforming_strings" "SSSS"
+B	NN	ParameterStatus	 "session_authorization" "SSSS"
+B	NN	ParameterStatus	 "client_encoding" "SSSS"
+B	NN	ParameterStatus	 "server_version" "SSSS"
+B	NN	ParameterStatus	 "server_encoding" "SSSS"
+B	NN	ParameterStatus	 "in_hot_standby" "SSSS"
+B	NN	ParameterStatus	 "integer_datetimes" "SSSS"
+B	NN	ParameterStatus	 "TimeZone" "SSSS"
+B	NN	ParameterStatus	 "application_name" "SSSS"
+B	NN	ParameterStatus	 "default_transaction_read_only" "SSSS"
+B	NN	ParameterStatus	 "scram_iterations" "SSSS"
+B	NN	ParameterStatus	 "DateStyle" "SSSS"
+B	40	BackendKeyData	 NNNN 'BBBB'
+B	5	ReadyForQuery	 I
+F	27	Query	 "SET lc_messages TO "C""
+B	8	CommandComplete	 "SET"
+B	5	ReadyForQuery	 I
+F	35	Query	 "SET debug_parallel_query = off"
+B	8	CommandComplete	 "SET"
+B	5	ReadyForQuery	 I
+F	NN	StartupMessage	 3 2 "user" "SSSS" "database" "SSSS" "application_name" "SSSS"
+B	NN	ParameterStatus	 "IntervalStyle" "SSSS"
+B	NN	ParameterStatus	 "search_path" "SSSS"
+B	NN	ParameterStatus	 "is_superuser" "SSSS"
+B	NN	ParameterStatus	 "standard_conforming_strings" "SSSS"
+B	NN	ParameterStatus	 "session_authorization" "SSSS"
+B	NN	ParameterStatus	 "client_encoding" "SSSS"
+B	NN	ParameterStatus	 "server_version" "SSSS"
+B	NN	ParameterStatus	 "server_encoding" "SSSS"
+B	NN	ParameterStatus	 "in_hot_standby" "SSSS"
+B	NN	ParameterStatus	 "integer_datetimes" "SSSS"
+B	NN	ParameterStatus	 "TimeZone" "SSSS"
+B	NN	ParameterStatus	 "application_name" "SSSS"
+B	NN	ParameterStatus	 "default_transaction_read_only" "SSSS"
+B	NN	ParameterStatus	 "scram_iterations" "SSSS"
+B	NN	ParameterStatus	 "DateStyle" "SSSS"
+B	40	BackendKeyData	 NNNN 'BBBB'
+B	5	ReadyForQuery	 I
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
-- 
2.54.0

