class PG::Connection

def connect_to_hosts(*args)

def connect_to_hosts(*args)
string = parse_connect_args(*args)
 PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
 PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
s[:hostaddr]
addr is provided -> no need to resolve hostnames
opts[:host] && !iopts[:host].empty? && PG.library_version >= 100000
lve DNS in Ruby to avoid blocking state while connecting.
iple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses.
 requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
 = iopts[:host].split(",", -1)
 = iopts[:port].split(",", -1)
 = [nil] if iports.size == 0
 = iports * ihosts.size if iports.size == 1
PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
= ihosts.each_with_index.flat_map do |mhost, idx|
s host_is_named_pipe?(mhost)
iber.respond_to?(:scheduler) &&
iber.scheduler &&
UBY_VERSION < '3.1.'
se a second thread to avoid blocking of the scheduler.
TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
taddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value

taddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
 hostname to resolve (UnixSocket)
addrs = [nil]
ddrs.map { |hostaddr| [hostaddr, mhost, iports[idx]] }
merge!(
ddr: dests.map{|d| d[0] }.join(","),
 dests.map{|d| d[1] }.join(","),
 dests.map{|d| d[2] }.join(","))
ost given
self.connect_start(iopts) or
raise(PG::Error, "Unable to create a new connection")
G::ConnectionBad, conn.error_message if conn.status == PG::CONNECTION_BAD
nd(:async_connect_or_reset, :connect_poll)