From 22c8aa2583a63340402934522009b8586a9b94cc Mon Sep 17 00:00:00 2001
From: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Date: Wed, 8 Jul 2026 14:26:58 +0200
Subject: Test trace of cancel requests

Enable trace for cancel test of libpq_pipeline.

Cancel requests generated with PQcancel are not traced as the
signal-safe function doesn't use the normal message construction
functions.
---
 .../modules/libpq_pipeline/libpq_pipeline.c   | 17 +++-
 .../libpq_pipeline/t/001_libpq_pipeline.pl    |  2 +-
 .../libpq_pipeline/traces/cancel.trace        | 88 +++++++++++++++++++
 3 files changed, 105 insertions(+), 2 deletions(-)
 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..9448bde9328 100644
--- a/src/test/modules/libpq_pipeline/libpq_pipeline.c
+++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c
@@ -264,6 +264,12 @@ copy_connection(PGconn *conn)
 	{
 		if (opt->val)
 		{
+			/*
+			 * We don't want the copied connection to have tracing enabled, so
+			 * skip the trace_file parameter
+			 */
+			if (strcmp(opt->keyword, "trace_file") == 0)
+				continue;
 			keywords[i] = opt->keyword;
 			vals[i] = opt->val;
 			i++;
@@ -294,6 +300,7 @@ test_cancel(PGconn *conn)
 	PGcancelConn *cancelConn;
 	PGconn	   *monitorConn;
 	char		errorbuf[256];
+	char	   *pgtrace;
 
 	fprintf(stderr, "test cancellations... ");
 
@@ -302,10 +309,18 @@ test_cancel(PGconn *conn)
 
 	/*
 	 * Make a separate connection to the database to monitor the query on the
-	 * main connection.
+	 * main connection. Tracing needs to be disabled for this connection.
 	 */
+	pgtrace = getenv("PGTRACE");
+	if (pgtrace != NULL)
+	{
+		pgtrace = pg_strdup(pgtrace);
+		unsetenv("PGTRACE");
+	}
 	monitorConn = copy_connection(conn);
 	Assert(PQstatus(monitorConn) == CONNECTION_OK);
+	if (pgtrace != NULL)
+		setenv("PGTRACE", pgtrace, 1);
 
 	/* test PQcancel */
 	send_cancellable_query(conn, monitorConn);
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 76816d6c343..8ae4a3aea2b 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 =
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..829ca7c192e
--- /dev/null
+++ b/src/test/modules/libpq_pipeline/traces/cancel.trace
@@ -0,0 +1,88 @@
+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	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	31	Parse	 "" "SELECT pg_sleep($1)" 1 NNNN
+F	21	Bind	 "" "" 0 1 3 '180' 1 0
+F	6	Describe	 P ""
+F	9	Execute	 "" 0
+F	4	Sync
+F	44	CancelRequest	 1234 5678 NNNN 'BBBB'
+B	4	ParseComplete
+B	4	BindComplete
+B	33	RowDescription	 1 "pg_sleep" NNNN 0 NNNN 4 -1 0
+B	NN	ErrorResponse	 S "ERROR" V "ERROR" C "57014" M "canceling statement due to user request" F "SSSS" L "SSSS" R "SSSS" \x00
+B	5	ReadyForQuery	 I
+F	4	Terminate
-- 
2.54.0

