From 4a7c8b30f297189f6801076556a984baa51daa4f Mon Sep 17 00:00:00 2001 From: "okbob@github.com" Date: Sun, 3 Sep 2023 19:14:24 +0200 Subject: [PATCH 3/4] - allow to connect to server with major protocol version 3, minor version is ignored - allow to read minor protocol version --- doc/src/sgml/libpq.sgml | 17 +++++++++++++++++ src/include/libpq/pqcomm.h | 2 +- src/interfaces/libpq/exports.txt | 1 + src/interfaces/libpq/fe-connect.c | 12 +++++++++++- src/interfaces/libpq/fe-protocol3.c | 21 +++++++++++++++++---- src/interfaces/libpq/libpq-fe.h | 1 + 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index a52baa27d5..d9e5502d09 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -2576,6 +2576,23 @@ int PQprotocolVersion(const PGconn *conn); + + PQprotocolVersionFullPQprotocolVersionFull + + + + Returns complete frontend/backend protocol number. + +int PQprotocolVersionFull(const PGconn *conn); + + The frontend/backend version protocol number is an value, that composites. + major protocol number and minor protocol number. These numbers can be + separated by using macros PG_PROTOCOL_MAJOR and + PG_PROTOCOL_MINOR. + + + + PQserverVersionPQserverVersion diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index 46a0946b8b..4ea4538157 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -94,7 +94,7 @@ is_unixsock_path(const char *path) */ #define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0) -#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) +#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,1) typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt index 7e101368d5..595a4808f2 100644 --- a/src/interfaces/libpq/exports.txt +++ b/src/interfaces/libpq/exports.txt @@ -193,3 +193,4 @@ PQsendClosePrepared 190 PQsendClosePortal 191 PQlinkParameterStatus 192 PQunlinkParameterStatus 193 +PQprotocolVersionFull 194 diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index bf83a9b569..6762ed7cc5 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -2777,7 +2777,7 @@ keep_going: /* We will come back to here until there is * must persist across individual connection attempts, but we must * reset them when we start to consider a new server. */ - conn->pversion = PG_PROTOCOL(3, 0); + conn->pversion = PG_PROTOCOL(3, 1); conn->send_appname = true; #ifdef USE_SSL /* initialize these values based on SSL mode */ @@ -7234,6 +7234,16 @@ PQprotocolVersion(const PGconn *conn) return PG_PROTOCOL_MAJOR(conn->pversion); } +int +PQprotocolVersionFull(const PGconn *conn) +{ + if (!conn) + return 0; + if (conn->status == CONNECTION_BAD) + return 0; + return (int) conn->pversion; +} + int PQserverVersion(const PGconn *conn) { diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index 90d4e17e6f..e9d4d2a1ca 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -1440,10 +1440,23 @@ pqGetNegotiateProtocolVersion3(PGconn *conn) appendPQExpBufferStr(&buf, conn->workBuffer.data); } - if (their_version < conn->pversion) - libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u", - PG_PROTOCOL_MAJOR(conn->pversion), PG_PROTOCOL_MINOR(conn->pversion), - PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version)); + if (their_version != conn->pversion) + { + if ((PG_PROTOCOL_MAJOR(their_version) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST)) || + ((PG_PROTOCOL_MAJOR(their_version) == PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST)) && + (PG_PROTOCOL_MINOR(their_version) < PG_PROTOCOL_MINOR(PG_PROTOCOL_EARLIEST))) || + (PG_PROTOCOL_MAJOR(their_version) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST)) || + ((PG_PROTOCOL_MAJOR(their_version) == PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST)) && + (PG_PROTOCOL_MINOR(their_version) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))) + { + libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u", + PG_PROTOCOL_MAJOR(conn->pversion), PG_PROTOCOL_MINOR(conn->pversion), + PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version)); + } + else + conn->pversion = their_version; + } + if (num > 0) { appendPQExpBuffer(&conn->errorMessage, diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index ba3ad7e0aa..ae824ff9f5 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -347,6 +347,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 PQprotocolVersionFull(const PGconn *conn); extern int PQserverVersion(const PGconn *conn); extern char *PQerrorMessage(const PGconn *conn); extern int PQsocket(const PGconn *conn); -- 2.41.0