From 256ce554246cc459dc4efdab69a00d3503fca45e Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Wed, 11 Sep 2024 14:16:24 +0900
Subject: [PATCH 3/3] Report query ID for execute fetch in extended query
 protocol

This concerns for example queries that execute a query through a portal,
then do *not* require going through an execution again because all the
tuples to return are stored in a tuplestore part of a portal.  For
example, this would happen for a RETURNING query with a fetch_size small
enough to require multiple fetch batch with a message sequence like:
<execute>
<fetch>
<...>
<fetch>
<commit>

The query ID would be set in the initial execute message, but not in any
of the follow up execute fetch messages.

Perhaps backpatch to 14?  This would report new information in
pg_stat_activity, and nobody has complained about that, either.
---
 src/backend/tcop/postgres.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 8bc6bea113..0f549468d2 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2185,9 +2185,28 @@ exec_execute_message(const char *portal_name, long max_rows)
 	 * then we are only fetching more rows rather than completely re-executing
 	 * the query from the start. atStart is never reset for a v3 portal, so we
 	 * are safe to use this check.
+	 *
+	 * The query ID is lost in this case as of pgstat_report_activity() done
+	 * above, so set it again when only fetching rows.
 	 */
 	execute_is_fetch = !portal->atStart;
 
+	if (execute_is_fetch)
+	{
+		ListCell	   *lc;
+
+		foreach(lc, portal->stmts)
+		{
+			PlannedStmt *stmt = lfirst_node(PlannedStmt, lc);
+
+			if (stmt->queryId != UINT64CONST(0))
+			{
+				pgstat_report_query_id(stmt->queryId, false);
+				break;
+			}
+		}
+	}
+
 	/* Log immediately if dictated by log_statement */
 	if (check_log_statement(portal->stmts))
 	{
-- 
2.45.2

