Обсуждение: Support named (destination) portals in extended proto for psql meta commands.
Support named (destination) portals in extended proto for psql meta commands.
От
Kirill Reshke
Дата:
I am a big fan of psql extended proto meta commands feature [0], and I
frequently use these psql commands for testing purposes while
developing [1] & [2].
Recently I had to support and test some more named portals (cursor)
use-cases for [1]. And I faced a problem, that there is no way to test
extended query bind commands for non-empty destination portal. So, I
propose to add a psql meta command just for that purpose. Something
like \bind_cursor CURSOR_NAME STMT_NAME [params..]
Per doc [3]
```
The Bind message gives the name of the source prepared statement
(empty string denotes the unnamed prepared statement), the name of the
destination portal (empty string denotes the unnamed portal), and the
values to use for any parameter placeholders present in the prepared
statement.
```
I did actually start to implement this, but I faced the issue with
libpq. The thing is,
PQsendQueryParams does not support non-unnamed portal (cursor) case,
and its workhorse,
PQsendQueryGuts also. In fact, in PQsendQueryGuts we always send empty
portal name
```
/* Construct the Bind message */
if (pqPutMsgStart(PqMsg_Bind, conn) < 0 ||
pqPuts("", conn) < 0 ||
pqPuts(stmtName, conn) < 0)
goto sendFailed;
```
Per [4] the first string is the name of the destination portal and
PQsendQueryGuts always send empty strings.
I did some archeology only to find that the PQsendQueryParams
declaration did not change since [5].
So, sending non-empty portal names was never supported in libpq?
It makes me think there was a good reason for that. Can somebody
please clarify on that?
If that's ok, I will proceed with sending patches for libpq and psql
to support $subj, if no complains.
[0] https://git.postgresql.org/cgit/postgresql.git/commit/?id=d55322b0da60a8798ffdb8b78ef90db0fb5be18e
[1] https://github.com/pg-sharding/spqr/pulls
[2] https://github.com/yandex/odyssey
[3] https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
[4] https://www.postgresql.org/docs/current/protocol-message-formats.html
[5] https://git.postgresql.org/cgit/postgresql.git/commit/?id=efc3a25bb02a
--
Best regards,
Kirill Reshke
Re: Support named (destination) portals in extended proto for psql meta commands.
От
Jelte Fennema-Nio
Дата:
On Sat, 13 Dec 2025 at 09:56, Kirill Reshke <reshkekirill@gmail.com> wrote: > And I faced a problem, that there is no way to test > extended query bind commands for non-empty destination portal. So, I > propose to add a psql meta command just for that purpose. Something > like \bind_cursor CURSOR_NAME STMT_NAME [params..] Probably call it bind_portal though. So far we've aligned the meta command names with the protocol/libpq names (e.g. \parse instead of \prepare) > So, sending non-empty portal names was never supported in libpq? > It makes me think there was a good reason for that. Can somebody > please clarify on that? No good reason, just no-one spent the time to implement it. libpq hasn't implemented most of the somewhat more exotic parts of the protocol. So yeah, addition is definitely welcome.
Re: Support named (destination) portals in extended proto for psql meta commands.
От
Sami Imseih
Дата:
Hi, Thanks for raising this! > I am a big fan of psql extended proto meta commands feature [0], and I > frequently use these psql commands for testing purposes while > developing [1] & [2]. +1 > Recently I had to support and test some more named portals (cursor) > use-cases for [1]. And I faced a problem, that there is no way to test > extended query bind commands for non-empty destination portal. Same here [0], I ended up using JDBC to test my scenario for named portals, but could not add in-core tests. > So, I propose to add a psql meta command just for that purpose. Something > like \bind_cursor CURSOR_NAME STMT_NAME [params..] I like this idea, although instead of \bind_cursor ( or \bind_portal) what about allowing a \portal to be optionally supplied to the end of a \bind_named? This is easier to rationalize IMO because adding \bind_portal while we have \bind_named is confusing. If the \portal is not supplied, then an unnamed portal is used (current state), and if it's supplied a named portal is used. Also, with this syntax we can allow for a max_rows to be supplied to the portal, if we don't want to fetch the portal to completion. ``` \portal name [max_rows] -- prepare the statements select from mytab limit $1 \parse p1 -- bind/execute the statement, optionally to a portal \bind_named p1 10 \portal portalname \g \bind_named p1 50 \portal portalname \g -- bind/execute the statement, optionally to a portal, with max_rows \bind_named p1 50 \portal portalname 50 \g \bind_named p1 50 \portal portalname 40 \g ``` The syntax may seem awkward, but we already do this with \bind, where the meta command is not at the start. ``` select $ \bind 1 \g ``` [0] https://www.postgresql.org/message-id/CAA5RZ0s-JLjD4E7shD9otcqJTgy-1K7FLrs9F%3D0QCC5qn_bMrQ%40mail.gmail.com -- Sami Imseih Amazon Web Services (AWS)