On Fri, 6 Dec 2024 06:25:49 +0900
Yugo Nagata <nag...@sraoss.co.jp> 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 <nag...@sraoss.co.jp>


-- 
Yugo Nagata <nag...@sraoss.co.jp>
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);
 

Reply via email to