On Fri, Aug 23, 2024 at 7:42 AM Jelte Fennema-Nio <postg...@jeltef.nl> wrote:
>
> On Fri, 23 Aug 2024 at 16:02, Robert Haas <robertmh...@gmail.com> wrote:
> > Personally, I'm 100% convinced at this point that we're arguing about
> > the wrong problem. Before, I didn't know for sure whether anyone would
> > be mad if we redefined PQprotocolVersion(), but now I know that there
> > is at least one person who will be, and that's Jacob.
>
> I could be interpreting Jacob his response incorrectly, but my
> understanding is that the type of protocol changes we would actually
> do in this version bump, would determine if he's either mad or happy
> that we redefined PQprotocolVersion.

Yes, but my conclusion is pretty much the same: let's talk about the
protocol changes. If we get to the end and revert the new API because
it's no longer adding anything -- e.g. because we've decided that
minor versions no longer have any compatibility guarantees at all --
so be it.

> > If there's one
> > among regular -hackers posters, there are probably more. Since Jelte
> > doesn't seem to want to produce the patch to add
> > PQminorProtocolVersion(), I suggest that somebody else does that --
> > Jacob, do you want to? -- and we commit that and move on.
>
> Let's call it PQfullProtocolVersion and make it return 30002. I'm fine
> with updating the patch. But I'll be unavailable for the next ~3
> weeks.

Agreed on the name. I've attached a reconfigured version of v15-0003,
with an extension that should hopefully not throw off the cfbot, and a
commit message that should hopefully not misrepresent the discussion
so far?

Thanks,
--Jacob
From d4e4ccd2d08e2a6159521fa31d929b796c56383d Mon Sep 17 00:00:00 2001
From: Jacob Champion <jacob.champ...@enterprisedb.com>
Date: Fri, 23 Aug 2024 11:48:55 -0700
Subject: [PATCH] libpq: surface the full protocol version to clients

PQprotocolVersion() does not include the minor version of the protocol.
In preparation for proposals that bump that number for the first time,
add PQfullProtocolVersion() to provide it to clients that may care,
using the (major * 10000 + minor) construction already in use by
PQserverVersion().

The core of this patch and its documentation is based on work by Jelte
Fennema-Nio, but that doesn't mean he endorses how I've used it here.
There is still significant disagreement on the semantics of major vs
minor versions when it comes to the wire protocol.
---
 doc/src/sgml/libpq.sgml           | 38 ++++++++++++++++++++++++-------
 src/include/libpq/pqcomm.h        |  1 +
 src/interfaces/libpq/fe-connect.c | 10 ++++++++
 src/interfaces/libpq/libpq-fe.h   |  5 ++++
 4 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index f916fce414..eb8c232869 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2678,22 +2678,44 @@ const char *PQparameterStatus(const PGconn *conn, const 
char *paramName);
      </listitem>
     </varlistentry>
 
+    <varlistentry id="libpq-PQfullProtocolVersion">
+     
<term><function>PQfullProtocolVersion</function><indexterm><primary>PQfullProtocolVersion</primary></indexterm></term>
+
+     <listitem>
+      <para>
+       Interrogates the frontend/backend protocol being used.
+<synopsis>
+int PQfullProtocolVersion(const PGconn *conn);
+</synopsis>
+       Applications might wish to use this function to determine whether 
certain
+       features are supported. The result is formed by multiplying the server's
+       major version number by 10000 and adding the minor version number. For
+       example, version 3.2 would be returned as 30002, and version 4.0 would
+       be returned as 40000. Zero is returned if the connection is bad. The 3.0
+       protocol is supported by <productname>PostgreSQL</productname> server
+       versions 7.4 and above.
+      </para>
+      <para>
+       The protocol version will not change after connection startup is
+       complete, but it could theoretically change during a connection reset.
+      </para>
+     </listitem>
+    </varlistentry>
+
     <varlistentry id="libpq-PQprotocolVersion">
      
<term><function>PQprotocolVersion</function><indexterm><primary>PQprotocolVersion</primary></indexterm></term>
 
      <listitem>
       <para>
-       Interrogates the frontend/backend protocol being used.
+       Interrogates the frontend/backend protocol major version.
 <synopsis>
 int PQprotocolVersion(const PGconn *conn);
 </synopsis>
-       Applications might wish to use this function to determine whether 
certain
-       features are supported.  Currently, the possible values are 3
-       (3.0 protocol), or zero (connection bad).  The protocol version will
-       not change after connection startup is complete, but it could
-       theoretically change during a connection reset.  The 3.0 protocol is
-       supported by <productname>PostgreSQL</productname> server versions 7.4
-       and above.
+       Unlike <xref linkend="libpq-PQfullProtocolVersion"/>, this returns only
+       the major protocol version in use, but it is supported by a wider range
+       of libpq releases back to version 7.4. Currently, the possible values 
are
+       3 (3.0 protocol), or zero (connection bad). Prior to release version
+       14.0, libpq could additionally return 2 (2.0 protocol).
       </para>
      </listitem>
     </varlistentry>
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 527735e3db..6925f10602 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -86,6 +86,7 @@ is_unixsock_path(const char *path)
 
 #define PG_PROTOCOL_MAJOR(v)   ((v) >> 16)
 #define PG_PROTOCOL_MINOR(v)   ((v) & 0x0000ffff)
+#define PG_PROTOCOL_FULL(v)    (PG_PROTOCOL_MAJOR(v) * 10000 + 
PG_PROTOCOL_MINOR(v))
 #define PG_PROTOCOL(m,n)       (((m) << 16) | (n))
 
 /*
diff --git a/src/interfaces/libpq/fe-connect.c 
b/src/interfaces/libpq/fe-connect.c
index ab308a0580..74d9d4ab53 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -7175,6 +7175,16 @@ PQprotocolVersion(const PGconn *conn)
        return PG_PROTOCOL_MAJOR(conn->pversion);
 }
 
+int
+PQfullProtocolVersion(const PGconn *conn)
+{
+       if (!conn)
+               return 0;
+       if (conn->status == CONNECTION_BAD)
+               return 0;
+       return PG_PROTOCOL_FULL(conn->pversion);
+}
+
 int
 PQserverVersion(const PGconn *conn)
 {
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index ca3e028a51..15012c770c 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -56,6 +56,10 @@ extern "C"
 /* Indicates presence of PQsocketPoll, PQgetCurrentTimeUSec */
 #define LIBPQ_HAS_SOCKET_POLL 1
 
+/* Features added in PostgreSQL v18: */
+/* Indicates presence of PQfullProtocolVersion */
+#define LIBPQ_HAS_FULL_PROTOCOL_VERSION 1
+
 /*
  * Option flags for PQcopyResult
  */
@@ -393,6 +397,7 @@ extern PGTransactionStatusType PQtransactionStatus(const 
PGconn *conn);
 extern const char *PQparameterStatus(const PGconn *conn,
                                                                         const 
char *paramName);
 extern int     PQprotocolVersion(const PGconn *conn);
+extern int     PQfullProtocolVersion(const PGconn *conn);
 extern int     PQserverVersion(const PGconn *conn);
 extern char *PQerrorMessage(const PGconn *conn);
 extern int     PQsocket(const PGconn *conn);
-- 
2.34.1

Reply via email to