On Fri, 6 Dec 2024 06:25:49 +0900
Yugo Nagata <[email protected]> wrote:
> 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
Another idea is not call PortalRun in this case like the attached patch.
Which approach is better? Or, should we fix in other approach?
> Regards,
> Yugo Nagata
>
> --
> Yugo Nagata <[email protected]>
--
Yugo Nagata <[email protected]>
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 42af768045..d06a2e6d1a 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2257,13 +2257,20 @@ exec_execute_message(const char *portal_name, long
max_rows)
if (max_rows <= 0)
max_rows = FETCH_ALL;
- completed = PortalRun(portal,
- max_rows,
- true, /* always top level */
- !execute_is_fetch && max_rows
== FETCH_ALL,
- receiver,
- receiver,
- &qc);
+ if (portal->atEnd)
+ {
+ CopyQueryCompletion(&qc, &portal->qc);
+ qc.nprocessed = 0;
+ completed = true;
+ }
+ else
+ completed = PortalRun(portal,
+ max_rows,
+ true, /* always top
level */
+ !execute_is_fetch &&
max_rows == FETCH_ALL,
+ receiver,
+ receiver,
+ &qc);
receiver->rDestroy(receiver);