pg 1.6.3-aarch64-linux → 1.7.0-aarch64-linux
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/CHANGELOG.md +52 -6
- data/Gemfile +1 -0
- data/README.ja.md +81 -30
- data/README.md +14 -7
- data/Rakefile +8 -7
- data/certs/larskanis-2026.pem +24 -0
- data/ext/extconf.rb +18 -28
- data/ext/gvl_wrappers.c +2 -2
- data/ext/gvl_wrappers.h +40 -160
- data/ext/pg.c +8 -12
- data/ext/pg.h +8 -11
- data/ext/pg_binary_decoder.c +6 -2
- data/ext/pg_binary_encoder.c +7 -0
- data/ext/pg_cancel_connection.c +6 -6
- data/ext/pg_coder.c +4 -4
- data/ext/pg_connection.c +196 -159
- data/ext/pg_copy_coder.c +34 -21
- data/ext/pg_record_coder.c +10 -6
- data/ext/pg_result.c +42 -26
- data/ext/pg_text_decoder.c +6 -6
- data/ext/pg_text_encoder.c +7 -2
- data/ext/pg_tuple.c +1 -1
- data/ext/pg_type_map.c +41 -1
- data/ext/pg_type_map_all_strings.c +2 -2
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +2 -2
- data/ext/pg_type_map_by_oid.c +1 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/lib/3.1/pg_ext.so +0 -0
- data/lib/3.2/pg_ext.so +0 -0
- data/lib/3.3/pg_ext.so +0 -0
- data/lib/3.4/pg_ext.so +0 -0
- data/lib/4.0/pg_ext.so +0 -0
- data/lib/pg/basic_type_map_based_on_result.rb +5 -0
- data/lib/pg/basic_type_map_for_queries.rb +9 -2
- data/lib/pg/basic_type_map_for_results.rb +5 -0
- data/lib/pg/connection.rb +166 -76
- data/lib/pg/text_decoder/date.rb +1 -1
- data/lib/pg/text_decoder/json.rb +1 -1
- data/lib/pg/text_encoder/date.rb +7 -1
- data/lib/pg/text_encoder/json.rb +1 -1
- data/lib/pg/version.rb +1 -1
- data/misc/yugabyte/docker-compose.yml +1 -1
- data/pg.gemspec +1 -1
- data/ports/aarch64-linux/lib/libpq-ruby-pg.so.1 +0 -0
- data/sample/async_mixed.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +17 -19
- metadata.gz.sig +0 -0
- data/lib/3.0/pg_ext.so +0 -0
- data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +0 -21
- data/ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +0 -52
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0001-Allow-static-linking-krb5-library.patch +0 -0
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0002-unknown-command-line-option-on-clang.patch +0 -0
- /data/ports/patches/postgresql/{18.1 → 18.6}/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +0 -0
|
@@ -57,6 +57,11 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
|
57
57
|
init_encoders
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
# Returns the PG::BasicTypeRegistry::CoderMapsBundle used to translate encoders to OIDs.
|
|
61
|
+
def coder_maps_bundle
|
|
62
|
+
@coder_maps
|
|
63
|
+
end
|
|
64
|
+
|
|
60
65
|
class UndefinedDefault
|
|
61
66
|
def self.call(oid_name, format)
|
|
62
67
|
raise UndefinedEncoder, "no encoder defined for type #{oid_name.inspect} format #{format}"
|
|
@@ -177,13 +182,14 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
|
177
182
|
end
|
|
178
183
|
|
|
179
184
|
DEFAULT_TYPE_MAP = PG.make_shareable({
|
|
180
|
-
TrueClass => [
|
|
181
|
-
FalseClass => [
|
|
185
|
+
TrueClass => [0, 'bool', 'bool'],
|
|
186
|
+
FalseClass => [0, 'bool', 'bool'],
|
|
182
187
|
# We use text format and no type OID for numbers, because setting the OID can lead
|
|
183
188
|
# to unnecessary type conversions on server side.
|
|
184
189
|
Integer => [0, 'int8'],
|
|
185
190
|
Float => [0, 'float8'],
|
|
186
191
|
Time => [0, 'timestamptz'],
|
|
192
|
+
Date => [0, 'date'],
|
|
187
193
|
# We use text format and no type OID for IPAddr, because setting the OID can lead
|
|
188
194
|
# to unnecessary inet/cidr conversions on the server side.
|
|
189
195
|
IPAddr => [0, 'inet'],
|
|
@@ -200,6 +206,7 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
|
200
206
|
String => [0, '_text'],
|
|
201
207
|
Float => [0, '_float8'],
|
|
202
208
|
Time => [0, '_timestamptz'],
|
|
209
|
+
Date => [0, '_date'],
|
|
203
210
|
IPAddr => [0, '_inet'],
|
|
204
211
|
}.merge(has_bigdecimal ? {BigDecimal => [0, '_numeric']} : {}))
|
|
205
212
|
private_constant :DEFAULT_ARRAY_TYPE_MAP
|
|
@@ -101,4 +101,9 @@ class PG::BasicTypeMapForResults < PG::TypeMapByOid
|
|
|
101
101
|
typenames = @coder_maps.typenames_by_oid
|
|
102
102
|
self.default_type_map = WarningTypeMap.new(typenames)
|
|
103
103
|
end
|
|
104
|
+
|
|
105
|
+
# Returns the PG::BasicTypeRegistry::CoderMapsBundle used to translate result OIDs to decoders.
|
|
106
|
+
def coder_maps_bundle
|
|
107
|
+
@coder_maps
|
|
108
|
+
end
|
|
104
109
|
end
|
data/lib/pg/connection.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require 'pg' unless defined?( PG )
|
|
5
|
-
require 'io/wait' unless ::IO.public_instance_methods(false).include?(:wait_readable) # for ruby < 3.0
|
|
6
5
|
require 'socket'
|
|
7
6
|
|
|
8
7
|
# The PostgreSQL connection class. The interface for this class is based on
|
|
@@ -13,7 +12,7 @@ require 'socket'
|
|
|
13
12
|
# For example, to send query to the database on the localhost:
|
|
14
13
|
#
|
|
15
14
|
# require 'pg'
|
|
16
|
-
# conn = PG::Connection.open(:
|
|
15
|
+
# conn = PG::Connection.open(dbname: 'test')
|
|
17
16
|
# res = conn.exec_params('SELECT $1 AS a, $2 AS b, $3 AS c', [1, 2, nil])
|
|
18
17
|
# # Equivalent to:
|
|
19
18
|
# # res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
|
@@ -306,22 +305,19 @@ class PG::Connection
|
|
|
306
305
|
# and a +COMMIT+ at the end of the block, or
|
|
307
306
|
# +ROLLBACK+ if any exception occurs.
|
|
308
307
|
def transaction
|
|
309
|
-
rollback = false
|
|
310
308
|
exec "BEGIN"
|
|
311
309
|
yield(self)
|
|
312
|
-
rescue PG::RollbackTransaction
|
|
313
|
-
|
|
314
|
-
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
|
315
|
-
block
|
|
316
|
-
exec "ROLLBACK"
|
|
317
|
-
rescue Exception
|
|
318
|
-
rollback = true
|
|
319
|
-
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
|
320
|
-
block
|
|
321
|
-
exec "ROLLBACK"
|
|
310
|
+
rescue PG::RollbackTransaction => error
|
|
311
|
+
rescue Exception => error
|
|
322
312
|
raise
|
|
323
313
|
ensure
|
|
324
|
-
|
|
314
|
+
if error || Thread.current.status == "aborting"
|
|
315
|
+
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
|
316
|
+
block
|
|
317
|
+
exec("ROLLBACK")
|
|
318
|
+
else
|
|
319
|
+
exec("COMMIT")
|
|
320
|
+
end
|
|
325
321
|
end
|
|
326
322
|
|
|
327
323
|
### Returns an array of Hashes with connection defaults. See ::conndefaults
|
|
@@ -555,33 +551,30 @@ class PG::Connection
|
|
|
555
551
|
alias async_pipeline_sync pipeline_sync
|
|
556
552
|
end
|
|
557
553
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
algorithm ||= exec("SHOW password_encryption").getvalue(0,0)
|
|
581
|
-
sync_encrypt_password(password, username, algorithm)
|
|
582
|
-
end
|
|
583
|
-
alias async_encrypt_password encrypt_password
|
|
554
|
+
# call-seq:
|
|
555
|
+
# conn.encrypt_password( password, username, algorithm=nil ) -> String
|
|
556
|
+
#
|
|
557
|
+
# This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
|
|
558
|
+
# It is good practice not to send the original cleartext password in such a command, because it might be exposed in command logs, activity displays, and so on.
|
|
559
|
+
# Instead, use this function to convert the password to encrypted form before it is sent.
|
|
560
|
+
#
|
|
561
|
+
# The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
|
|
562
|
+
# +algorithm+ specifies the encryption algorithm to use to encrypt the password.
|
|
563
|
+
# Currently supported algorithms are +md5+ and +scram-sha-256+ (+on+ and +off+ are also accepted as aliases for +md5+, for compatibility with older server versions).
|
|
564
|
+
# Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
|
|
565
|
+
# If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
|
|
566
|
+
# That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
|
|
567
|
+
# If you wish to use the default algorithm for the server but want to avoid blocking, query +password_encryption+ yourself before calling #encrypt_password, and pass that value as the algorithm.
|
|
568
|
+
#
|
|
569
|
+
# Return value is the encrypted password.
|
|
570
|
+
# The caller can assume the string doesn't contain any special characters that would require escaping.
|
|
571
|
+
#
|
|
572
|
+
# See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
|
|
573
|
+
def encrypt_password( password, username, algorithm=nil )
|
|
574
|
+
algorithm ||= exec("SHOW password_encryption").getvalue(0,0)
|
|
575
|
+
sync_encrypt_password(password, username, algorithm)
|
|
584
576
|
end
|
|
577
|
+
alias async_encrypt_password encrypt_password
|
|
585
578
|
|
|
586
579
|
# call-seq:
|
|
587
580
|
# conn.reset()
|
|
@@ -592,7 +585,9 @@ class PG::Connection
|
|
|
592
585
|
# Use connection options from PG::Connection.new to reconnect with the same options but with renewed DNS resolution.
|
|
593
586
|
# Use conninfo_hash as a fallback when connect_start was used to create the connection object.
|
|
594
587
|
iopts = @iopts_for_reset || conninfo_hash.compact
|
|
595
|
-
if
|
|
588
|
+
if iopts[:host] && !iopts[:host].empty? &&
|
|
589
|
+
iopts[:port] && !iopts[:port].empty? &&
|
|
590
|
+
PG.library_version >= 100000
|
|
596
591
|
iopts = self.class.send(:resolve_hosts, iopts)
|
|
597
592
|
end
|
|
598
593
|
conninfo = self.class.parse_connect_args( iopts );
|
|
@@ -621,7 +616,7 @@ class PG::Connection
|
|
|
621
616
|
# Returns +nil+ on success, or a string containing the
|
|
622
617
|
# error message if a failure occurs.
|
|
623
618
|
#
|
|
624
|
-
# On PostgreSQL-17+ client
|
|
619
|
+
# On PostgreSQL-17+ client library the class PG::CancelConnection is used.
|
|
625
620
|
# On older client library a pure ruby implementation is used.
|
|
626
621
|
def cancel
|
|
627
622
|
cancon = PG::CancelConnection.new(self)
|
|
@@ -672,6 +667,101 @@ class PG::Connection
|
|
|
672
667
|
end
|
|
673
668
|
alias async_cancel cancel
|
|
674
669
|
|
|
670
|
+
PLACEHOLDER_RE = /
|
|
671
|
+
'(?:''|[^'])*' | # string literal
|
|
672
|
+
"(?:""|[^"])*" | # quoted identifier
|
|
673
|
+
--[^\n]* | # line comment
|
|
674
|
+
\/\*.*?\*\/ | # block comment
|
|
675
|
+
\$\$.*?\$\$ | # dollar-quoted string. E.g. $$ $1 $$
|
|
676
|
+
\$(?<__dq_tag>[A-Za-z_][A-Za-z_0-9]*)\$.*?\$\k<__dq_tag>\$ | # named dollar-quoted string. E.g. $foo$ $1 $foo$
|
|
677
|
+
(?<placeholder>\$(?:[1-9]\d*)) # placeholder we are interested in
|
|
678
|
+
/mx
|
|
679
|
+
private_constant :PLACEHOLDER_RE
|
|
680
|
+
SAFE_TYPE_NAME_PART_RE = /\A[A-Za-z_][A-Za-z0-9_$]*\z/
|
|
681
|
+
private_constant :SAFE_TYPE_NAME_PART_RE
|
|
682
|
+
|
|
683
|
+
private def quote_type_name(name)
|
|
684
|
+
name = name.to_s.dup
|
|
685
|
+
array_suffix = name.slice!(/(?:\[\])+\z/) || ""
|
|
686
|
+
name = name.split(".", -1).map do |part|
|
|
687
|
+
SAFE_TYPE_NAME_PART_RE.match?(part) ? part : quote_ident(part)
|
|
688
|
+
end.join(".")
|
|
689
|
+
name + array_suffix
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
# Compiles your prepared SQL statement and the given positional arguments into plain SQL string.
|
|
693
|
+
#
|
|
694
|
+
# The resulting SQL string can be used with +conn.exec+ like the prepared SQL statement and parameters with +conn.exec_params+.
|
|
695
|
+
# +conn.exec_params+ is usually preferred because it's faster and safer.
|
|
696
|
+
# +embed_params+ is intended for debugging messages with positional parameters.
|
|
697
|
+
# It avoids manual insertion for later inspection in +psql+ or so.
|
|
698
|
+
#
|
|
699
|
+
# When using PG::Connection#exec_params, it's possible to set the numeric database type OID of a parameter by either a hash with +:type+ key, or by PG::Coder#oid .
|
|
700
|
+
# +embed_params+ casts the parameter the same way, but needs the name of the type instead its OID.
|
|
701
|
+
# That name must be provided by either a +:typename+ key in addition to the +:type+ OID or by PG::Coder#name in addition to PG::Coder#oid.
|
|
702
|
+
#
|
|
703
|
+
# Only text parameter format can be embedded into SQL text.
|
|
704
|
+
# Binary data ( <tt>:format => 1</tt> or PG::Coder#format == 1 ) raises an ArgumentError.
|
|
705
|
+
# However the common pattern of sending BYTEA (OID 17) data as format 1, which avoids escapting large blobs, is recognized and probably escaped into the SQL result string.
|
|
706
|
+
#
|
|
707
|
+
# Example:
|
|
708
|
+
# conn.embed_params('SELECT $1 AS a, $2 AS b, $3 AS c', [1, 2, {value: "\0", type: 17, format: 1}])
|
|
709
|
+
# => "SELECT '1' AS a, '2' AS b, '\\x00'::bytea AS c"
|
|
710
|
+
def embed_params(sql, params, type_map: type_map_for_queries)
|
|
711
|
+
return sql if params.empty?
|
|
712
|
+
|
|
713
|
+
oid_to_typecast = proc do |oid, tname, errtext|
|
|
714
|
+
if oid && oid > 0
|
|
715
|
+
if tname.to_s.empty?
|
|
716
|
+
raise(ArgumentError, "Database type name of OID #{oid.inspect} missing#{errtext}")
|
|
717
|
+
else
|
|
718
|
+
"::#{quote_type_name(tname)}"
|
|
719
|
+
end
|
|
720
|
+
end
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
encoders = type_map.query_param_encoders(params)
|
|
724
|
+
params = encoders.map.with_index do |enc, i|
|
|
725
|
+
value = params[i]
|
|
726
|
+
case value
|
|
727
|
+
when NilClass
|
|
728
|
+
'NULL'
|
|
729
|
+
when PG::BasicTypeMapForQueries::BinaryData
|
|
730
|
+
"'#{ escape_bytea(value) }'"
|
|
731
|
+
else
|
|
732
|
+
if enc
|
|
733
|
+
raise ArgumentError, "binary encoded parameter from #{enc.inspect} cannot be inserted into SQL text" if enc.format != 0
|
|
734
|
+
"'#{escape(enc.encode(value))}'#{oid_to_typecast[enc.oid, enc.name, " - please set name of encoder #{enc.inspect}"]}"
|
|
735
|
+
elsif Hash === value
|
|
736
|
+
typename = value[:format] == 1 && value[:type] == 17 ?
|
|
737
|
+
"::bytea" : oid_to_typecast[value[:type], value[:typename], " - please set parameter key :typename"]
|
|
738
|
+
|
|
739
|
+
case value[:value]
|
|
740
|
+
when NilClass
|
|
741
|
+
"NULL#{typename}"
|
|
742
|
+
else
|
|
743
|
+
if value[:format] == 1
|
|
744
|
+
raise ArgumentError, "binary encoded parameter with OID #{value[:type].inspect} cannot be inserted into SQL text" if value[:type] && value[:type] != 17
|
|
745
|
+
"'#{escape_bytea(value[:value].to_s)}'#{typename}"
|
|
746
|
+
else
|
|
747
|
+
"'#{escape(value[:value].to_s)}'#{typename}"
|
|
748
|
+
end
|
|
749
|
+
end
|
|
750
|
+
else
|
|
751
|
+
"'#{escape(value.to_s)}'"
|
|
752
|
+
end
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
sql.gsub(PLACEHOLDER_RE).each do |matched|
|
|
757
|
+
placeholder = Regexp.last_match[:placeholder]
|
|
758
|
+
# Do not replace non-positional args string and pass it as is
|
|
759
|
+
next matched unless placeholder
|
|
760
|
+
|
|
761
|
+
params[placeholder[1..].to_i - 1]
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
|
|
675
765
|
module Pollable
|
|
676
766
|
# Track the progress of the connection, waiting for the socket to become readable/writable before polling it.
|
|
677
767
|
#
|
|
@@ -679,7 +769,7 @@ class PG::Connection
|
|
|
679
769
|
# - All hosts are passed to PG::Connection.connect_start
|
|
680
770
|
# - As soon as the host is tried to connect the related host is removed from the hosts list
|
|
681
771
|
# - 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
|
|
772
|
+
# - When the polling status changes to `PG::PGRES_POLLING_FAILED` connecting is aborted and a PG::ConnectionBad is raised with details to all connection attempts.
|
|
683
773
|
# - When a timeout occurs, connecting is restarted with the remaining hosts.
|
|
684
774
|
#
|
|
685
775
|
# The downside is that this connects only once to hosts which are listed twice when they timeout.
|
|
@@ -706,22 +796,13 @@ class PG::Connection
|
|
|
706
796
|
# If the socket needs to read, wait 'til it becomes readable to poll again
|
|
707
797
|
case poll_status
|
|
708
798
|
when PG::PGRES_POLLING_READING
|
|
709
|
-
|
|
710
|
-
socket_io.wait(IO::READABLE | IO::PRIORITY, timeout)
|
|
711
|
-
else
|
|
712
|
-
IO.select([socket_io], nil, [socket_io], timeout)
|
|
713
|
-
end
|
|
799
|
+
socket_io.wait(IO::READABLE | IO::PRIORITY, timeout)
|
|
714
800
|
|
|
715
801
|
# ...and the same for when the socket needs to write
|
|
716
802
|
when PG::PGRES_POLLING_WRITING
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
socket_io.wait(IO::WRITABLE | IO::PRIORITY, timeout)
|
|
721
|
-
else
|
|
722
|
-
# io#wait on ruby-2.x doesn't wait for priority, so fallback to IO.select
|
|
723
|
-
IO.select(nil, [socket_io], [socket_io], timeout)
|
|
724
|
-
end
|
|
803
|
+
# Use wait instead of wait_readable, since connection errors are delivered as
|
|
804
|
+
# exceptional/priority events on Windows.
|
|
805
|
+
socket_io.wait(IO::WRITABLE | IO::PRIORITY, timeout)
|
|
725
806
|
end
|
|
726
807
|
end
|
|
727
808
|
|
|
@@ -887,7 +968,6 @@ class PG::Connection
|
|
|
887
968
|
|
|
888
969
|
# Resolve DNS in Ruby to avoid blocking state while connecting.
|
|
889
970
|
# Multiple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses.
|
|
890
|
-
# This requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
|
|
891
971
|
private def resolve_hosts(iopts)
|
|
892
972
|
ihosts = iopts[:host].split(",", -1)
|
|
893
973
|
iports = iopts[:port].split(",", -1)
|
|
@@ -897,16 +977,7 @@ class PG::Connection
|
|
|
897
977
|
|
|
898
978
|
dests = ihosts.each_with_index.flat_map do |mhost, idx|
|
|
899
979
|
unless host_is_named_pipe?(mhost)
|
|
900
|
-
|
|
901
|
-
Fiber.scheduler &&
|
|
902
|
-
RUBY_VERSION < '3.1.'
|
|
903
|
-
|
|
904
|
-
# Use a second thread to avoid blocking of the scheduler.
|
|
905
|
-
# `TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
|
|
906
|
-
hostaddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
|
|
907
|
-
else
|
|
908
|
-
hostaddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
|
|
909
|
-
end
|
|
980
|
+
hostaddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
|
|
910
981
|
else
|
|
911
982
|
# No hostname to resolve (UnixSocket)
|
|
912
983
|
hostaddrs = [nil]
|
|
@@ -919,13 +990,24 @@ class PG::Connection
|
|
|
919
990
|
port: dests.map{|d| d[2] }.join(","))
|
|
920
991
|
end
|
|
921
992
|
|
|
993
|
+
RESOLUTION_KEYS = [:host, :hostaddr, :port].freeze
|
|
994
|
+
private_constant :RESOLUTION_KEYS
|
|
995
|
+
|
|
922
996
|
private def connect_to_hosts(*args)
|
|
923
997
|
option_string = parse_connect_args(*args)
|
|
924
|
-
iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
|
925
|
-
iopts = PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
|
|
998
|
+
iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}) { |h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
|
926
999
|
|
|
927
|
-
|
|
928
|
-
|
|
1000
|
+
has_explicit_host = (!iopts[:host].to_s.empty? || !iopts[:hostaddr].to_s.empty?) && !iopts[:port].to_s.empty?
|
|
1001
|
+
has_explicit_service = !iopts[:service].to_s.empty?
|
|
1002
|
+
|
|
1003
|
+
iopts_with_defaults = PG::Connection.conndefaults.each_with_object({}) do |h, o|
|
|
1004
|
+
k = h[:keyword].to_sym
|
|
1005
|
+
# Only use the host/hostname/port keys from defaults and leave user/dbname/sslmode/... for libpq, so that they are processed in the right order.
|
|
1006
|
+
o[k] = h[:val] if h[:val] && RESOLUTION_KEYS.include?(k)
|
|
1007
|
+
end.merge(iopts)
|
|
1008
|
+
|
|
1009
|
+
if PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET && iopts_with_defaults[:host].to_s.empty? && iopts_with_defaults[:hostaddr].to_s.empty?
|
|
1010
|
+
# Many distros patch the hardcoded default UnixSocket path in libpq to /var/run/postgresql instead of /tmp .
|
|
929
1011
|
# We simply try them all.
|
|
930
1012
|
iopts[:host] = "/var/run/postgresql" + # Ubuntu, Debian, Fedora, Opensuse
|
|
931
1013
|
",/run/postgresql" + # Alpine, Archlinux, Gentoo
|
|
@@ -933,15 +1015,22 @@ class PG::Connection
|
|
|
933
1015
|
end
|
|
934
1016
|
|
|
935
1017
|
iopts_for_reset = iopts
|
|
936
|
-
if
|
|
1018
|
+
if iopts_with_defaults[:hostaddr]
|
|
937
1019
|
# hostaddr is provided -> no need to resolve hostnames
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1020
|
+
elsif has_explicit_service && !has_explicit_host
|
|
1021
|
+
# The pg_service.conf might provide host/user/port/etc.
|
|
1022
|
+
# Ruby-pg cannot interpret pg_service without reading INI file and the additional LDAP stuff.
|
|
1023
|
+
# So, pass params through and let libpq resolve the service, possibly blocking the Thread.scheduler.
|
|
1024
|
+
# This ensures the processing order of libpq which is:
|
|
1025
|
+
# connection string => service file => environment variable => compiled default
|
|
1026
|
+
elsif iopts_with_defaults[:host] && !iopts_with_defaults[:host].empty?
|
|
1027
|
+
# Do host resolution in Ruby to avoid blocking Thread.scheduler while DNS queries in libpq.
|
|
1028
|
+
iopts_for_reset = iopts_with_defaults
|
|
1029
|
+
iopts = resolve_hosts(iopts_with_defaults)
|
|
941
1030
|
else
|
|
942
1031
|
# No host given
|
|
943
1032
|
end
|
|
944
|
-
conn =
|
|
1033
|
+
conn = connect_start(iopts) or
|
|
945
1034
|
raise(PG::Error, "Unable to create a new connection")
|
|
946
1035
|
|
|
947
1036
|
raise PG::ConnectionBad, conn.error_message if conn.status == PG::CONNECTION_BAD
|
|
@@ -1047,6 +1136,7 @@ class PG::Connection
|
|
|
1047
1136
|
}
|
|
1048
1137
|
private_constant :REDIRECT_METHODS
|
|
1049
1138
|
if PG::Connection.instance_methods.include? :async_close_prepared
|
|
1139
|
+
# PostgreSQL-17+
|
|
1050
1140
|
REDIRECT_METHODS.merge!({
|
|
1051
1141
|
:close_prepared => [:async_close_prepared, :sync_close_prepared],
|
|
1052
1142
|
:close_portal => [:async_close_portal, :sync_close_portal],
|
data/lib/pg/text_decoder/date.rb
CHANGED
data/lib/pg/text_decoder/json.rb
CHANGED
data/lib/pg/text_encoder/date.rb
CHANGED
|
@@ -6,7 +6,13 @@ module PG
|
|
|
6
6
|
# This is a encoder class for conversion of Ruby Date values to PostgreSQL date type.
|
|
7
7
|
class Date < SimpleEncoder
|
|
8
8
|
def encode(value)
|
|
9
|
-
value.respond_to?(:
|
|
9
|
+
if value.respond_to?(:gregorian?)
|
|
10
|
+
# Only create a new gregorian Date object if necessary
|
|
11
|
+
value = value.gregorian unless value.gregorian?
|
|
12
|
+
value.strftime("%Y-%m-%d")
|
|
13
|
+
else
|
|
14
|
+
value
|
|
15
|
+
end
|
|
10
16
|
end
|
|
11
17
|
end
|
|
12
18
|
end
|
data/lib/pg/text_encoder/json.rb
CHANGED
data/lib/pg/version.rb
CHANGED
data/pg.gemspec
CHANGED
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.description = "Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL 10 and later."
|
|
14
14
|
spec.homepage = "https://github.com/ged/ruby-pg"
|
|
15
15
|
spec.license = "BSD-2-Clause"
|
|
16
|
-
spec.required_ruby_version = ">=
|
|
16
|
+
spec.required_ruby_version = ">= 3.1"
|
|
17
17
|
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
19
|
spec.metadata["source_code_uri"] = "https://github.com/ged/ruby-pg"
|
|
Binary file
|
data/sample/async_mixed.rb
CHANGED
|
@@ -5,7 +5,7 @@ require 'pg'
|
|
|
5
5
|
$stdout.sync = true
|
|
6
6
|
|
|
7
7
|
# This is a example of how to mix and match synchronous and async APIs. In this case,
|
|
8
|
-
# the connection to the server is made
|
|
8
|
+
# the connection to the server is made synchronously, and then queries are
|
|
9
9
|
# asynchronous.
|
|
10
10
|
|
|
11
11
|
TIMEOUT = 5.0 # seconds to wait for an async operation to complete
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Granger
|
|
@@ -11,8 +11,8 @@ cert_chain:
|
|
|
11
11
|
- |
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
|
13
13
|
MIIEBDCCAmygAwIBAgIBBDANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNjAyMTQyMTU3MTlaFw0yNzAy
|
|
15
|
+
MTQyMTU3MTlaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
|
16
16
|
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
|
17
17
|
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
|
18
18
|
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
|
@@ -23,15 +23,15 @@ cert_chain:
|
|
|
23
23
|
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
|
24
24
|
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
|
25
25
|
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAWuY62AlTOhipB443sEkhK0G09vjB3v0j
|
|
27
|
+
9A2HlHXMOcgilbfbMR7ejT+/ynwdqMkrYCQCvoQH06NgIzFi2u6cKKmb2rWXMAF1
|
|
28
|
+
g0NLTs1h/KFsfwuX7IOQ9LxkMl9jlYWdFptFi9oQhlfgmFAFLiZJzNA0+QZMgW6A
|
|
29
|
+
e3usJh0/pT8E0hLWnJdomEF7pNsFyfKjbp5KWRd585z3dePi0iPcpzdByCnJsO36
|
|
30
|
+
Hyl/JsJZyHwpR6LlgfpXmYFwxeFZvpJg2S9O7Yo+qlgiaIUbnkVxOqfEXhCRZm8d
|
|
31
|
+
vfBZ6NSBwcdh7tXk01Yeqap0OtIE7Ey6C/so7uc3vZE6lPZ8xumMYyZ1lJTk5WwS
|
|
32
|
+
qgNbJXZWC/Q9RqPbOZXj4Q2Rq0iFfGNPlkKVeDabXfAASAVtrUb1gByb2b53Kq6N
|
|
33
|
+
OZ/RmpA4/XcoJIE2pnoUq8j6WCeNJ9m11JS2NmgUvYtdMFgMJWoH/hiF71l8dH3v
|
|
34
|
+
76Q140MRgXCuR7RMxztucM6XZQbk1VSO
|
|
35
35
|
-----END CERTIFICATE-----
|
|
36
36
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
37
37
|
dependencies: []
|
|
@@ -117,6 +117,7 @@ files:
|
|
|
117
117
|
- certs/larskanis-2022.pem
|
|
118
118
|
- certs/larskanis-2023.pem
|
|
119
119
|
- certs/larskanis-2024.pem
|
|
120
|
+
- certs/larskanis-2026.pem
|
|
120
121
|
- ext/errorcodes.def
|
|
121
122
|
- ext/errorcodes.rb
|
|
122
123
|
- ext/errorcodes.txt
|
|
@@ -149,7 +150,6 @@ files:
|
|
|
149
150
|
- ext/vc/pg.sln
|
|
150
151
|
- ext/vc/pg_18/pg.vcproj
|
|
151
152
|
- ext/vc/pg_19/pg_19.vcproj
|
|
152
|
-
- lib/3.0/pg_ext.so
|
|
153
153
|
- lib/3.1/pg_ext.so
|
|
154
154
|
- lib/3.2/pg_ext.so
|
|
155
155
|
- lib/3.3/pg_ext.so
|
|
@@ -200,11 +200,9 @@ files:
|
|
|
200
200
|
- misc/yugabyte/pg-test.rb
|
|
201
201
|
- pg.gemspec
|
|
202
202
|
- ports/aarch64-linux/lib/libpq-ruby-pg.so.1
|
|
203
|
-
- ports/patches/krb5/1.22.
|
|
204
|
-
- ports/patches/krb5/1.22.
|
|
205
|
-
- ports/patches/
|
|
206
|
-
- ports/patches/postgresql/18.1/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
|
|
207
|
-
- ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch
|
|
203
|
+
- ports/patches/krb5/1.22.2/0001-Allow-static-linking-krb5-library.patch
|
|
204
|
+
- ports/patches/krb5/1.22.2/0002-unknown-command-line-option-on-clang.patch
|
|
205
|
+
- ports/patches/postgresql/18.6/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
|
|
208
206
|
- rakelib/pg_gem_helper.rb
|
|
209
207
|
- rakelib/task_extension.rb
|
|
210
208
|
- sample/array_insert.rb
|
|
@@ -245,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
245
243
|
requirements:
|
|
246
244
|
- - ">="
|
|
247
245
|
- !ruby/object:Gem::Version
|
|
248
|
-
version: '3.
|
|
246
|
+
version: '3.1'
|
|
249
247
|
- - "<"
|
|
250
248
|
- !ruby/object:Gem::Version
|
|
251
249
|
version: 4.1.dev
|
metadata.gz.sig
CHANGED
|
Binary file
|
data/lib/3.0/pg_ext.so
DELETED
|
Binary file
|
|
@@ -1,21 +0,0 @@
|
|
|
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" ],
|