From b86c752889aabd40e4e2f6ab1b36f090fe0abc6b Mon Sep 17 00:00:00 2001
From: Sami Imseih <simseih@amazon.com>
Date: Sat, 19 Apr 2025 08:00:27 -0500
Subject: [PATCH v2 1/1] Fix race condition between debug_query_string and
 PortalDrop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

It was discovered that temporary file logging could be associated
with incorrect query text. This is because temporary file logging
occurs when the portal is dropped, but this can occur when a new
query starts execution, such as in the case of unnamed portals.
To correct this behavior, PortalDrop should temporarily switch to
using a debug_query_string set to that of the query associated with
the portal being dropped.

Author: Frédéric Yhuel <frederic.yhuel@dalibo.com>
Discussion: https://www.postgresql.org/message-id/flat/3d07ee43-8855-42db-97e0-bad5db82d972%40dalibo.com
---
 src/backend/utils/mmgr/portalmem.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index e3526e78064..04224551cdf 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -27,6 +27,7 @@
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/timestamp.h"
+#include "tcop/tcopprot.h"
 
 /*
  * Estimate of the maximum number of open portals a user would have,
@@ -469,6 +470,8 @@ MarkPortalFailed(Portal portal)
 void
 PortalDrop(Portal portal, bool isTopCommit)
 {
+	char *save_debug_query_string;
+
 	Assert(PortalIsValid(portal));
 
 	/*
@@ -488,6 +491,17 @@ PortalDrop(Portal portal, bool isTopCommit)
 				(errcode(ERRCODE_INVALID_CURSOR_STATE),
 				 errmsg("cannot drop active portal \"%s\"", portal->name)));
 
+	/*
+	 * By the time this point is reached, a query string different from the one
+	 * referenced by this to-be-dropped portal could be used. Therefore, let's
+	 * temporarily switch the debug_query_string to report on this portal.
+	 */
+	if (portal->queryDesc && debug_query_string)
+	{
+		save_debug_query_string = pstrdup(debug_query_string);
+		debug_query_string = portal->queryDesc->sourceText;
+	}
+
 	/*
 	 * Allow portalcmds.c to clean up the state it knows about, in particular
 	 * shutting down the executor if still active.  This step potentially runs
@@ -596,6 +610,8 @@ PortalDrop(Portal portal, bool isTopCommit)
 	/* release subsidiary storage */
 	MemoryContextDelete(portal->portalContext);
 
+	debug_query_string = save_debug_query_string;
+
 	/* release portal struct (it's in TopPortalContext) */
 	pfree(portal);
 }
-- 
2.39.5 (Apple Git-154)

