-
-
Notifications
You must be signed in to change notification settings - Fork 450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support unnamed statements #1067
Conversation
This will break pipelined queries. |
@sfackler Can you elaborate on this? My understanding is the parse/bind/execute is sent as a single unit, and would therefore be unaffected by pipelining? |
Oh wait, the same query is prepared both at preparation time and at each use? I guess that works but it feels like an pretty janky setup, and defeats the purpose of statement preparation. IMO, if you're running pgbouncer in transaction mode you should just make sure you scope your statements within the transaction that uses them. If you're using it in statement mode, either don't, or deal with |
Yeah the prepare flow is only for this library to get a handle on those types that it expects. It is definitely not ideal BUT it is not worse than the current implementation of doing a named prepare for every query. I don't think I agree that |
It is worse - it means you cannot avoid preparing frequently-executed queries on every execution. |
To be clear: let statement = client.prepare("...").await?;
client.query(statement, &[]).await?; client.query("...", &[]).await?; The first example is not changed at all by this PR. The second example behaves almost the identically, except that it uses an unnamed statement instead of a named statement. No additional network calls or round trips are introduced in either case by this PR. This matches how other postgres libraries (including libpq) generally behave. |
@sfackler any chance of this getting merged? I really don't want to have to maintain a fork of this library... If you're still against this for some reason, maybe it could be behind a cargo feature? |
@sfackler We would love to see this one merged too as we're about to launch the Postgres connector at Grafbase. |
We at @prisma would also be very interested in this. Right now, we do a weird dance of wrapping all queries in transactions, and each time deallocating the named prepared statements when talking to a PgBouncer instance in transaction mode - which adds up to 3 additional roundtrips for 1 query and has an obvious very bad effect on our performance. With unnamed (but still prepared) statements we could probably avoid this. |
It would be extra cool to get this merged... Now, again, needing to use a fork of this crate for a production system. |
@sfackler any word here? |
@sfackler anything? should i just close this? i really don't want to fork... |
Introduce a new `query_with_param_types` method that allows to specify Postgres type parameters. This obviated the need to use prepared statementsjust to obtain parameter types for a query. It then combines parse, bind, and execute in a single packet. Related: sfackler#1017, sfackler#1067
Refs: #1017
Refs: #1044
This PR implements unnamed statements when querying the database. This is not a performance optimization. The library still uses a "prepared" statement in order to parse the columns and types of queries, so round trips are not reduced (although we don't need to send an additional query to clean up the named prepared statement, which is nice). The reason for this change is to enable queries against pgbouncer instances which are running in transaction or statement pooling modes. A named prepared statement cannot be used in these modes, because the connection may be swapped from under you between preparing the statement and using it.
I found this helpful in understanding what was going on while I was debugging this problem: https://jpcamara.com/2023/04/12/pgbouncer-is-useful.html#prepared-statements
While writing this I also changed the "unexpected message" errors to help me debug, but I can remove that from this PR if you feel it is out of scope.