Hi,

I notice that the following Assert in PortalRun fails when a same portal is
executed more than once by an Execute message whose "max number of rows"
is specified to zero, that is, "no limit".  

        /* Set run_once flag.  Shouldn't be clear if previously set. */
        Assert(!portal->run_once || run_once);
        portal->run_once = run_once;

I tested this using pgproto [1] in Pgpool-II.

I believe the server should return CommanComplete normally in this case. 
his can be fixed by not setting execute_is_fetch flag (run_once as the result)
when the portal is already completed since no rows will be fetched in this case.
I've attached a pach in this approach.

[1] https://www.pgpool.net/docs/latest/en/html/pgproto.html

Regards,
Yugo Nagata

-- 
Yugo Nagata <nag...@sraoss.co.jp>
>From f993f0af9e52d83f5c03fb18d0a8199b0377c62d Mon Sep 17 00:00:00 2001
From: Yugo Nagata <nag...@sraoss.co.jp>
Date: Fri, 6 Dec 2024 03:10:48 +0900
Subject: [PATCH] Prevent Assert failure when a completed portal is run again

---
 src/backend/tcop/postgres.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 42af768045..3d898392ea 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2204,12 +2204,12 @@ exec_execute_message(const char *portal_name, long max_rows)
 	start_xact_command();
 
 	/*
-	 * If we re-issue an Execute protocol request against an existing portal,
-	 * 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.
+	 * If we re-issue an Execute protocol request against an existing
+	 * incompleted portal, then we are only fetching more rows rather than
+	 * completely re-executing the query from the start. atStart and atEnd
+	 * never reset for a v3 portal, so we are safe to use this check.
 	 */
-	execute_is_fetch = !portal->atStart;
+	execute_is_fetch = !(portal->atStart || portal->atEnd);
 
 	/* Log immediately if dictated by log_statement */
 	if (check_log_statement(portal->stmts))
-- 
2.34.1

Reply via email to