Skip to content

Commit 4024dbd

Browse files
committed
Add method for getting the full protocol version
PostgreSQL 18 added PQfullProtocolVersion() which return the full protocol version used including the minor version, e.g. 3.0 or 3.2 rather than just 3. The new methods PG::Connection#full_protocol_version retuns the version as major version * 10000 + minor version, e.g. 30002 for version 3.2.
1 parent 01aa282 commit 4024dbd

4 files changed

Lines changed: 42 additions & 0 deletions

File tree

ext/extconf.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ module PG
316316
src + " int con(){ return PGRES_PIPELINE_SYNC; }"
317317
end
318318
have_func 'PQsetChunkedRowsMode', 'libpq-fe.h' # since PostgreSQL-17
319+
have_func 'PQfullProtocolVersion', 'libpq-fe.h' # since PostgreSQL-18
319320
have_func 'timegm'
320321
have_func 'rb_io_wait' # since ruby-3.0
321322
have_func 'rb_io_descriptor' # since ruby-3.1

ext/pg_connection.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,31 @@ pgconn_protocol_version(VALUE self)
865865
return INT2NUM(protocol_version);
866866
}
867867

868+
#ifdef HAVE_PQFULLPROTOCOLVERSION
869+
/*
870+
* call-seq:
871+
* conn.full_protocol_version -> Integer
872+
*
873+
* Interrogates the frontend/backend protocol being used, including minor version.
874+
*
875+
* Applications might wish to use this function to determine whether certain features are supported.
876+
* The result is the major version multiplied by 10000 added to the minor version, e.g. 30002 for version 3.2.
877+
* The protocol version will not change after connection startup is complete, but it could theoretically change during a connection reset.
878+
* The 3.0 protocol is supported by PostgreSQL server versions 7.4 and above.
879+
*
880+
* PG::ConnectionBad is raised if the connection is bad.
881+
*/
882+
static VALUE
883+
pgconn_full_protocol_version(VALUE self)
884+
{
885+
int protocol_version = PQfullProtocolVersion(pg_get_pgconn(self));
886+
if (protocol_version == 0) {
887+
pg_raise_conn_error( rb_eConnectionBad, self, "PQfullProtocolVersion() can't get protocol version");
888+
}
889+
return INT2NUM(protocol_version);
890+
}
891+
#endif
892+
868893
/*
869894
* call-seq:
870895
* conn.server_version -> Integer
@@ -4733,6 +4758,9 @@ init_pg_connection(void)
47334758
rb_define_method(rb_cPGconn, "transaction_status", pgconn_transaction_status, 0);
47344759
rb_define_method(rb_cPGconn, "parameter_status", pgconn_parameter_status, 1);
47354760
rb_define_method(rb_cPGconn, "protocol_version", pgconn_protocol_version, 0);
4761+
#ifdef HAVE_PQFULLPROTOCOLVERSION
4762+
rb_define_method(rb_cPGconn, "full_protocol_version", pgconn_full_protocol_version, 0);
4763+
#endif
47364764
rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
47374765
rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
47384766
rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);

spec/helpers.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ def set_etc_hosts(hostaddr, hostname)
682682
config.filter_run_excluding( :postgresql_12 ) if PG.library_version < 120000
683683
config.filter_run_excluding( :postgresql_14 ) if PG.library_version < 140000
684684
config.filter_run_excluding( :postgresql_17 ) if PG.library_version < 170000
685+
config.filter_run_excluding( :postgresql_18 ) if PG.library_version < 180000
685686
config.filter_run_excluding( :unix_socket ) if RUBY_PLATFORM=~/mingw|mswin/i
686687
config.filter_run_excluding( :scheduler ) if RUBY_VERSION < "3.0" || (RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION < "3.1") || !Fiber.respond_to?(:scheduler)
687688
config.filter_run_excluding( :scheduler_address_resolve ) if RUBY_VERSION < "3.1"

spec/pg/connection_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,18 @@
976976
end
977977
end
978978

979+
context :protocol_version, :postgresql_18 do
980+
it "should retrieve the wrie protocol version" do
981+
expect( @conn.full_protocol_version ).to eq 30000
982+
end
983+
984+
it "should raise an error on a bad connection" do
985+
conn = PG::Connection.connect_start( @conninfo )
986+
conn.finish
987+
expect{ conn.full_protocol_version }.to raise_error(PG::ConnectionBad)
988+
end
989+
end
990+
979991
it "allows a query to be cancelled" do
980992
start = Time.now
981993
@conn.set_notice_processor do |notice|

0 commit comments

Comments
 (0)