On Thu, Apr 4, 2024 at 12:45 PM Jelte Fennema-Nio <m...@jeltef.nl> wrote: > Yeah, we definitely think differently here then. To me bumping the > minor protocol version shouldn't be a thing that we would need to > carefully consider. It should be easy to do, and probably done often.
Often? I kind of hope that the protocol starts to evolve a bit more than it has, but I don't want a continuous stream of changes. That will be very hard to test and verify correctness, and a hassle for drivers to keep up with, and a mess for compatibility. > So, what approach of checking feature support are you envisioning > instead? A function for every feature? > Something like SupportsSetProtocolParameter, that returns an error > message if it's not supported and NULL otherwise. And then add such a > support function for every feature? Yeah, something like that. > I think I might agree with you that it would be nice for features that > depend on a protocol extension parameter, indeed because in the future > we might make them required and they don't have to update their logic > then. But for features only depending on the protocol version I > honestly don't see the point. A protocol version check is always going > to continue working. Sure, if we introduce it based on the protocol version then we don't need anything else. > I'm also not sure why you're saying a user is not entitled to this > information. We already provide users of libpq a way to see the full > Postgres version, and the major protocol version. I think allowing a > user to access this information is only a good thing. But I agree that > providing easy to use feature support functions is a better user > experience in some cases. I guess that's a fair point. But I'm worried that if we expose too much of the internals, we won't be able to change things later. > > But this is another example of a problem that can *easily* be fixed > > without using up the entirety of the _pq_ namespace. You can introduce > > _pq_.dont_error_on_unknown_gucs=1 or > > _pq_.dont_error_on_these_gucs='foo, bar, baz'. The distinction between > > the startup packet containing whizzbang=frob and instead containing > > _pq_.whizzbang=frob shouldn't be just whether an error is thrown if we > > don't know anything about whizzbang. > > Nice idea, but that sadly won't work well in practice. Because old PG > versions don't know about _pq_.dont_error_on_unknown_gucs. So that > would mean we'd have to wait another 5 years (and probably more) until > we could set non-_pq_-prefixed GUCs safely in the startup message, > using this approach. Hmm. I guess that is a problem. > Two side-notes: > 1. I realized there is a second benefit to using _pq_ for all GUCs > that change the protocol level that I didn't mention in my previous > email: It allows clients to assume that _pq_ prefixed GUCs will change > the wire-protocol and that they should not allow a user of the client > to set them willy-nilly. I'll go into this benefit more in the rest of > this email. > 2. To clarify: I'm suggesting that a startup packet containing > _pq_.whizzbang would actually set the _pq_.whizzbang GUC, and not the > whizzbang GUC. i.e. the _pq_ prefix is not stripped-off when parsing > the startup packet. I really intended the _pq_ prefix as a way of taking something out of the GUC namespace, not as a part of the GUC namespace that users would see. And I'm reluctant to go back on that. If we want to make pg_protocol.${NAME} mean a wire protocol parameter, well maybe there's something to that idea [insert caveats here]. But doesn't _pq_ look like something that was intended to be internal? That's certainly how I intended it. > > I want to be able to know the state of my protocol > > parameters by calling libpq functions that answer my questions > > definitively based on libpq's own internal state. libpq itself *must* > > know what compression I'm using on my connection; the server's answer > > may be different. > > I think that totally makes sense that libpq should be able to answer > those questions without contacting the server, and indeed some > introspection should be added for that. But being able to introspect > what the server thinks the setting is seems quite useful too. That > still doesn't solve the problem of poolers though. How about > introducing a new ParameterGet message type too (matching the proposed > ParameterSet), so that poolers can easily parse and intercept that > message type. Wouldn't libpq already know what value it last set? Or is this needed because it doesn't know what the other side's default is? > 2. By using PGC_PROTOCOL to indicate that those GUCs can only be > changed using ParameterSet Hmm, OK. I guess if the PGC_PROTOCOL flag makes it so that the GUC can only be set using ParameterSet, and it also makes them non-transactional, then it's fine. So to be clear, I can't set these in postgresql.conf, or postgresql.auto.conf, or via ALTER $ANYTHING, or via SET, or in any other way than by sending ParameterStatus messages. And when I send a ParameterStatus message, it doesn't matter if I'm in a good transaction, an aborted transaction, or no transaction at all, and the setting change takes effect regardless of that and regardless of any subsequent rollbacks. Is that right? I feel like maybe it's not, because you seem to be thinking that you'd also set these in the startup packet, at least... -- Robert Haas EDB: http://www.enterprisedb.com