pg 1.6.0.rc1 → 1.6.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/{History.md → CHANGELOG.md} +28 -0
- data/Gemfile +1 -1
- data/README.ja.md +1 -1
- data/README.md +2 -1
- data/Rakefile +31 -7
- data/ext/extconf.rb +51 -13
- data/ext/pg.h +1 -0
- data/ext/pg_binary_encoder.c +8 -1
- data/ext/pg_coder.c +49 -0
- data/ext/pg_connection.c +31 -10
- data/ext/pg_text_encoder.c +18 -5
- data/ext/pg_type_map_by_column.c +1 -0
- data/ext/pg_type_map_by_oid.c +2 -0
- data/lib/pg/basic_type_map_for_queries.rb +7 -3
- data/lib/pg/cancel_connection.rb +26 -3
- data/lib/pg/coder.rb +2 -1
- data/lib/pg/connection.rb +84 -19
- data/lib/pg/version.rb +1 -1
- data/misc/yugabyte/Dockerfile +9 -0
- data/misc/yugabyte/docker-compose.yml +28 -0
- data/misc/yugabyte/pg-test.rb +45 -0
- data/pg.gemspec +3 -1
- data/ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch +21 -0
- data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data.tar.gz.sig +0 -0
- metadata +26 -19
- metadata.gz.sig +0 -0
- data/Manifest.txt +0 -72
data/lib/pg/connection.rb
CHANGED
@@ -625,7 +625,6 @@ class PG::Connection
|
|
625
625
|
# On older client library a pure ruby implementation is used.
|
626
626
|
def cancel
|
627
627
|
cancon = PG::CancelConnection.new(self)
|
628
|
-
cancon.async_connect_timeout = conninfo_hash[:connect_timeout]
|
629
628
|
cancon.async_cancel
|
630
629
|
rescue PG::Error => err
|
631
630
|
err.to_s
|
@@ -674,20 +673,35 @@ class PG::Connection
|
|
674
673
|
alias async_cancel cancel
|
675
674
|
|
676
675
|
module Pollable
|
677
|
-
# Track the progress of the connection, waiting for the socket to become readable/writable before polling it
|
678
|
-
|
676
|
+
# Track the progress of the connection, waiting for the socket to become readable/writable before polling it.
|
677
|
+
#
|
678
|
+
# Connecting to multiple hosts is done like so:
|
679
|
+
# - All hosts are passed to PG::Connection.connect_start
|
680
|
+
# - As soon as the host is tried to connect the related host is removed from the hosts list
|
681
|
+
# - When the polling status changes to `PG::PGRES_POLLING_OK` the connection is returned and ready to use.
|
682
|
+
# - When the polling status changes to `PG::PGRES_POLLING_FAILED` connecting is aborted and a PG::ConnectionBad is raised with details to all connection attepts.
|
683
|
+
# - When a timeout occurs, connecting is restarted with the remaining hosts.
|
684
|
+
#
|
685
|
+
# The downside is that this connects only once to hosts which are listed twice when they timeout.
|
686
|
+
private def polling_loop(poll_meth)
|
687
|
+
connect_timeout = conninfo_hash[:connect_timeout]
|
679
688
|
if (timeo = connect_timeout.to_i) && timeo > 0
|
680
|
-
host_count = conninfo_hash[:host].to_s.count(",") + 1
|
689
|
+
host_count = (conninfo_hash[:hostaddr].to_s.empty? ? conninfo_hash[:host] : conninfo_hash[:hostaddr]).to_s.count(",") + 1
|
681
690
|
stop_time = timeo * host_count + Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
682
691
|
end
|
683
|
-
|
692
|
+
iopts = conninfo_hash.compact
|
693
|
+
connection_errors = []
|
684
694
|
poll_status = PG::PGRES_POLLING_WRITING
|
695
|
+
|
685
696
|
until poll_status == PG::PGRES_POLLING_OK ||
|
686
697
|
poll_status == PG::PGRES_POLLING_FAILED
|
687
698
|
|
688
699
|
# Set single timeout to parameter "connect_timeout" but
|
689
700
|
# don't exceed total connection time of number-of-hosts * connect_timeout.
|
690
701
|
timeout = [timeo, stop_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)].min if stop_time
|
702
|
+
|
703
|
+
hostcnt = remove_current_host(iopts)
|
704
|
+
|
691
705
|
event = if !timeout || timeout >= 0
|
692
706
|
# If the socket needs to read, wait 'til it becomes readable to poll again
|
693
707
|
case poll_status
|
@@ -710,17 +724,21 @@ class PG::Connection
|
|
710
724
|
end
|
711
725
|
end
|
712
726
|
end
|
727
|
+
|
713
728
|
# connection to server at "localhost" (127.0.0.1), port 5433 failed: timeout expired (PG::ConnectionBad)
|
714
729
|
# connection to server on socket "/var/run/postgresql/.s.PGSQL.5433" failed: No such file or directory
|
715
730
|
unless event
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
731
|
+
connection_errors << (error_message + "timeout expired")
|
732
|
+
if hostcnt > 0
|
733
|
+
reset_start2(self.class.parse_connect_args(iopts))
|
734
|
+
# Restart polling with waiting for writable.
|
735
|
+
# Otherwise "not connected" error is raised on Windows.
|
736
|
+
poll_status = PG::PGRES_POLLING_WRITING
|
737
|
+
next
|
720
738
|
else
|
721
|
-
|
739
|
+
finish
|
740
|
+
raise PG::ConnectionBad.new(connection_errors.join("\n").b, connection: self)
|
722
741
|
end
|
723
|
-
raise PG::ConnectionBad.new("connection to server #{connhost} failed: timeout expired", connection: self)
|
724
742
|
end
|
725
743
|
|
726
744
|
# Check to see if it's finished or failed yet
|
@@ -730,16 +748,51 @@ class PG::Connection
|
|
730
748
|
unless status == PG::CONNECTION_OK
|
731
749
|
msg = error_message
|
732
750
|
finish
|
733
|
-
raise PG::ConnectionBad.new(msg, connection: self)
|
751
|
+
raise PG::ConnectionBad.new(connection_errors.map{|e| e + "\n" }.join.b + msg, connection: self)
|
734
752
|
end
|
735
753
|
end
|
754
|
+
|
755
|
+
# Remove the host to which the connection is currently established from the option hash.
|
756
|
+
# Affected options are:
|
757
|
+
# - :host
|
758
|
+
# - :hostaddr
|
759
|
+
# - :port
|
760
|
+
#
|
761
|
+
# Return the number of remaining hosts.
|
762
|
+
private def remove_current_host(iopts)
|
763
|
+
ihosts = iopts[:host]&.split(",", -1)
|
764
|
+
ihostaddrs = iopts[:hostaddr]&.split(",", -1)
|
765
|
+
iports = iopts[:port]&.split(",", -1)
|
766
|
+
iports = iports * (ihosts || ihostaddrs).size if iports&.size == 1
|
767
|
+
|
768
|
+
idx = (ihosts || ihostaddrs || iports).index.with_index do |_, i|
|
769
|
+
(ihosts ? ihosts[i] == host : true) &&
|
770
|
+
(ihostaddrs && respond_to?(:hostaddr, true) ? ihostaddrs[i] == hostaddr : true) &&
|
771
|
+
(iports ? iports[i].to_i == port : true)
|
772
|
+
end
|
773
|
+
|
774
|
+
if idx
|
775
|
+
ihosts&.delete_at(idx)
|
776
|
+
ihostaddrs&.delete_at(idx)
|
777
|
+
iports&.delete_at(idx)
|
778
|
+
|
779
|
+
iopts.merge!(
|
780
|
+
host: ihosts.join(",")) if ihosts
|
781
|
+
iopts.merge!(
|
782
|
+
hostaddr: ihostaddrs.join(",")) if ihostaddrs
|
783
|
+
iopts.merge!(
|
784
|
+
port: iports.join(",")) if iports
|
785
|
+
end
|
786
|
+
|
787
|
+
(ihosts || ihostaddrs || iports).size
|
788
|
+
end
|
736
789
|
end
|
737
790
|
|
738
791
|
include Pollable
|
739
792
|
|
740
793
|
private def async_connect_or_reset(poll_meth)
|
741
794
|
# Track the progress of the connection, waiting for the socket to become readable/writable before polling it
|
742
|
-
polling_loop(poll_meth
|
795
|
+
polling_loop(poll_meth)
|
743
796
|
|
744
797
|
# Set connection to nonblocking to handle all blocking states in ruby.
|
745
798
|
# That way a fiber scheduler is able to handle IO requests.
|
@@ -755,7 +808,7 @@ class PG::Connection
|
|
755
808
|
# PG::Connection.new(connection_string) -> conn
|
756
809
|
# PG::Connection.new(host, port, options, tty, dbname, user, password) -> conn
|
757
810
|
#
|
758
|
-
# Create a connection to the specified server.
|
811
|
+
# === Create a connection to the specified server.
|
759
812
|
#
|
760
813
|
# +connection_hash+ must be a ruby Hash with connection parameters.
|
761
814
|
# See the {list of valid parameters}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS] in the PostgreSQL documentation.
|
@@ -779,7 +832,13 @@ class PG::Connection
|
|
779
832
|
# [+password+]
|
780
833
|
# login password
|
781
834
|
#
|
782
|
-
#
|
835
|
+
#
|
836
|
+
# If the Ruby default internal encoding is set (i.e., <code>Encoding.default_internal != nil</code>), the
|
837
|
+
# connection will have its +client_encoding+ set accordingly.
|
838
|
+
#
|
839
|
+
# Raises a PG::Error if the connection fails.
|
840
|
+
#
|
841
|
+
# === Examples:
|
783
842
|
#
|
784
843
|
# # Connect using all defaults
|
785
844
|
# PG::Connection.new
|
@@ -796,10 +855,16 @@ class PG::Connection
|
|
796
855
|
# # As an URI
|
797
856
|
# PG::Connection.new( "postgresql://user:pass@pgsql.example.com:5432/testdb?sslmode=require" )
|
798
857
|
#
|
799
|
-
#
|
800
|
-
#
|
858
|
+
# === Specifying Multiple Hosts
|
859
|
+
#
|
860
|
+
# It is possible to specify multiple hosts to connect to, so that they are tried in the given order or optionally in random order.
|
861
|
+
# In the Keyword/Value format, the host, hostaddr, and port options accept comma-separated lists of values.
|
862
|
+
# The {details to libpq}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-MULTIPLE-HOSTS] describe how it works, but there are two small differences how ruby-pg handles multiple hosts:
|
863
|
+
# - All hosts are resolved before the first connection is tried.
|
864
|
+
# This means that when +load_balance_hosts+ is set to +random+, then all resolved addresses are tried randomly in one level.
|
865
|
+
# When a host resolves to more than one address, it is therefore tried more often than a host that has only one address.
|
866
|
+
# - When a timeout occurs due to the value of +connect_timeout+, then the given +host+, +hostaddr+ and +port+ combination is not tried a second time, even if it is specified several times.
|
801
867
|
#
|
802
|
-
# Raises a PG::Error if the connection fails.
|
803
868
|
def new(*args)
|
804
869
|
conn = connect_to_hosts(*args)
|
805
870
|
|
@@ -857,7 +922,7 @@ class PG::Connection
|
|
857
922
|
iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
858
923
|
iopts = PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
|
859
924
|
|
860
|
-
if PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET && iopts[:host].to_s.empty?
|
925
|
+
if PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET && iopts[:host].to_s.empty? && iopts[:hostaddr].to_s.empty?
|
861
926
|
# Many distors patch the hardcoded default UnixSocket path in libpq to /var/run/postgresql instead of /tmp .
|
862
927
|
# We simply try them all.
|
863
928
|
iopts[:host] = "/var/run/postgresql" + # Ubuntu, Debian, Fedora, Opensuse
|
data/lib/pg/version.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
FROM yugabytedb/yugabyte:2024.1.0.0-b129
|
2
|
+
|
3
|
+
WORKDIR /app
|
4
|
+
|
5
|
+
RUN yugabyted cert generate_server_certs --hostnames=127.0.0.1 --base_dir=.
|
6
|
+
|
7
|
+
ENTRYPOINT ["yugabyted"]
|
8
|
+
CMD ["start", "--background", "false", "--ui", "false", "--tserver_flags", "use_client_to_server_encryption=true,cert_node_filename=127.0.0.1,certs_dir=/app/generated_certs/127.0.0.1"]
|
9
|
+
VOLUME /app
|
@@ -0,0 +1,28 @@
|
|
1
|
+
services:
|
2
|
+
yb:
|
3
|
+
build: .
|
4
|
+
container_name: yb
|
5
|
+
ports:
|
6
|
+
- "127.0.0.1:5433:5433"
|
7
|
+
volumes:
|
8
|
+
- certs:/app/generated_certs
|
9
|
+
healthcheck:
|
10
|
+
test: 'ysqlsh -h $$(hostname) -c \\conninfo || exit 1;'
|
11
|
+
interval: 2s
|
12
|
+
timeout: 30s
|
13
|
+
retries: 20
|
14
|
+
start_period: 10s
|
15
|
+
|
16
|
+
pg:
|
17
|
+
image: ruby:3.0
|
18
|
+
working_dir: /app
|
19
|
+
volumes:
|
20
|
+
- .:/app
|
21
|
+
- certs:/generated_certs
|
22
|
+
command: bash -c "gem inst pg-*.gem && ruby pg-test.rb"
|
23
|
+
depends_on:
|
24
|
+
yb:
|
25
|
+
condition: service_healthy
|
26
|
+
|
27
|
+
volumes:
|
28
|
+
certs:
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'pg'
|
2
|
+
|
3
|
+
conn = PG.connect(
|
4
|
+
host: 'yb',
|
5
|
+
port: 5433,
|
6
|
+
user: 'yugabyte',
|
7
|
+
dbname: 'yugabyte',
|
8
|
+
sslmode: 'require',
|
9
|
+
sslrootcert: 'app/generated_certs/127.0.0.1/ca.crt',
|
10
|
+
sslcert: 'app/generated_certs/127.0.0.1/node.127.0.0.1.crt',
|
11
|
+
sslkey: 'app/generated_certs/127.0.0.1/node.127.0.0.1.key'
|
12
|
+
)
|
13
|
+
|
14
|
+
$stdout.sync = true
|
15
|
+
# fd = File.open("pg_trace.log", "a+")
|
16
|
+
# conn.trace(fd)
|
17
|
+
|
18
|
+
begin
|
19
|
+
# Validate connection is working
|
20
|
+
res = conn.exec("SELECT version();")
|
21
|
+
res.each_row do |row|
|
22
|
+
puts "You are connected to: #{row[0]}"
|
23
|
+
end
|
24
|
+
# 53*511
|
25
|
+
# 53*767
|
26
|
+
# 53*1023
|
27
|
+
# 53*1279
|
28
|
+
# 7*1817
|
29
|
+
# 11*1487
|
30
|
+
# 13*1363
|
31
|
+
# 16*1211
|
32
|
+
# 18*1128
|
33
|
+
# 22*1984
|
34
|
+
# 27*1723
|
35
|
+
|
36
|
+
(22..53).each do |m|
|
37
|
+
(1..2048).each do |l|
|
38
|
+
hanging_query = "SELECT lpad(''::text, #{m}, '0') FROM generate_series(1, #{l});"
|
39
|
+
puts "Executing hanging query: #{hanging_query}"
|
40
|
+
conn.exec(hanging_query)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
ensure
|
44
|
+
conn.close if conn
|
45
|
+
end
|
data/pg.gemspec
CHANGED
@@ -17,8 +17,10 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
19
|
spec.metadata["source_code_uri"] = "https://github.com/ged/ruby-pg"
|
20
|
-
spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/CHANGELOG.md"
|
21
21
|
spec.metadata["documentation_uri"] = "http://deveiate.org/code/pg"
|
22
|
+
# https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#msys2-library-dependency
|
23
|
+
spec.metadata["msys2_mingw_dependencies"] = "postgresql"
|
22
24
|
|
23
25
|
# Specify which files should be added to the gem when it is released.
|
24
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
From e82c1b395162ea71279ea2170259383082e41ab0 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Lars Kanis <lars@greiz-reinsdorf.de>
|
3
|
+
Date: Sat, 12 Jul 2025 10:55:17 +0200
|
4
|
+
Subject: [PATCH] Allow static linking krb5 library
|
5
|
+
|
6
|
+
Otherwise it fails with:
|
7
|
+
Undefined symbols for architecture arm64:
|
8
|
+
"_krb5int_c_mit_des_zeroblock", referenced from:
|
9
|
+
_krb5int_des3_cbc_encrypt in libk5crypto.a(d3_aead.o)
|
10
|
+
_krb5int_des3_cbc_decrypt in libk5crypto.a(d3_aead.o)
|
11
|
+
---
|
12
|
+
src/lib/crypto/builtin/des/des_int.h | 2 +-
|
13
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
14
|
+
|
15
|
+
diff --git a/src/lib/crypto/builtin/des/des_int.h b/src/lib/crypto/builtin/des/des_int.h
|
16
|
+
index 46fed7dbd..114e48ebd 100644
|
17
|
+
--- a/lib/crypto/builtin/des/des_int.h
|
18
|
+
+++ b/lib/crypto/builtin/des/des_int.h
|
19
|
+
@@ -159,7 +159,7 @@ mit_des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out,
|
20
|
+
const mit_des_cblock ivec, int enc);
|
21
|
+
|
22
|
+
#define mit_des_zeroblock krb5int_c_mit_des_zeroblock
|
23
|
+
-extern const mit_des_cblock mit_des_zeroblock;
|
24
|
+
+const mit_des_cblock mit_des_zeroblock;
|
25
|
+
|
26
|
+
/* fin_rndkey.c */
|
27
|
+
krb5_error_code mit_des_finish_random_key(const krb5_encrypt_block *,
|
28
|
+
--
|
29
|
+
2.43.0
|
30
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
--- a/Configurations/10-main.conf
|
2
|
+
+++ b/Configurations/10-main.conf
|
3
|
+
@@ -1603,6 +1603,18 @@
|
4
|
+
multilib => "64",
|
5
|
+
},
|
6
|
+
|
7
|
+
+ "mingwarm64" => {
|
8
|
+
+ inherit_from => [ "mingw-common" ],
|
9
|
+
+ cflags => "",
|
10
|
+
+ sys_id => "MINGWARM64",
|
11
|
+
+ bn_ops => add("SIXTY_FOUR_BIT"),
|
12
|
+
+ asm_arch => 'aarch64',
|
13
|
+
+ uplink_arch => 'armv8',
|
14
|
+
+ perlasm_scheme => "win64",
|
15
|
+
+ shared_rcflag => "",
|
16
|
+
+ multilib => "-arm64",
|
17
|
+
+ },
|
18
|
+
+
|
19
|
+
#### UEFI
|
20
|
+
"UEFI" => {
|
21
|
+
inherit_from => [ "BASE_unix" ],
|
data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
From 746e8e250b265c40d9706f26560e02e8623f123f Mon Sep 17 00:00:00 2001
|
2
|
+
From: Lars Kanis <lars@greiz-reinsdorf.de>
|
3
|
+
Date: Fri, 31 Jan 2025 21:58:00 +0100
|
4
|
+
Subject: [PATCH] Use workaround of __builtin_setjmp only on MINGW on MSVCRT
|
5
|
+
|
6
|
+
Because it is not present on ARM64 on Windows and not necessary on any UCRT based toolchain.
|
7
|
+
---
|
8
|
+
src/include/c.h | 10 +++++-----
|
9
|
+
1 file changed, 5 insertions(+), 5 deletions(-)
|
10
|
+
|
11
|
+
diff --git a/src/include/c.h b/src/include/c.h
|
12
|
+
index a14c631516..33792c860c 100644
|
13
|
+
--- a/src/include/c.h
|
14
|
+
+++ b/src/include/c.h
|
15
|
+
@@ -1312,19 +1312,19 @@ extern int fdatasync(int fildes);
|
16
|
+
/*
|
17
|
+
* When there is no sigsetjmp, its functionality is provided by plain
|
18
|
+
* setjmp. We now support the case only on Windows. However, it seems
|
19
|
+
- * that MinGW-64 has some longstanding issues in its setjmp support,
|
20
|
+
- * so on that toolchain we cheat and use gcc's builtins.
|
21
|
+
+ * that MinGW-64 on x86_64 has some longstanding issues in its setjmp
|
22
|
+
+ * support, so on that toolchain we cheat and use gcc's builtins.
|
23
|
+
*/
|
24
|
+
#ifdef WIN32
|
25
|
+
-#ifdef __MINGW64__
|
26
|
+
+#if defined(__MINGW64__) && !defined(_UCRT)
|
27
|
+
typedef intptr_t sigjmp_buf[5];
|
28
|
+
#define sigsetjmp(x,y) __builtin_setjmp(x)
|
29
|
+
#define siglongjmp __builtin_longjmp
|
30
|
+
-#else /* !__MINGW64__ */
|
31
|
+
+#else /* !defined(__MINGW64__) || defined(_UCRT) */
|
32
|
+
#define sigjmp_buf jmp_buf
|
33
|
+
#define sigsetjmp(x,y) setjmp(x)
|
34
|
+
#define siglongjmp longjmp
|
35
|
+
-#endif /* __MINGW64__ */
|
36
|
+
+#endif /* defined(__MINGW64__) && !defined(_UCRT) */
|
37
|
+
#endif /* WIN32 */
|
38
|
+
|
39
|
+
/* /port compatibility functions */
|
40
|
+
--
|
41
|
+
2.43.0
|
42
|
+
|
data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
From ab793829a4ce473f1cc2bbc0e2a6f6753553255d Mon Sep 17 00:00:00 2001
|
2
|
+
From: Lars Kanis <lars@greiz-reinsdorf.de>
|
3
|
+
Date: Sun, 8 Sep 2024 13:59:05 +0200
|
4
|
+
Subject: [PATCH] libpq: Process buffered SSL read bytes to support records
|
5
|
+
>8kB on async API
|
6
|
+
|
7
|
+
The async API of libpq doesn't support SSL record sizes >8kB so far.
|
8
|
+
This size isn't exceeded by vanilla PostgreSQL, but by other products using
|
9
|
+
the postgres wire protocol 3.
|
10
|
+
PQconsumeInput() reads all data readable from the socket, so that the read
|
11
|
+
condition is cleared.
|
12
|
+
But it doesn't process all the data that is pending on the SSL layer.
|
13
|
+
Also a subsequent call to PQisBusy() doesn't process it, so that the client
|
14
|
+
is triggered to wait for more readable data on the socket.
|
15
|
+
But this never arrives, so that the connection blocks infinitely.
|
16
|
+
|
17
|
+
To fix this issue call pqReadData() repeatedly until there is no buffered
|
18
|
+
SSL data left to be read.
|
19
|
+
|
20
|
+
The synchronous libpq API isn't affected, since it supports arbitrary SSL
|
21
|
+
record sizes already.
|
22
|
+
---
|
23
|
+
src/interfaces/libpq/fe-exec.c | 13 +++++++++++++
|
24
|
+
1 file changed, 13 insertions(+)
|
25
|
+
|
26
|
+
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
|
27
|
+
index 0d224a852..637894ee1 100644
|
28
|
+
--- a/src/interfaces/libpq/fe-exec.c
|
29
|
+
+++ b/src/interfaces/libpq/fe-exec.c
|
30
|
+
@@ -2006,6 +2006,19 @@ PQconsumeInput(PGconn *conn)
|
31
|
+
if (pqReadData(conn) < 0)
|
32
|
+
return 0;
|
33
|
+
|
34
|
+
+ #ifdef USE_SSL
|
35
|
+
+ /*
|
36
|
+
+ * Ensure all buffered read bytes in the SSL library are processed,
|
37
|
+
+ * which might be not the case, if the SSL record size exceeds 8k.
|
38
|
+
+ * Otherwise parseInput can't process the data.
|
39
|
+
+ */
|
40
|
+
+ while (conn->ssl_in_use && pgtls_read_pending(conn))
|
41
|
+
+ {
|
42
|
+
+ if (pqReadData(conn) < 0)
|
43
|
+
+ return 0;
|
44
|
+
+ }
|
45
|
+
+ #endif
|
46
|
+
+
|
47
|
+
/* Parsing of the data waits till later. */
|
48
|
+
return 1;
|
49
|
+
}
|
50
|
+
--
|
51
|
+
2.43.0
|
52
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'bundler/gem_helper'
|
3
|
+
|
4
|
+
class PgGemHelper < Bundler::GemHelper
|
5
|
+
attr_accessor :cross_platforms
|
6
|
+
|
7
|
+
def install
|
8
|
+
super
|
9
|
+
|
10
|
+
task "release:guard_clean" => ["release:update_history"]
|
11
|
+
|
12
|
+
task "release:update_history" do
|
13
|
+
update_history
|
14
|
+
end
|
15
|
+
|
16
|
+
task "release:rubygem_push" => ["gem:native"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def hfile
|
20
|
+
"CHANGELOG.md"
|
21
|
+
end
|
22
|
+
|
23
|
+
def headline
|
24
|
+
'^([^\n]*)(\d+\.\d+\.\d+(?:\.\w+)?)([^\w]+)([2Y][0Y][0-9Y][0-9Y]-[0-1M][0-9M]-[0-3D][0-9D])([^\w]*|$)'
|
25
|
+
end
|
26
|
+
|
27
|
+
def reldate
|
28
|
+
Time.now.strftime("%Y-%m-%d")
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_history
|
32
|
+
hin = File.read(hfile)
|
33
|
+
hout = hin.sub(/#{headline}/) do
|
34
|
+
raise "#{hfile} isn't up-to-date for version #{version} (!= #{$2})" unless $2==version.to_s
|
35
|
+
$1 + $2 + $3 + reldate + $5
|
36
|
+
end
|
37
|
+
if hout != hin
|
38
|
+
Bundler.ui.confirm "Updating #{hfile} for release."
|
39
|
+
File.write(hfile, hout)
|
40
|
+
Rake::FileUtilsExt.sh "git", "commit", hfile, "-m", "Update release date in #{hfile}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def tag_version
|
45
|
+
Bundler.ui.confirm "Tag release with annotation:"
|
46
|
+
m = File.read(hfile).match(/(?<annotation>#{headline}.*?)#{headline}/m) || raise("Unable to find release notes in #{hfile}")
|
47
|
+
Bundler.ui.info(m[:annotation].gsub(/^/, " "))
|
48
|
+
IO.popen(["git", "tag", "--file=-", version_tag], "w") do |fd|
|
49
|
+
fd.write m[:annotation]
|
50
|
+
end
|
51
|
+
yield if block_given?
|
52
|
+
rescue
|
53
|
+
Bundler.ui.error "Untagging #{version_tag} due to error."
|
54
|
+
Rake::FileUtilsExt.sh "git", "tag", "-d", version_tag
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
|
58
|
+
def rubygem_push(path)
|
59
|
+
cross_platforms.each do |ruby_platform|
|
60
|
+
super(path.gsub(/\.gem\z/, "-#{ruby_platform}.gem"))
|
61
|
+
end
|
62
|
+
super(path)
|
63
|
+
end
|
64
|
+
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.0.
|
4
|
+
version: 1.6.0.rc2
|
5
5
|
platform: ruby
|
6
|
-
original_platform: ''
|
7
6
|
authors:
|
8
7
|
- Michael Granger
|
9
8
|
- Lars Kanis
|
@@ -12,8 +11,8 @@ cert_chain:
|
|
12
11
|
- |
|
13
12
|
-----BEGIN CERTIFICATE-----
|
14
13
|
MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
15
|
-
|
16
|
-
|
14
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDEyMjkxOTU2NTZaFw0yNTEy
|
15
|
+
MjkxOTU2NTZaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
17
16
|
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
18
17
|
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
19
18
|
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
@@ -24,17 +23,17 @@ cert_chain:
|
|
24
23
|
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
25
24
|
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
26
25
|
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAoZZWzNV2XXaoSmvyamSSN+Wt/Ia+DNrU
|
27
|
+
2pc3kMEqykH6l1WiVPszr6HavQ//2I2UcSRSS5AGDdiSXcfyFmHtMBdtJHhTPcn7
|
28
|
+
4DLliB0szpvwG+ltGD8PI8eWkLaTQeFzs+0QCTavgKV+Zw56Q0J5zZvHHUMrLkUD
|
29
|
+
qhwKjdTdkrRTn9Sqi0BrIRRZGTUDdrt8qoWm35aES5arKZzytgrRD/kXfFW2LCg0
|
30
|
+
FzgTKibR4/3g8ph94kQLg/D2SMlVPkQ3ECi036mZxDC2n8V6u3rDkG5923wmrRZB
|
31
|
+
J6cqz475Q8HYORQCB68OPzkWMfC7mBo3vpSsIqRoNs1FE4FJu4FGwZG8fBSrDC4H
|
32
|
+
bZe+GtyS3e2SMjgT65zp35gLO9I7MquzYN9P6V2u1iBpTycchk5z9R1ghxzZSBT8
|
33
|
+
DrkJ9tVlPQtJB0LqT0tvBap4upnwT1xYq721b5dwH6AF4Pi6iz/dc5vnq1/MH8bV
|
34
|
+
8VbbBzzeE7MsvgkP3sHlLmY8PtuyViJ8
|
36
35
|
-----END CERTIFICATE-----
|
37
|
-
date:
|
36
|
+
date: 2025-07-16 00:00:00.000000000 Z
|
38
37
|
dependencies: []
|
39
38
|
description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
|
40
39
|
10 and later.
|
@@ -45,8 +44,8 @@ executables: []
|
|
45
44
|
extensions:
|
46
45
|
- ext/extconf.rb
|
47
46
|
extra_rdoc_files:
|
47
|
+
- CHANGELOG.md
|
48
48
|
- Contributors.rdoc
|
49
|
-
- History.md
|
50
49
|
- README-OS_X.rdoc
|
51
50
|
- README-Windows.rdoc
|
52
51
|
- README.ja.md
|
@@ -104,11 +103,10 @@ extra_rdoc_files:
|
|
104
103
|
- lib/pg/version.rb
|
105
104
|
files:
|
106
105
|
- BSDL
|
106
|
+
- CHANGELOG.md
|
107
107
|
- Contributors.rdoc
|
108
108
|
- Gemfile
|
109
|
-
- History.md
|
110
109
|
- LICENSE
|
111
|
-
- Manifest.txt
|
112
110
|
- POSTGRES
|
113
111
|
- README-OS_X.rdoc
|
114
112
|
- README-Windows.rdoc
|
@@ -189,7 +187,15 @@ files:
|
|
189
187
|
- misc/ruby-pg/README.txt
|
190
188
|
- misc/ruby-pg/Rakefile
|
191
189
|
- misc/ruby-pg/lib/ruby/pg.rb
|
190
|
+
- misc/yugabyte/Dockerfile
|
191
|
+
- misc/yugabyte/docker-compose.yml
|
192
|
+
- misc/yugabyte/pg-test.rb
|
192
193
|
- pg.gemspec
|
194
|
+
- ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch
|
195
|
+
- ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch
|
196
|
+
- ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
|
197
|
+
- ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch
|
198
|
+
- rakelib/pg_gem_helper.rb
|
193
199
|
- rakelib/task_extension.rb
|
194
200
|
- sample/array_insert.rb
|
195
201
|
- sample/async_api.rb
|
@@ -216,8 +222,9 @@ licenses:
|
|
216
222
|
metadata:
|
217
223
|
homepage_uri: https://github.com/ged/ruby-pg
|
218
224
|
source_code_uri: https://github.com/ged/ruby-pg
|
219
|
-
changelog_uri: https://github.com/ged/ruby-pg/blob/master/
|
225
|
+
changelog_uri: https://github.com/ged/ruby-pg/blob/master/CHANGELOG.md
|
220
226
|
documentation_uri: http://deveiate.org/code/pg
|
227
|
+
msys2_mingw_dependencies: postgresql
|
221
228
|
rdoc_options:
|
222
229
|
- "--main"
|
223
230
|
- README.md
|
@@ -236,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
243
|
- !ruby/object:Gem::Version
|
237
244
|
version: '0'
|
238
245
|
requirements: []
|
239
|
-
rubygems_version: 3.6.
|
246
|
+
rubygems_version: 3.6.2
|
240
247
|
specification_version: 4
|
241
248
|
summary: Pg is the Ruby interface to the PostgreSQL RDBMS
|
242
249
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|