From f06f200ebe4aca7331a3de8a0b103f1246a4c351 Mon Sep 17 00:00:00 2001
From: renovate <renovate-bot@autistici.org>
Date: Tue, 12 Jan 2021 17:21:30 +0000
Subject: [PATCH] Update module lib/pq to v1

---
 go.mod                                   |   2 +-
 go.sum                                   |   2 +
 vendor/github.com/lib/pq/.gitignore      |   2 +
 vendor/github.com/lib/pq/.travis.sh      |  13 -
 vendor/github.com/lib/pq/.travis.yml     |  17 +-
 vendor/github.com/lib/pq/CONTRIBUTING.md |  29 ---
 vendor/github.com/lib/pq/README.md       |  77 +-----
 vendor/github.com/lib/pq/array.go        | 139 +++++++++++
 vendor/github.com/lib/pq/buf.go          |   2 +-
 vendor/github.com/lib/pq/conn.go         | 297 +++++++++++++++++++----
 vendor/github.com/lib/pq/conn_go18.go    |  24 +-
 vendor/github.com/lib/pq/connector.go    |   7 +-
 vendor/github.com/lib/pq/copy.go         |  33 ++-
 vendor/github.com/lib/pq/doc.go          |  23 ++
 vendor/github.com/lib/pq/encode.go       |  31 ++-
 vendor/github.com/lib/pq/error.go        |  13 +-
 vendor/github.com/lib/pq/go.mod          |   2 +
 vendor/github.com/lib/pq/krb.go          |  27 +++
 vendor/github.com/lib/pq/notice.go       |  71 ++++++
 vendor/github.com/lib/pq/notify.go       |  63 ++++-
 vendor/github.com/lib/pq/scram/scram.go  | 264 ++++++++++++++++++++
 vendor/github.com/lib/pq/user_posix.go   |   2 +-
 vendor/modules.txt                       |   3 +-
 23 files changed, 945 insertions(+), 198 deletions(-)
 delete mode 100644 vendor/github.com/lib/pq/CONTRIBUTING.md
 create mode 100644 vendor/github.com/lib/pq/krb.go
 create mode 100644 vendor/github.com/lib/pq/notice.go
 create mode 100644 vendor/github.com/lib/pq/scram/scram.go

diff --git a/go.mod b/go.mod
index beaeedf6..3f30c0c3 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/coreos/go-systemd/v22 v22.1.0
 	github.com/go-ldap/ldap/v3 v3.2.4
 	github.com/go-sql-driver/mysql v1.4.0
-	github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6
+	github.com/lib/pq v1.9.0
 	github.com/mattn/go-sqlite3 v0.0.0-20180926090220-0a88db3545c4
 	github.com/prometheus/client_golang v1.9.0
 	golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
diff --git a/go.sum b/go.sum
index eff24845..f2b8645c 100644
--- a/go.sum
+++ b/go.sum
@@ -185,6 +185,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6 h1:faSzJmSgOhbgs/gWoEPhVr+mHTZWGFwiBgCW6/P49VM=
 github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
+github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
diff --git a/vendor/github.com/lib/pq/.gitignore b/vendor/github.com/lib/pq/.gitignore
index 0f1d00e1..3243952a 100644
--- a/vendor/github.com/lib/pq/.gitignore
+++ b/vendor/github.com/lib/pq/.gitignore
@@ -2,3 +2,5 @@
 *.test
 *~
 *.swp
+.idea
+.vscode
\ No newline at end of file
diff --git a/vendor/github.com/lib/pq/.travis.sh b/vendor/github.com/lib/pq/.travis.sh
index 21a52644..ebf44703 100644
--- a/vendor/github.com/lib/pq/.travis.sh
+++ b/vendor/github.com/lib/pq/.travis.sh
@@ -70,17 +70,4 @@ postgresql_uninstall() {
 	sudo rm -rf /var/lib/postgresql
 }
 
-megacheck_install() {
-	# Lock megacheck version at $MEGACHECK_VERSION to prevent spontaneous
-	# new error messages in old code.
-	go get -d honnef.co/go/tools/...
-	git -C $GOPATH/src/honnef.co/go/tools/ checkout $MEGACHECK_VERSION
-	go install honnef.co/go/tools/cmd/megacheck
-	megacheck --version
-}
-
-golint_install() {
-	go get golang.org/x/lint/golint
-}
-
 $1
diff --git a/vendor/github.com/lib/pq/.travis.yml b/vendor/github.com/lib/pq/.travis.yml
index f0305809..f378207f 100644
--- a/vendor/github.com/lib/pq/.travis.yml
+++ b/vendor/github.com/lib/pq/.travis.yml
@@ -1,9 +1,8 @@
 language: go
 
 go:
-  - 1.9.x
-  - 1.10.x
-  - 1.11.x
+  - 1.14.x
+  - 1.15.x
   - master
 
 sudo: true
@@ -14,16 +13,12 @@ env:
     - PQGOSSLTESTS=1
     - PQSSLCERTTEST_PATH=$PWD/certs
     - PGHOST=127.0.0.1
-    - MEGACHECK_VERSION=2017.2.2
+    - GODEBUG=x509ignoreCN=0
   matrix:
     - PGVERSION=10
     - PGVERSION=9.6
     - PGVERSION=9.5
     - PGVERSION=9.4
-    - PGVERSION=9.3
-    - PGVERSION=9.2
-    - PGVERSION=9.1
-    - PGVERSION=9.0
 
 before_install:
   - ./.travis.sh postgresql_uninstall
@@ -31,9 +26,9 @@ before_install:
   - ./.travis.sh postgresql_install
   - ./.travis.sh postgresql_configure
   - ./.travis.sh client_configure
-  - ./.travis.sh megacheck_install
-  - ./.travis.sh golint_install
   - go get golang.org/x/tools/cmd/goimports
+  - go get golang.org/x/lint/golint
+  - GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2020.1.3
 
 before_script:
   - createdb pqgotest
@@ -44,7 +39,7 @@ script:
   - >
     goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
   - go vet ./...
-  - megacheck -go 1.9 ./...
+  - staticcheck -go 1.13 ./...
   - golint ./...
   - PQTEST_BINARY_PARAMETERS=no  go test -race -v ./...
   - PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
