Re: Add new protocol message to change GUCs for usage with future protocol-only GUCs

Heikki Linnakangas <hlinnaka@iki.fi>

From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Jacob Champion <jacob.champion@enterprisedb.com>, Jelte Fennema-Nio <postgres@jeltef.nl>
Cc: Robert Haas <robertmhaas@gmail.com>, Tom Lane <tgl@sss.pgh.pa.us>, Jacob Burroughs <jburroughs@instructure.com>, Dave Cramer <davecramer@gmail.com>, Peter Smith <smithpb2250@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, "Andrey M. Borodin" <x4mmm@yandex-team.ru>, Pavel Stehule <pavel.stehule@gmail.com>, Jeff Davis <pgsql@j-davis.com>, Peter Eisentraut <peter@eisentraut.org>, Daniele Varrazzo <daniele.varrazzo@gmail.com>
Date: 2024-08-20T15:24:11Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. libpq: Add min/max_protocol_version connection options

  2. libpq: Handle NegotiateProtocolVersion message differently

  3. Add PQfullProtocolVersion() to surface the precise protocol version.

  4. Do not hardcode PG_PROTOCOL_LATEST in NegotiateProtocolVersion

  5. libpq: Handle NegotiateProtocolVersion message

  6. Provide for forward compatibility with future minor protocol versions.

On 20/08/2024 16:48, Jacob Champion wrote:
> On Mon, Aug 19, 2024 at 1:54 PM Jelte Fennema-Nio <postgres@jeltef.nl> wrote:
>> My point is that the code that breaks, actually wants to be broken in this case.
> 
> I'll turn this around then and assume for a moment that this is true:
> no matter what the use cases are, they all want to be broken for
> correctness. If this version change is allowed to break both the
> endpoints and any intermediaries on the connection, why have we chosen
> 30001 as the new reported version as opposed to, say, 4?

That's not a completely crazy idea, it crossed my mind too. And since we 
already decided to skip protocol number 3.1, how about we jump directly 
to 3.4. That way:

protocol |
  version | PQProtocolVersion()

        2 | 2   (in old unsupported library versions)
      3.0 | 3
      3.4 | 4
      3.5 | 5

and so forth.

This kind of assumes we'll never bump the major protocol version again. 
But if we do, we could jump to 40000 at that point.

> Put another way: for a middlebox on the connection (which may be
> passively observing, but also maybe actively adding new messages to
> the stream), what is guaranteed to remain the same in the protocol
> across a minor version bump? Hopefully the answer isn't "nothing"?

I don't think we can give any future guarantees like that. If you have a 
middlebox on the connection, it needs to fully understand all the 
protocol versions it supports. It cannot safely pass through protocol 
version 3.5 without knowing what changed between 3.4 and 3.5. If the 
middlebox only knows about protocol version 3.4, it should respond with 
a NegotiateProtocolVersion packet to downgrade to 3.4, even if both ends 
of the connection could speak 3.5.

That seems a bit tangential to the PQprotocolVersion() function though. 
A middlebox like that would probably not use libpq.

I'm actually not sure exactly what an application would use 
PQprotocolVersion() for. To check if a feature exists or not? None of 
the features discussed so far really need an application to check that, 
but if we introduce one, I think we'd want to add a better feature-check 
function for that purpose. Something like "bool PQsupportsFeature(conn, 
const char *feature_name)" perhaps. If we introduce optional protocol 
features rather than bump protocol version in the future, we'll need a 
different mechanism than PQprotocolVersion() anyway.

-- 
Heikki Linnakangas
Neon (https://neon.tech)