diff --git a/vendor/github.com/lib/pq/CONTRIBUTING.md b/vendor/github.com/lib/pq/CONTRIBUTING.md
deleted file mode 100644
index 84c937f1..00000000
--- a/vendor/github.com/lib/pq/CONTRIBUTING.md
+++ /dev/null
@@ -1,29 +0,0 @@
-## Contributing to pq
-
-`pq` has a backlog of pull requests, but contributions are still very
-much welcome. You can help with patch review, submitting bug reports,
-or adding new functionality. There is no formal style guide, but
-please conform to the style of existing code and general Go formatting
-conventions when submitting patches.
-
-### Patch review
-
-Help review existing open pull requests by commenting on the code or
-proposed functionality.
-
-### Bug reports
-
-We appreciate any bug reports, but especially ones with self-contained
-(doesn't depend on code outside of pq), minimal (can't be simplified
-further) test cases. It's especially helpful if you can submit a pull
-request with just the failing test case (you'll probably want to
-pattern it after the tests in
-[conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go).
-
-### New functionality
-
-There are a number of pending patches for new functionality, so
-additional feature patches will take a while to merge. Still, patches
-are generally reviewed based on usefulness and complexity in addition
-to time-in-queue, so if you have a knockout idea, take a shot. Feel
-free to open an issue discussion your proposed patch beforehand.
diff --git a/vendor/github.com/lib/pq/README.md b/vendor/github.com/lib/pq/README.md
index 385fe735..c972a86a 100644
--- a/vendor/github.com/lib/pq/README.md
+++ b/vendor/github.com/lib/pq/README.md
@@ -1,21 +1,11 @@
 # pq - A pure Go postgres driver for Go's database/sql package
 
-[![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://godoc.org/github.com/lib/pq)
-[![Build Status](https://travis-ci.org/lib/pq.svg?branch=master)](https://travis-ci.org/lib/pq)
+[![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://pkg.go.dev/github.com/lib/pq?tab=doc)
 
 ## Install
 
 	go get github.com/lib/pq
 
-## Docs
-
-For detailed documentation and basic usage examples, please see the package
-documentation at <https://godoc.org/github.com/lib/pq>.
-
-## Tests
-
-`go test` is used for testing.  See [TESTS.md](TESTS.md) for more details.
-
 ## Features
 
 * SSL
@@ -29,67 +19,12 @@ documentation at <https://godoc.org/github.com/lib/pq>.
 * Unix socket support
 * Notifications: `LISTEN`/`NOTIFY`
 * pgpass support
+* GSS (Kerberos) auth
 
-## Future / Things you can help with
-
-* Better COPY FROM / COPY TO (see discussion in #181)
+## Tests
 
-## Thank you (alphabetical)
+`go test` is used for testing.  See [TESTS.md](TESTS.md) for more details.
 
-Some of these contributors are from the original library `bmizerany/pq.go` whose
-code still exists in here.
+## Status
 
-* Andy Balholm (andybalholm)
-* Ben Berkert (benburkert)
-* Benjamin Heatwole (bheatwole)
-* Bill Mill (llimllib)
-* Bjørn Madsen (aeons)
-* Blake Gentry (bgentry)
-* Brad Fitzpatrick (bradfitz)
-* Charlie Melbye (cmelbye)
-* Chris Bandy (cbandy)
-* Chris Gilling (cgilling)
-* Chris Walsh (cwds)
-* Dan Sosedoff (sosedoff)
-* Daniel Farina (fdr)
-* Eric Chlebek (echlebek)
-* Eric Garrido (minusnine)
-* Eric Urban (hydrogen18)
-* Everyone at The Go Team
-* Evan Shaw (edsrzf)
-* Ewan Chou (coocood)
-* Fazal Majid (fazalmajid)
-* Federico Romero (federomero)
-* Fumin (fumin)
-* Gary Burd (garyburd)
-* Heroku (heroku)
-* James Pozdena (jpoz)
-* Jason McVetta (jmcvetta)
-* Jeremy Jay (pbnjay)
-* Joakim Sernbrant (serbaut)
-* John Gallagher (jgallagher)
-* Jonathan Rudenberg (titanous)
-* Joël Stemmer (jstemmer)
-* Kamil Kisiel (kisielk)
-* Kelly Dunn (kellydunn)
-* Keith Rarick (kr)
-* Kir Shatrov (kirs)
-* Lann Martin (lann)
-* Maciek Sakrejda (uhoh-itsmaciek)
-* Marc Brinkmann (mbr)
-* Marko Tiikkaja (johto)
-* Matt Newberry (MattNewberry)
-* Matt Robenolt (mattrobenolt)
-* Martin Olsen (martinolsen)
-* Mike Lewis (mikelikespie)
-* Nicolas Patry (Narsil)
-* Oliver Tonnhofer (olt)
-* Patrick Hayes (phayes)
-* Paul Hammond (paulhammond)
-* Ryan Smith (ryandotsmith)
-* Samuel Stauffer (samuel)
-* Timothée Peignier (cyberdelia)
-* Travis Cline (tmc)
-* TruongSinh Tran-Nguyen (truongsinh)
-* Yaismel Miranda (ympons)
-* notedit (notedit)
+This package is effectively in maintenance mode and is not actively developed. Small patches and features are only rarely reviewed and merged. We recommend using [pgx](https://github.com/jackc/pgx) which is actively maintained.
diff --git a/vendor/github.com/lib/pq/array.go b/vendor/github.com/lib/pq/array.go
index e4933e22..405da236 100644
--- a/vendor/github.com/lib/pq/array.go
+++ b/vendor/github.com/lib/pq/array.go
@@ -35,19 +35,31 @@ func Array(a interface{}) interface {
 		return (*BoolArray)(&a)
 	case []float64:
 		return (*Float64Array)(&a)
+	case []float32:
+		return (*Float32Array)(&a)
 	case []int64:
 		return (*Int64Array)(&a)
+	case []int32:
+		return (*Int32Array)(&a)
 	case []string:
 		return (*StringArray)(&a)
+	case [][]byte:
+		return (*ByteaArray)(&a)
 
 	case *[]bool:
 		return (*BoolArray)(a)
 	case *[]float64:
 		return (*Float64Array)(a)
+	case *[]float32:
+		return (*Float32Array)(a)
 	case *[]int64:
 		return (*Int64Array)(a)
+	case *[]int32:
+		return (*Int32Array)(a)
 	case *[]string:
 		return (*StringArray)(a)
+	case *[][]byte:
+		return (*ByteaArray)(a)
 	}
 
 	return GenericArray{a}
@@ -267,6 +279,70 @@ func (a Float64Array) Value() (driver.Value, error) {
 	return "{}", nil
 }
 
+// Float32Array represents a one-dimensional array of the PostgreSQL double
+// precision type.
+type Float32Array []float32
+
+// Scan implements the sql.Scanner interface.
+func (a *Float32Array) Scan(src interface{}) error {
+	switch src := src.(type) {
+	case []byte:
+		return a.scanBytes(src)
+	case string:
+		return a.scanBytes([]byte(src))
+	case nil:
+		*a = nil
+		return nil
+	}
+
+	return fmt.Errorf("pq: cannot convert %T to Float32Array", src)
+}
+
+func (a *Float32Array) scanBytes(src []byte) error {
+	elems, err := scanLinearArray(src, []byte{','}, "Float32Array")
+	if err != nil {
+		return err
+	}
+	if *a != nil && len(elems) == 0 {
+		*a = (*a)[:0]
+	} else {
+		b := make(Float32Array, len(elems))
+		for i, v := range elems {
+			var x float64
+			if x, err = strconv.ParseFloat(string(v), 32); err != nil {
+				return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
+			}
+			b[i] = float32(x)
+		}
+		*a = b
+	}
+	return nil
+}
+
+// Value implements the driver.Valuer interface.
+func (a Float32Array) Value() (driver.Value, error) {
+	if a == nil {
+		return nil, nil
+	}
+
+	if n := len(a); n > 0 {
+		// There will be at least two curly brackets, N bytes of values,
+		// and N-1 bytes of delimiters.
+		b := make([]byte, 1, 1+2*n)
+		b[0] = '{'
+
+		b = strconv.AppendFloat(b, float64(a[0]), 'f', -1, 32)
+		for i := 1; i < n; i++ {
+			b = append(b, ',')
+			b = strconv.AppendFloat(b, float64(a[i]), 'f', -1, 32)
+		}
+
+		return string(append(b, '}')), nil
+	}
+
+	return "{}", nil
+}
+
 // GenericArray implements the driver.Valuer and sql.Scanner interfaces for
 // an array or slice of any dimension.
 type GenericArray struct{ A interface{} }
@@ -483,6 +559,69 @@ func (a Int64Array) Value() (driver.Value, error) {
 	return "{}", nil
 }
 
+// Int32Array represents a one-dimensional array of the PostgreSQL integer types.
+type Int32Array []int32
+
+// Scan implements the sql.Scanner interface.
+func (a *Int32Array) Scan(src interface{}) error {
+	switch src := src.(type) {
+	case []byte:
+		return a.scanBytes(src)
+	case string:
+		return a.scanBytes([]byte(src))
+	case nil:
+		*a = nil
+		return nil
+	}
+
+	return fmt.Errorf("pq: cannot convert %T to Int32Array", src)
+}
+
+func (a *Int32Array) scanBytes(src []byte) error {
+	elems, err := scanLinearArray(src, []byte{','}, "Int32Array")
+	if err != nil {
+		return err
+	}
+	if *a != nil && len(elems) == 0 {
+		*a = (*a)[:0]
+	} else {
+		b := make(Int32Array, len(elems))
+		for i, v := range elems {
+			var x int
+			if x, err = strconv.Atoi(string(v)); err != nil {
+				return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
+			}
+			b[i] = int32(x)
+		}
+		*a = b
+	}
+	return nil
+}
+
+// Value implements the driver.Valuer interface.
+func (a Int32Array) Value() (driver.Value, error) {
+	if a == nil {
+		return nil, nil
+	}
+
+	if n := len(a); n > 0 {
+		// There will be at least two curly brackets, N bytes of values,
+		// and N-1 bytes of delimiters.
+		b := make([]byte, 1, 1+2*n)
+		b[0] = '{'
+
+		b = strconv.AppendInt(b, int64(a[0]), 10)
+		for i := 1; i < n; i++ {
+			b = append(b, ',')
+			b = strconv.AppendInt(b, int64(a[i]), 10)
+		}
+
+		return string(append(b, '}')), nil
+	}
+
+	return "{}", nil
+}
+
 // StringArray represents a one-dimensional array of the PostgreSQL character types.
 type StringArray []string
 
diff --git a/vendor/github.com/lib/pq/buf.go b/vendor/github.com/lib/pq/buf.go
index 666b0012..4b0a0a8f 100644
--- a/vendor/github.com/lib/pq/buf.go
+++ b/vendor/github.com/lib/pq/buf.go
@@ -66,7 +66,7 @@ func (b *writeBuf) int16(n int) {
 }
 
 func (b *writeBuf) string(s string) {
-	b.buf = append(b.buf, (s + "\000")...)
+	b.buf = append(append(b.buf, s...), '\000')
 }
 
 func (b *writeBuf) byte(c byte) {
diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go
index df2dab22..db0b6cef 100644
--- a/vendor/github.com/lib/pq/conn.go
+++ b/vendor/github.com/lib/pq/conn.go
@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"context"
 	"crypto/md5"
+	"crypto/sha256"
 	"database/sql"
 	"database/sql/driver"
 	"encoding/binary"
@@ -17,10 +18,12 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
+	"sync/atomic"
 	"time"
 	"unicode"
 
 	"github.com/lib/pq/oid"
+	"github.com/lib/pq/scram"
 )
 
 // Common error types
@@ -36,13 +39,18 @@ var (
 	errNoLastInsertID  = errors.New("no LastInsertId available after the empty statement")
 )
 
+// Compile time validation that our types implement the expected interfaces
+var (
+	_ driver.Driver = Driver{}
+)
+
 // Driver is the Postgres database driver.
 type Driver struct{}
 
 // Open opens a new connection to the database. name is a connection string.
 // Most users should only use it through database/sql package from the standard
 // library.
-func (d *Driver) Open(name string) (driver.Conn, error) {
+func (d Driver) Open(name string) (driver.Conn, error) {
 	return Open(name)
 }
 
@@ -90,6 +98,7 @@ type Dialer interface {
 	DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
 }
 
+// DialerContext is the context-aware dialer interface.
 type DialerContext interface {
 	DialContext(ctx context.Context, network, address string) (net.Conn, error)
 }
@@ -133,7 +142,7 @@ type conn struct {
 
 	// If true, this connection is bad and all public-facing functions should
 	// return ErrBadConn.
-	bad bool
+	bad *atomic.Value
 
 	// If set, this connection should never use the binary format when
 	// receiving query results from prepared statements.  Only provided for
@@ -146,6 +155,15 @@ type conn struct {
 
 	// If true this connection is in the middle of a COPY
 	inCopy bool
+
+	// If not nil, notices will be synchronously sent here
+	noticeHandler func(*Error)
+
+	// If not nil, notifications will be synchronously sent here
+	notificationHandler func(*Notification)
+
+	// GSSAPI context
+	gss GSS
 }
 
 // Handle driver-side settings in parsed connection string.
@@ -282,9 +300,12 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
 
 	o := c.opts
 
+	bad := &atomic.Value{}
+	bad.Store(false)
 	cn = &conn{
 		opts:   o,
 		dialer: c.dialer,
+		bad:    bad,
 	}
 	err = cn.handleDriverSettings(o)
 	if err != nil {
@@ -299,6 +320,9 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
 
 	err = cn.ssl(o)
 	if err != nil {
+		if cn.c != nil {
+			cn.c.Close()
+		}
 		return nil, err
 	}
 
@@ -323,10 +347,6 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
 
 func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) {
 	network, address := network(o)
-	// SSL is not necessary or supported over UNIX domain sockets
-	if network == "unix" {
-		o["sslmode"] = "disable"
-	}
 
 	// Zero or not specified means wait indefinitely.
 	if timeout, ok := o["connect_timeout"]; ok && timeout != "0" {
@@ -490,9 +510,22 @@ func (cn *conn) isInTransaction() bool {
 		cn.txnStatus == txnStatusInFailedTransaction
 }
 
+func (cn *conn) setBad() {
+	if cn.bad != nil {
+		cn.bad.Store(true)
+	}
+}
+
+func (cn *conn) getBad() bool {
+	if cn.bad != nil {
+		return cn.bad.Load().(bool)
+	}
+	return false
+}
+
 func (cn *conn) checkIsInTransaction(intxn bool) {
 	if cn.isInTransaction() != intxn {
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected transaction status %v", cn.txnStatus)
 	}
 }
@@ -502,7 +535,7 @@ func (cn *conn) Begin() (_ driver.Tx, err error) {
 }
 
 func (cn *conn) begin(mode string) (_ driver.Tx, err error) {
-	if cn.bad {
+	if cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
@@ -513,11 +546,11 @@ func (cn *conn) begin(mode string) (_ driver.Tx, err error) {
 		return nil, err
 	}
 	if commandTag != "BEGIN" {
-		cn.bad = true
+		cn.setBad()
 		return nil, fmt.Errorf("unexpected command tag %s", commandTag)
 	}
 	if cn.txnStatus != txnStatusIdleInTransaction {
-		cn.bad = true
+		cn.setBad()
 		return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus)
 	}
 	return cn, nil
@@ -531,7 +564,7 @@ func (cn *conn) closeTxn() {
 
 func (cn *conn) Commit() (err error) {
 	defer cn.closeTxn()
-	if cn.bad {
+	if cn.getBad() {
 		return driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
@@ -544,7 +577,7 @@ func (cn *conn) Commit() (err error) {
 	// would get the same behaviour if you issued a COMMIT in a failed
 	// transaction, so it's also the least surprising thing to do here.
 	if cn.txnStatus == txnStatusInFailedTransaction {
-		if err := cn.Rollback(); err != nil {
+		if err := cn.rollback(); err != nil {
 			return err
 		}
 		return ErrInFailedTransaction
@@ -553,12 +586,12 @@ func (cn *conn) Commit() (err error) {
 	_, commandTag, err := cn.simpleExec("COMMIT")
 	if err != nil {
 		if cn.isInTransaction() {
-			cn.bad = true
+			cn.setBad()
 		}
 		return err
 	}
 	if commandTag != "COMMIT" {
-		cn.bad = true
+		cn.setBad()
 		return fmt.Errorf("unexpected command tag %s", commandTag)
 	}
 	cn.checkIsInTransaction(false)
@@ -567,16 +600,19 @@ func (cn *conn) Commit() (err error) {
 
 func (cn *conn) Rollback() (err error) {
 	defer cn.closeTxn()
-	if cn.bad {
+	if cn.getBad() {
 		return driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
+	return cn.rollback()
+}
 
+func (cn *conn) rollback() (err error) {
 	cn.checkIsInTransaction(true)
 	_, commandTag, err := cn.simpleExec("ROLLBACK")
 	if err != nil {
 		if cn.isInTransaction() {
-			cn.bad = true
+			cn.setBad()
 		}
 		return err
 	}
@@ -616,7 +652,7 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err
 		case 'T', 'D':
 			// ignore any results
 		default:
-			cn.bad = true
+			cn.setBad()
 			errorf("unknown response for simple query: %q", t)
 		}
 	}
@@ -638,7 +674,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
 			// the user can close, though, to avoid connections from being
 			// leaked.  A "rows" with done=true works fine for that purpose.
 			if err != nil {
-				cn.bad = true
+				cn.setBad()
 				errorf("unexpected message %q in simple query execution", t)
 			}
 			if res == nil {
@@ -649,8 +685,11 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
 			// Set the result and tag to the last command complete if there wasn't a
 			// query already run. Although queries usually return from here and cede
 			// control to Next, a query with zero results does not.
-			if t == 'C' && res.colNames == nil {
+			if t == 'C' {
 				res.result, res.tag = cn.parseComplete(r.string())
+				if res.colNames != nil {
+					return
+				}
 			}
 			res.done = true
 		case 'Z':
@@ -662,7 +701,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
 			err = parseError(r)
 		case 'D':
 			if res == nil {
-				cn.bad = true
+				cn.setBad()
 				errorf("unexpected DataRow in simple query execution")
 			}
 			// the query didn't fail; kick off to Next
@@ -677,7 +716,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
 			// To work around a bug in QueryRow in Go 1.2 and earlier, wait
 			// until the first DataRow has been received.
 		default:
-			cn.bad = true
+			cn.setBad()
 			errorf("unknown response for simple query: %q", t)
 		}
 	}
@@ -770,7 +809,7 @@ func (cn *conn) prepareTo(q, stmtName string) *stmt {
 }
 
 func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) {
-	if cn.bad {
+	if cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
@@ -809,7 +848,7 @@ func (cn *conn) Query(query string, args []driver.Value) (driver.Rows, error) {
 }
 
 func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) {
-	if cn.bad {
+	if cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	if cn.inCopy {
@@ -843,7 +882,7 @@ func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) {
 
 // Implement the optional "Execer" interface for one-shot queries
 func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) {
-	if cn.bad {
+	if cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
@@ -877,9 +916,20 @@ func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err
 	return r, err
 }
 
+type safeRetryError struct {
+	Err error
+}
+
+func (se *safeRetryError) Error() string {
+	return se.Err.Error()
+}
+
 func (cn *conn) send(m *writeBuf) {
-	_, err := cn.c.Write(m.wrap())
+	n, err := cn.c.Write(m.wrap())
 	if err != nil {
+		if n == 0 {
+			err = &safeRetryError{Err: err}
+		}
 		panic(err)
 	}
 }
@@ -904,7 +954,7 @@ func (cn *conn) sendSimpleMessage(typ byte) (err error) {
 // the message yourself.
 func (cn *conn) saveMessage(typ byte, buf *readBuf) {
 	if cn.saveMessageType != 0 {
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected saveMessageType %d", cn.saveMessageType)
 	}
 	cn.saveMessageType = typ
@@ -958,12 +1008,17 @@ func (cn *conn) recv() (t byte, r *readBuf) {
 		if err != nil {
 			panic(err)
 		}
-
 		switch t {
 		case 'E':
 			panic(parseError(r))
 		case 'N':
-			// ignore
+			if n := cn.noticeHandler; n != nil {
+				n(parseError(r))
+			}
+		case 'A':
+			if n := cn.notificationHandler; n != nil {
+				n(recvNotification(r))
+			}
 		default:
 			return
 		}
@@ -980,8 +1035,14 @@ func (cn *conn) recv1Buf(r *readBuf) byte {
 		}
 
 		switch t {
-		case 'A', 'N':
-			// ignore
+		case 'A':
+			if n := cn.notificationHandler; n != nil {
+				n(recvNotification(r))
+			}
+		case 'N':
+			if n := cn.noticeHandler; n != nil {
+				n(parseError(r))
+			}
 		case 'S':
 			cn.processParameterStatus(r)
 		default:
@@ -1049,7 +1110,10 @@ func isDriverSetting(key string) bool {
 		return true
 	case "binary_parameters":
 		return true
-
+	case "krbsrvname":
+		return true
+	case "krbspn":
+		return true
 	default:
 		return false
 	}
@@ -1129,6 +1193,108 @@ func (cn *conn) auth(r *readBuf, o values) {
 		if r.int32() != 0 {
 			errorf("unexpected authentication response: %q", t)
 		}
+	case 7: // GSSAPI, startup
+		if newGss == nil {
+			errorf("kerberos error: no GSSAPI provider registered (import github.com/lib/pq/auth/kerberos if you need Kerberos support)")
+		}
+		cli, err := newGss()
+		if err != nil {
+			errorf("kerberos error: %s", err.Error())
+		}
+
+		var token []byte
+
+		if spn, ok := o["krbspn"]; ok {
+			// Use the supplied SPN if provided..
+			token, err = cli.GetInitTokenFromSpn(spn)
+		} else {
+			// Allow the kerberos service name to be overridden
+			service := "postgres"
+			if val, ok := o["krbsrvname"]; ok {
+				service = val
+			}
+
+			token, err = cli.GetInitToken(o["host"], service)
+		}
+
+		if err != nil {
+			errorf("failed to get Kerberos ticket: %q", err)
+		}
+
+		w := cn.writeBuf('p')
+		w.bytes(token)
+		cn.send(w)
+
+		// Store for GSSAPI continue message
+		cn.gss = cli
+
+	case 8: // GSSAPI continue
+
+		if cn.gss == nil {
+			errorf("GSSAPI protocol error")
+		}
+
+		b := []byte(*r)
+
+		done, tokOut, err := cn.gss.Continue(b)
+		if err == nil && !done {
+			w := cn.writeBuf('p')
+			w.bytes(tokOut)
+			cn.send(w)
+		}
+
+		// Errors fall through and read the more detailed message
+		// from the server..
+
+	case 10:
+		sc := scram.NewClient(sha256.New, o["user"], o["password"])
+		sc.Step(nil)
+		if sc.Err() != nil {
+			errorf("SCRAM-SHA-256 error: %s", sc.Err().Error())
+		}
+		scOut := sc.Out()
+
+		w := cn.writeBuf('p')
+		w.string("SCRAM-SHA-256")
+		w.int32(len(scOut))
+		w.bytes(scOut)
+		cn.send(w)
+
+		t, r := cn.recv()
+		if t != 'R' {
+			errorf("unexpected password response: %q", t)
+		}
+
+		if r.int32() != 11 {
+			errorf("unexpected authentication response: %q", t)
+		}
+
+		nextStep := r.next(len(*r))
+		sc.Step(nextStep)
+		if sc.Err() != nil {
+			errorf("SCRAM-SHA-256 error: %s", sc.Err().Error())
+		}
+
+		scOut = sc.Out()
+		w = cn.writeBuf('p')
+		w.bytes(scOut)
+		cn.send(w)
+
+		t, r = cn.recv()
+		if t != 'R' {
+			errorf("unexpected password response: %q", t)
+		}
+
+		if r.int32() != 12 {
+			errorf("unexpected authentication response: %q", t)
+		}
+
+		nextStep = r.next(len(*r))
+		sc.Step(nextStep)
+		if sc.Err() != nil {
+			errorf("SCRAM-SHA-256 error: %s", sc.Err().Error())
+		}
+
 	default:
 		errorf("unknown authentication response: %d", code)
 	}
@@ -1158,7 +1324,7 @@ func (st *stmt) Close() (err error) {
 	if st.closed {
 		return nil
 	}
-	if st.cn.bad {
+	if st.cn.getBad() {
 		return driver.ErrBadConn
 	}
 	defer st.cn.errRecover(&err)
@@ -1172,14 +1338,14 @@ func (st *stmt) Close() (err error) {
 
 	t, _ := st.cn.recv1()
 	if t != '3' {
-		st.cn.bad = true
+		st.cn.setBad()
 		errorf("unexpected close response: %q", t)
 	}
 	st.closed = true
 
 	t, r := st.cn.recv1()
 	if t != 'Z' {
-		st.cn.bad = true
+		st.cn.setBad()
 		errorf("expected ready for query, but got: %q", t)
 	}
 	st.cn.processReadyForQuery(r)
@@ -1188,7 +1354,7 @@ func (st *stmt) Close() (err error) {
 }
 
 func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) {
-	if st.cn.bad {
+	if st.cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	defer st.cn.errRecover(&err)
@@ -1201,7 +1367,7 @@ func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) {
 }
 
 func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) {
-	if st.cn.bad {
+	if st.cn.getBad() {
 		return nil, driver.ErrBadConn
 	}
 	defer st.cn.errRecover(&err)
@@ -1288,7 +1454,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
 	if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") {
 		parts := strings.Split(commandTag, " ")
 		if len(parts) != 3 {
-			cn.bad = true
+			cn.setBad()
 			errorf("unexpected INSERT command tag %s", commandTag)
 		}
 		affectedRows = &parts[len(parts)-1]
@@ -1300,7 +1466,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
 	}
 	n, err := strconv.ParseInt(*affectedRows, 10, 64)
 	if err != nil {
-		cn.bad = true
+		cn.setBad()
 		errorf("could not parse commandTag: %s", err)
 	}
 	return driver.RowsAffected(n), commandTag
@@ -1367,7 +1533,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
 	}
 
 	conn := rs.cn
-	if conn.bad {
+	if conn.getBad() {
 		return driver.ErrBadConn
 	}
 	defer conn.errRecover(&err)
@@ -1392,7 +1558,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
 		case 'D':
 			n := rs.rb.int16()
 			if err != nil {
-				conn.bad = true
+				conn.setBad()
 				errorf("unexpected DataRow after error %s", err)
 			}
 			if n < len(dest) {
@@ -1450,6 +1616,39 @@ func QuoteIdentifier(name string) string {
 	return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
 }
 
+// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal
+// to DDL and other statements that do not accept parameters) to be used as part
+// of an SQL statement.  For example:
+//
+//    exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
+//    err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
+//
+// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be
+// replaced by two backslashes (i.e. "\\") and the C-style escape identifier
+// that PostgreSQL provides ('E') will be prepended to the string.
+func QuoteLiteral(literal string) string {
+	// This follows the PostgreSQL internal algorithm for handling quoted literals
+	// from libpq, which can be found in the "PQEscapeStringInternal" function,
+	// which is found in the libpq/fe-exec.c source file:
+	// https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c
+	//
+	// substitute any single-quotes (') with two single-quotes ('')
+	literal = strings.Replace(literal, `'`, `''`, -1)
+	// determine if the string has any backslashes (\) in it.
+	// if it does, replace any backslashes (\) with two backslashes (\\)
+	// then, we need to wrap the entire string with a PostgreSQL
+	// C-style escape. Per how "PQEscapeStringInternal" handles this case, we
+	// also add a space before the "E"
+	if strings.Contains(literal, `\`) {
+		literal = strings.Replace(literal, `\`, `\\`, -1)
+		literal = ` E'` + literal + `'`
+	} else {
+		// otherwise, we can just wrap the literal with a pair of single quotes
+		literal = `'` + literal + `'`
+	}
+	return literal
+}
+
 func md5s(s string) string {
 	h := md5.New()
 	h.Write([]byte(s))
@@ -1554,7 +1753,7 @@ func (cn *conn) readReadyForQuery() {
 		cn.processReadyForQuery(r)
 		return
 	default:
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected message %q; expected ReadyForQuery", t)
 	}
 }
@@ -1574,7 +1773,7 @@ func (cn *conn) readParseResponse() {
 		cn.readReadyForQuery()
 		panic(err)
 	default:
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected Parse response %q", t)
 	}
 }
@@ -1599,7 +1798,7 @@ func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames [
 			cn.readReadyForQuery()
 			panic(err)
 		default:
-			cn.bad = true
+			cn.setBad()
 			errorf("unexpected Describe statement response %q", t)
 		}
 	}
@@ -1617,7 +1816,7 @@ func (cn *conn) readPortalDescribeResponse() rowsHeader {
 		cn.readReadyForQuery()
 		panic(err)
 	default:
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected Describe response %q", t)
 	}
 	panic("not reached")
@@ -1633,7 +1832,7 @@ func (cn *conn) readBindResponse() {
 		cn.readReadyForQuery()
 		panic(err)
 	default:
-		cn.bad = true
+		cn.setBad()
 		errorf("unexpected Bind response %q", t)
 	}
 }
@@ -1660,7 +1859,7 @@ func (cn *conn) postExecuteWorkaround() {
 			cn.saveMessage(t, r)
 			return
 		default:
-			cn.bad = true
+			cn.setBad()
 			errorf("unexpected message during extended query execution: %q", t)
 		}
 	}
@@ -1673,7 +1872,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
 		switch t {
 		case 'C':
 			if err != nil {
-				cn.bad = true
+				cn.setBad()
 				errorf("unexpected CommandComplete after error %s", err)
 			}
 			res, commandTag = cn.parseComplete(r.string())
@@ -1687,7 +1886,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
 			err = parseError(r)
 		case 'T', 'D', 'I':
 			if err != nil {
-				cn.bad = true
+				cn.setBad()
 				errorf("unexpected %q after error %s", t, err)
 			}
 			if t == 'I' {
@@ -1695,7 +1894,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
 			}
 			// ignore any results
 		default:
-			cn.bad = true
+			cn.setBad()
 			errorf("unknown %s response: %q", protocolState, t)
 		}
 	}
diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go
index 0fdd06a6..8cab67c9 100644
--- a/vendor/github.com/lib/pq/conn_go18.go
+++ b/vendor/github.com/lib/pq/conn_go18.go
@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
+	"sync/atomic"
 	"time"
 )
 
@@ -79,7 +80,7 @@ func (cn *conn) Ping(ctx context.Context) error {
 	if finish := cn.watchCancel(ctx); finish != nil {
 		defer finish()
 	}
-	rows, err := cn.simpleQuery("SELECT 'lib/pq ping test';")
+	rows, err := cn.simpleQuery(";")
 	if err != nil {
 		return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger
 	}
@@ -89,10 +90,21 @@ func (cn *conn) Ping(ctx context.Context) error {
 
 func (cn *conn) watchCancel(ctx context.Context) func() {
 	if done := ctx.Done(); done != nil {
-		finished := make(chan struct{})
+		finished := make(chan struct{}, 1)
 		go func() {
 			select {
 			case <-done:
+				select {
+				case finished <- struct{}{}:
+				default:
+					// We raced with the finish func, let the next query handle this with the
+					// context.
+					return
+				}
+
+				// Set the connection state to bad so it does not get reused.
+				cn.setBad()
+
 				// At this point the function level context is canceled,
 				// so it must not be used for the additional network
 				// request to cancel the query.
@@ -101,13 +113,14 @@ func (cn *conn) watchCancel(ctx context.Context) func() {
 				defer cancel()
 
 				_ = cn.cancel(ctxCancel)
-				finished <- struct{}{}
 			case <-finished:
 			}
 		}()
 		return func() {
 			select {
 			case <-finished:
+				cn.setBad()
+				cn.Close()
 			case finished <- struct{}{}:
 			}
 		}
@@ -123,8 +136,11 @@ func (cn *conn) cancel(ctx context.Context) error {
 	defer c.Close()
 
 	{
+		bad := &atomic.Value{}
+		bad.Store(false)
 		can := conn{
-			c: c,
+			c:   c,
+			bad: bad,
 		}
 		err = can.ssl(cn.opts)
 		if err != nil {
diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go
index 2f8ced67..d7d47261 100644
--- a/vendor/github.com/lib/pq/connector.go
+++ b/vendor/github.com/lib/pq/connector.go
@@ -27,7 +27,7 @@ func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
 	return c.open(ctx)
 }
 
-// Driver returnst the underlying driver of this Connector.
+// Driver returns the underlying driver of this Connector.
 func (c *Connector) Driver() driver.Driver {
 	return &Driver{}
 }
@@ -106,5 +106,10 @@ func NewConnector(dsn string) (*Connector, error) {
 		o["user"] = u
 	}
 
+	// SSL is not necessary or supported over UNIX domain sockets
+	if network, _ := network(o); network == "unix" {
+		o["sslmode"] = "disable"
+	}
+
 	return &Connector{opts: o, dialer: defaultDialer{}}, nil
 }
diff --git a/vendor/github.com/lib/pq/copy.go b/vendor/github.com/lib/pq/copy.go
index 345c2398..bb3cbd7b 100644
--- a/vendor/github.com/lib/pq/copy.go
+++ b/vendor/github.com/lib/pq/copy.go
@@ -49,6 +49,7 @@ type copyin struct {
 	buffer  []byte
 	rowData chan []byte
 	done    chan bool
+	driver.Result
 
 	closed bool
 
@@ -151,8 +152,12 @@ func (ci *copyin) resploop() {
 		switch t {
 		case 'C':
 			// complete
+			res, _ := ci.cn.parseComplete(r.string())
+			ci.setResult(res)
 		case 'N':
-			// NoticeResponse
+			if n := ci.cn.noticeHandler; n != nil {
+				n(parseError(&r))
+			}
 		case 'Z':
 			ci.cn.processReadyForQuery(&r)
 			ci.done <- true
@@ -171,13 +176,13 @@ func (ci *copyin) resploop() {
 
 func (ci *copyin) setBad() {
 	ci.Lock()
-	ci.cn.bad = true
+	ci.cn.setBad()
 	ci.Unlock()
 }
 
 func (ci *copyin) isBad() bool {
 	ci.Lock()
-	b := ci.cn.bad
+	b := ci.cn.getBad()
 	ci.Unlock()
 	return b
 }
@@ -199,6 +204,22 @@ func (ci *copyin) setError(err error) {
 	ci.Unlock()
 }
 
+func (ci *copyin) setResult(result driver.Result) {
+	ci.Lock()
+	ci.Result = result
+	ci.Unlock()
+}
+
+func (ci *copyin) getResult() driver.Result {
+	ci.Lock()
+	result := ci.Result
+	ci.Unlock()
+	if result == nil {
+		return driver.RowsAffected(0)
+	}
+	return result
+}
+
 func (ci *copyin) NumInput() int {
 	return -1
 }
@@ -229,7 +250,11 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
 	}
 
 	if len(v) == 0 {
-		return nil, ci.Close()
+		if err := ci.Close(); err != nil {
+			return driver.RowsAffected(0), err
+		}
+
+		return ci.getResult(), nil
 	}
 
 	numValues := len(v)
diff --git a/vendor/github.com/lib/pq/doc.go b/vendor/github.com/lib/pq/doc.go
index 2a60054e..b5718480 100644
--- a/vendor/github.com/lib/pq/doc.go
+++ b/vendor/github.com/lib/pq/doc.go
@@ -241,5 +241,28 @@ bytes by the PostgreSQL server.
 You can find a complete, working example of Listener usage at
 https://godoc.org/github.com/lib/pq/example/listen.
 
+
+Kerberos Support
+
+
+If you need support for Kerberos authentication, add the following to your main
+package:
+
+	import "github.com/lib/pq/auth/kerberos"
+
+	func init() {
+		pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() })
+	}
+
+This package is in a separate module so that users who don't need Kerberos
+don't have to download unnecessary dependencies.
+
+When imported, additional connection string parameters are supported:
+
+	* krbsrvname - GSS (Kerberos) service name when constructing the
+	  SPN (default is `postgres`). This will be combined with the host
+	  to form the full SPN: `krbsrvname/host`.
+	* krbspn - GSS (Kerberos) SPN. This takes priority over
+	  `krbsrvname` if present.
 */
 package pq
diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go
index 3b0d365f..c4dafe27 100644
--- a/vendor/github.com/lib/pq/encode.go
+++ b/vendor/github.com/lib/pq/encode.go
@@ -8,6 +8,7 @@ import (
 	"errors"
 	"fmt"
 	"math"
+	"regexp"
 	"strconv"
 	"strings"
 	"sync"
@@ -16,6 +17,8 @@ import (
 	"github.com/lib/pq/oid"
 )
 
+var time2400Regex = regexp.MustCompile(`^(24:00(?::00(?:\.0+)?)?)(?:[Z+-].*)?$`)
+
 func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte {
 	switch v := x.(type) {
 	case []byte:
@@ -117,11 +120,10 @@ func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interfa
 		}
 		return i
 	case oid.T_float4, oid.T_float8:
-		bits := 64
-		if typ == oid.T_float4 {
-			bits = 32
-		}
-		f, err := strconv.ParseFloat(string(s), bits)
+		// We always use 64 bit parsing, regardless of whether the input text is for
+		// a float4 or float8, because clients expect float64s for all float datatypes
+		// and returning a 32-bit parsed float64 produces lossy results.
+		f, err := strconv.ParseFloat(string(s), 64)
 		if err != nil {
 			errorf("%s", err)
 		}
@@ -203,10 +205,27 @@ func mustParse(f string, typ oid.Oid, s []byte) time.Time {
 		str[len(str)-3] == ':' {
 		f += ":00"
 	}
+	// Special case for 24:00 time.
+	// Unfortunately, golang does not parse 24:00 as a proper time.
+	// In this case, we want to try "round to the next day", to differentiate.
+	// As such, we find if the 24:00 time matches at the beginning; if so,
+	// we default it back to 00:00 but add a day later.
+	var is2400Time bool
+	switch typ {
+	case oid.T_timetz, oid.T_time:
+		if matches := time2400Regex.FindStringSubmatch(str); matches != nil {
+			// Concatenate timezone information at the back.
+			str = "00:00:00" + str[len(matches[1]):]
+			is2400Time = true
+		}
+	}
 	t, err := time.Parse(f, str)
 	if err != nil {
 		errorf("decode: %s", err)
 	}
+	if is2400Time {
+		t = t.Add(24 * time.Hour)
+	}
 	return t
 }
 
@@ -488,7 +507,7 @@ func FormatTimestamp(t time.Time) []byte {
 	b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00"))
 
 	_, offset := t.Zone()
-	offset = offset % 60
+	offset %= 60
 	if offset != 0 {
 		// RFC3339Nano already printed the minus sign
 		if offset < 0 {
diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go
index 96aae29c..c19c349f 100644
--- a/vendor/github.com/lib/pq/error.go
+++ b/vendor/github.com/lib/pq/error.go
@@ -478,13 +478,13 @@ func errRecoverNoErrBadConn(err *error) {
 	}
 }
 
-func (c *conn) errRecover(err *error) {
+func (cn *conn) errRecover(err *error) {
 	e := recover()
 	switch v := e.(type) {
 	case nil:
 		// Do nothing
 	case runtime.Error:
-		c.bad = true
+		cn.setBad()
 		panic(v)
 	case *Error:
 		if v.Fatal() {
@@ -493,8 +493,11 @@ func (c *conn) errRecover(err *error) {
 			*err = v
 		}
 	case *net.OpError:
-		c.bad = true
+		cn.setBad()
 		*err = v
+	case *safeRetryError:
+		cn.setBad()
+		*err = driver.ErrBadConn
 	case error:
 		if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
 			*err = driver.ErrBadConn
@@ -503,13 +506,13 @@ func (c *conn) errRecover(err *error) {
 		}
 
 	default:
-		c.bad = true
+		cn.setBad()
 		panic(fmt.Sprintf("unknown error: %#v", e))
 	}
 
 	// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
 	// mark the connection bad in database/sql.
 	if *err == driver.ErrBadConn {
-		c.bad = true
+		cn.setBad()
 	}
 }
diff --git a/vendor/github.com/lib/pq/go.mod b/vendor/github.com/lib/pq/go.mod
index edf0b343..b5a5639a 100644
--- a/vendor/github.com/lib/pq/go.mod
+++ b/vendor/github.com/lib/pq/go.mod
@@ -1 +1,3 @@
 module github.com/lib/pq
+
+go 1.13
diff --git a/vendor/github.com/lib/pq/krb.go b/vendor/github.com/lib/pq/krb.go
new file mode 100644
index 00000000..408ec01f
--- /dev/null
+++ b/vendor/github.com/lib/pq/krb.go
@@ -0,0 +1,27 @@
+package pq
+
+// NewGSSFunc creates a GSS authentication provider, for use with
+// RegisterGSSProvider.
+type NewGSSFunc func() (GSS, error)
+
+var newGss NewGSSFunc
+
+// RegisterGSSProvider registers a GSS authentication provider. For example, if
+// you need to use Kerberos to authenticate with your server, add this to your
+// main package:
+//
+//	import "github.com/lib/pq/auth/kerberos"
+//
+//	func init() {
+//		pq.RegisterGSSProvider(func() (pq.GSS, error) { return kerberos.NewGSS() })
+//	}
+func RegisterGSSProvider(newGssArg NewGSSFunc) {
+	newGss = newGssArg
+}
+
+// GSS provides GSSAPI authentication (e.g., Kerberos).
+type GSS interface {
+	GetInitToken(host string, service string) ([]byte, error)
+	GetInitTokenFromSpn(spn string) ([]byte, error)
+	Continue(inToken []byte) (done bool, outToken []byte, err error)
+}
diff --git a/vendor/github.com/lib/pq/notice.go b/vendor/github.com/lib/pq/notice.go
new file mode 100644
index 00000000..01dd8c72
--- /dev/null
+++ b/vendor/github.com/lib/pq/notice.go
@@ -0,0 +1,71 @@
+// +build go1.10
+
+package pq
+
+import (
+	"context"
+	"database/sql/driver"
+)
+
+// NoticeHandler returns the notice handler on the given connection, if any. A
+// runtime panic occurs if c is not a pq connection. This is rarely used
+// directly, use ConnectorNoticeHandler and ConnectorWithNoticeHandler instead.
+func NoticeHandler(c driver.Conn) func(*Error) {
+	return c.(*conn).noticeHandler
+}
+
+// SetNoticeHandler sets the given notice handler on the given connection. A
+// runtime panic occurs if c is not a pq connection. A nil handler may be used
+// to unset it. This is rarely used directly, use ConnectorNoticeHandler and
+// ConnectorWithNoticeHandler instead.
+//
+// Note: Notice handlers are executed synchronously by pq meaning commands
+// won't continue to be processed until the handler returns.
+func SetNoticeHandler(c driver.Conn, handler func(*Error)) {
+	c.(*conn).noticeHandler = handler
+}
+
+// NoticeHandlerConnector wraps a regular connector and sets a notice handler
+// on it.
+type NoticeHandlerConnector struct {
+	driver.Connector
+	noticeHandler func(*Error)
+}
+
+// Connect calls the underlying connector's connect method and then sets the
+// notice handler.
+func (n *NoticeHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) {
+	c, err := n.Connector.Connect(ctx)
+	if err == nil {
+		SetNoticeHandler(c, n.noticeHandler)
+	}
+	return c, err
+}
+
+// ConnectorNoticeHandler returns the currently set notice handler, if any. If
+// the given connector is not a result of ConnectorWithNoticeHandler, nil is
+// returned.
+func ConnectorNoticeHandler(c driver.Connector) func(*Error) {
+	if c, ok := c.(*NoticeHandlerConnector); ok {
+		return c.noticeHandler
+	}
+	return nil
+}
+
+// ConnectorWithNoticeHandler creates or sets the given handler for the given
+// connector. If the given connector is a result of calling this function
+// previously, it is simply set on the given connector and returned. Otherwise,
+// this returns a new connector wrapping the given one and setting the notice
+// handler. A nil notice handler may be used to unset it.
+//
+// The returned connector is intended to be used with database/sql.OpenDB.
+//
+// Note: Notice handlers are executed synchronously by pq meaning commands
+// won't continue to be processed until the handler returns.
+func ConnectorWithNoticeHandler(c driver.Connector, handler func(*Error)) *NoticeHandlerConnector {
+	if c, ok := c.(*NoticeHandlerConnector); ok {
+		c.noticeHandler = handler
+		return c
+	}
+	return &NoticeHandlerConnector{Connector: c, noticeHandler: handler}
+}
diff --git a/vendor/github.com/lib/pq/notify.go b/vendor/github.com/lib/pq/notify.go
index 850bb904..5c421fdb 100644
--- a/vendor/github.com/lib/pq/notify.go
+++ b/vendor/github.com/lib/pq/notify.go
@@ -4,6 +4,8 @@ package pq
 // This module contains support for Postgres LISTEN/NOTIFY.
 
 import (
+	"context"
+	"database/sql/driver"
 	"errors"
 	"fmt"
 	"sync"
@@ -29,6 +31,61 @@ func recvNotification(r *readBuf) *Notification {
 	return &Notification{bePid, channel, extra}
 }
 
+// SetNotificationHandler sets the given notification handler on the given
+// connection. A runtime panic occurs if c is not a pq connection. A nil handler
+// may be used to unset it.
+//
+// Note: Notification handlers are executed synchronously by pq meaning commands
+// won't continue to be processed until the handler returns.
+func SetNotificationHandler(c driver.Conn, handler func(*Notification)) {
+	c.(*conn).notificationHandler = handler
+}
+
+// NotificationHandlerConnector wraps a regular connector and sets a notification handler
+// on it.
+type NotificationHandlerConnector struct {
+	driver.Connector
+	notificationHandler func(*Notification)
+}
+
+// Connect calls the underlying connector's connect method and then sets the
+// notification handler.
+func (n *NotificationHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) {
+	c, err := n.Connector.Connect(ctx)
+	if err == nil {
+		SetNotificationHandler(c, n.notificationHandler)
+	}
+	return c, err
+}
+
+// ConnectorNotificationHandler returns the currently set notification handler, if any. If
+// the given connector is not a result of ConnectorWithNotificationHandler, nil is
+// returned.
+func ConnectorNotificationHandler(c driver.Connector) func(*Notification) {
+	if c, ok := c.(*NotificationHandlerConnector); ok {
+		return c.notificationHandler
+	}
+	return nil
+}
+
+// ConnectorWithNotificationHandler creates or sets the given handler for the given
+// connector. If the given connector is a result of calling this function
+// previously, it is simply set on the given connector and returned. Otherwise,
+// this returns a new connector wrapping the given one and setting the notification
+// handler. A nil notification handler may be used to unset it.
+//
+// The returned connector is intended to be used with database/sql.OpenDB.
+//
+// Note: Notification handlers are executed synchronously by pq meaning commands
+// won't continue to be processed until the handler returns.
+func ConnectorWithNotificationHandler(c driver.Connector, handler func(*Notification)) *NotificationHandlerConnector {
+	if c, ok := c.(*NotificationHandlerConnector); ok {
+		c.notificationHandler = handler
+		return c
+	}
+	return &NotificationHandlerConnector{Connector: c, notificationHandler: handler}
+}
+
 const (
 	connStateIdle int32 = iota
 	connStateExpectResponse
@@ -174,8 +231,12 @@ func (l *ListenerConn) listenerConnLoop() (err error) {
 			}
 			l.replyChan <- message{t, nil}
 
-		case 'N', 'S':
+		case 'S':
 			// ignore
+		case 'N':
+			if n := l.cn.noticeHandler; n != nil {
+				n(parseError(r))
+			}
 		default:
 			return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t)
 		}
diff --git a/vendor/github.com/lib/pq/scram/scram.go b/vendor/github.com/lib/pq/scram/scram.go
new file mode 100644
index 00000000..477216b6
--- /dev/null
+++ b/vendor/github.com/lib/pq/scram/scram.go
@@ -0,0 +1,264 @@
+// Copyright (c) 2014 - Gustavo Niemeyer <gustavo@niemeyer.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Package scram implements a SCRAM-{SHA-1,etc} client per RFC5802.
+//
+// http://tools.ietf.org/html/rfc5802
+//
+package scram
+
+import (
+	"bytes"
+	"crypto/hmac"
+	"crypto/rand"
+	"encoding/base64"
+	"fmt"
+	"hash"
+	"strconv"
+	"strings"
+)
+
+// Client implements a SCRAM-* client (SCRAM-SHA-1, SCRAM-SHA-256, etc).
+//
+// A Client may be used within a SASL conversation with logic resembling:
+//
+//    var in []byte
+//    var client = scram.NewClient(sha1.New, user, pass)
+//    for client.Step(in) {
+//            out := client.Out()
+//            // send out to server
+//            in := serverOut
+//    }
+//    if client.Err() != nil {
+//            // auth failed
+//    }
+//
+type Client struct {
+	newHash func() hash.Hash
+
+	user string
+	pass string
+	step int
+	out  bytes.Buffer
+	err  error
+
+	clientNonce []byte
+	serverNonce []byte
+	saltedPass  []byte
+	authMsg     bytes.Buffer
+}
+
+// NewClient returns a new SCRAM-* client with the provided hash algorithm.
+//
+// For SCRAM-SHA-256, for example, use:
+//
+//    client := scram.NewClient(sha256.New, user, pass)
+//
+func NewClient(newHash func() hash.Hash, user, pass string) *Client {
+	c := &Client{
+		newHash: newHash,
+		user:    user,
+		pass:    pass,
+	}
+	c.out.Grow(256)
+	c.authMsg.Grow(256)
+	return c
+}
+
+// Out returns the data to be sent to the server in the current step.
+func (c *Client) Out() []byte {
+	if c.out.Len() == 0 {
+		return nil
+	}
+	return c.out.Bytes()
+}
+
+// Err returns the error that occurred, or nil if there were no errors.
+func (c *Client) Err() error {
+	return c.err
+}
+
+// SetNonce sets the client nonce to the provided value.
+// If not set, the nonce is generated automatically out of crypto/rand on the first step.
+func (c *Client) SetNonce(nonce []byte) {
+	c.clientNonce = nonce
+}
+
+var escaper = strings.NewReplacer("=", "=3D", ",", "=2C")
+
+// Step processes the incoming data from the server and makes the
+// next round of data for the server available via Client.Out.
+// Step returns false if there are no errors and more data is
+// still expected.
+func (c *Client) Step(in []byte) bool {
+	c.out.Reset()
+	if c.step > 2 || c.err != nil {
+		return false
+	}
+	c.step++
+	switch c.step {
+	case 1:
+		c.err = c.step1(in)
+	case 2:
+		c.err = c.step2(in)
+	case 3:
+		c.err = c.step3(in)
+	}
+	return c.step > 2 || c.err != nil
+}
+
+func (c *Client) step1(in []byte) error {
+	if len(c.clientNonce) == 0 {
+		const nonceLen = 16
+		buf := make([]byte, nonceLen+b64.EncodedLen(nonceLen))
+		if _, err := rand.Read(buf[:nonceLen]); err != nil {
+			return fmt.Errorf("cannot read random SCRAM-SHA-256 nonce from operating system: %v", err)
+		}
+		c.clientNonce = buf[nonceLen:]
+		b64.Encode(c.clientNonce, buf[:nonceLen])
+	}
+	c.authMsg.WriteString("n=")
+	escaper.WriteString(&c.authMsg, c.user)
+	c.authMsg.WriteString(",r=")
+	c.authMsg.Write(c.clientNonce)
+
+	c.out.WriteString("n,,")
+	c.out.Write(c.authMsg.Bytes())
+	return nil
+}
+
+var b64 = base64.StdEncoding
+
+func (c *Client) step2(in []byte) error {
+	c.authMsg.WriteByte(',')
+	c.authMsg.Write(in)
+
+	fields := bytes.Split(in, []byte(","))
+	if len(fields) != 3 {
+		return fmt.Errorf("expected 3 fields in first SCRAM-SHA-256 server message, got %d: %q", len(fields), in)
+	}
+	if !bytes.HasPrefix(fields[0], []byte("r=")) || len(fields[0]) < 2 {
+		return fmt.Errorf("server sent an invalid SCRAM-SHA-256 nonce: %q", fields[0])
+	}
+	if !bytes.HasPrefix(fields[1], []byte("s=")) || len(fields[1]) < 6 {
+		return fmt.Errorf("server sent an invalid SCRAM-SHA-256 salt: %q", fields[1])
+	}
+	if !bytes.HasPrefix(fields[2], []byte("i=")) || len(fields[2]) < 6 {
+		return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2])
+	}
+
+	c.serverNonce = fields[0][2:]
+	if !bytes.HasPrefix(c.serverNonce, c.clientNonce) {
+		return fmt.Errorf("server SCRAM-SHA-256 nonce is not prefixed by client nonce: got %q, want %q+\"...\"", c.serverNonce, c.clientNonce)
+	}
+
+	salt := make([]byte, b64.DecodedLen(len(fields[1][2:])))
+	n, err := b64.Decode(salt, fields[1][2:])
+	if err != nil {
+		return fmt.Errorf("cannot decode SCRAM-SHA-256 salt sent by server: %q", fields[1])
+	}
+	salt = salt[:n]
+	iterCount, err := strconv.Atoi(string(fields[2][2:]))
+	if err != nil {
+		return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2])
+	}
+	c.saltPassword(salt, iterCount)
+
+	c.authMsg.WriteString(",c=biws,r=")
+	c.authMsg.Write(c.serverNonce)
+
+	c.out.WriteString("c=biws,r=")
+	c.out.Write(c.serverNonce)
+	c.out.WriteString(",p=")
+	c.out.Write(c.clientProof())
+	return nil
+}
+
+func (c *Client) step3(in []byte) error {
+	var isv, ise bool
+	var fields = bytes.Split(in, []byte(","))
+	if len(fields) == 1 {
+		isv = bytes.HasPrefix(fields[0], []byte("v="))
+		ise = bytes.HasPrefix(fields[0], []byte("e="))
+	}
+	if ise {
+		return fmt.Errorf("SCRAM-SHA-256 authentication error: %s", fields[0][2:])
+	} else if !isv {
+		return fmt.Errorf("unsupported SCRAM-SHA-256 final message from server: %q", in)
+	}
+	if !bytes.Equal(c.serverSignature(), fields[0][2:]) {
+		return fmt.Errorf("cannot authenticate SCRAM-SHA-256 server signature: %q", fields[0][2:])
+	}
+	return nil
+}
+
+func (c *Client) saltPassword(salt []byte, iterCount int) {
+	mac := hmac.New(c.newHash, []byte(c.pass))
+	mac.Write(salt)
+	mac.Write([]byte{0, 0, 0, 1})
+	ui := mac.Sum(nil)
+	hi := make([]byte, len(ui))
+	copy(hi, ui)
+	for i := 1; i < iterCount; i++ {
+		mac.Reset()
+		mac.Write(ui)
+		mac.Sum(ui[:0])
+		for j, b := range ui {
+			hi[j] ^= b
+		}
+	}
+	c.saltedPass = hi
+}
+
+func (c *Client) clientProof() []byte {
+	mac := hmac.New(c.newHash, c.saltedPass)
+	mac.Write([]byte("Client Key"))
+	clientKey := mac.Sum(nil)
+	hash := c.newHash()
+	hash.Write(clientKey)
+	storedKey := hash.Sum(nil)
+	mac = hmac.New(c.newHash, storedKey)
+	mac.Write(c.authMsg.Bytes())
+	clientProof := mac.Sum(nil)
+	for i, b := range clientKey {
+		clientProof[i] ^= b
+	}
+	clientProof64 := make([]byte, b64.EncodedLen(len(clientProof)))
+	b64.Encode(clientProof64, clientProof)
+	return clientProof64
+}
+
+func (c *Client) serverSignature() []byte {
+	mac := hmac.New(c.newHash, c.saltedPass)
+	mac.Write([]byte("Server Key"))
+	serverKey := mac.Sum(nil)
+
+	mac = hmac.New(c.newHash, serverKey)
+	mac.Write(c.authMsg.Bytes())
+	serverSignature := mac.Sum(nil)
+
+	encoded := make([]byte, b64.EncodedLen(len(serverSignature)))
+	b64.Encode(encoded, serverSignature)
+	return encoded
+}
diff --git a/vendor/github.com/lib/pq/user_posix.go b/vendor/github.com/lib/pq/user_posix.go
index bf982524..a5101920 100644
--- a/vendor/github.com/lib/pq/user_posix.go
+++ b/vendor/github.com/lib/pq/user_posix.go
@@ -1,6 +1,6 @@
 // Package pq is a pure Go Postgres driver for the database/sql package.
 
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris rumprun
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris rumprun
 
 package pq
 
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 01e103f4..aea82a33 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -47,10 +47,11 @@ github.com/golang/protobuf/ptypes/duration
 github.com/golang/protobuf/ptypes/timestamp
 # github.com/gorilla/handlers v1.5.1
 github.com/gorilla/handlers
-# github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6
+# github.com/lib/pq v1.9.0
 ## explicit
 github.com/lib/pq
 github.com/lib/pq/oid
+github.com/lib/pq/scram
 # github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
 github.com/lunixbochs/struc
 # github.com/mattn/go-sqlite3 v0.0.0-20180926090220-0a88db3545c4
-- 
GitLab