aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/lib/pq/conn.go
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2021-01-28 17:56:38 +0100
committerGitHub <noreply@github.com>2021-01-28 17:56:38 +0100
commitd1353e1f7c9bf648cd72bd9731b4f843b0dc9a86 (patch)
treec41437643185d16ab257cf9856a3e1ae8a835112 /vendor/github.com/lib/pq/conn.go
parente45bf12a34d04b18f09663f179fb58aca9ffa192 (diff)
downloadgitea-d1353e1f7c9bf648cd72bd9731b4f843b0dc9a86.tar.gz
gitea-d1353e1f7c9bf648cd72bd9731b4f843b0dc9a86.zip
Vendor Update (#14496)
* update code.gitea.io/sdk/gitea v0.13.1 -> v0.13.2 * update github.com/go-swagger/go-swagger v0.25.0 -> v0.26.0 * update github.com/google/uuid v1.1.2 -> v1.2.0 * update github.com/klauspost/compress v1.11.3 -> v1.11.7 * update github.com/lib/pq 083382b7e6fc -> v1.9.0 * update github.com/markbates/goth v1.65.0 -> v1.66.1 * update github.com/mattn/go-sqlite3 v1.14.4 -> v1.14.6 * update github.com/mgechev/revive 246eac737dc7 -> v1.0.3 * update github.com/minio/minio-go/v7 v7.0.6 -> v7.0.7 * update github.com/niklasfasching/go-org v1.3.2 -> v1.4.0 * update github.com/olivere/elastic/v7 v7.0.21 -> v7.0.22 * update github.com/pquerna/otp v1.2.0 -> v1.3.0 * update github.com/xanzy/go-gitlab v0.39.0 -> v0.42.0 * update github.com/yuin/goldmark v1.2.1 -> v1.3.1
Diffstat (limited to 'vendor/github.com/lib/pq/conn.go')
-rw-r--r--vendor/github.com/lib/pq/conn.go114
1 files changed, 75 insertions, 39 deletions
diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go
index f313c14986..db0b6cef5e 100644
--- a/vendor/github.com/lib/pq/conn.go
+++ b/vendor/github.com/lib/pq/conn.go
@@ -18,6 +18,7 @@ import (
"path/filepath"
"strconv"
"strings"
+ "sync/atomic"
"time"
"unicode"
@@ -38,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)
}
@@ -136,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
@@ -294,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 {
@@ -501,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)
}
}
@@ -513,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)
@@ -524,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
@@ -542,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)
@@ -564,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)
@@ -578,7 +600,7 @@ 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)
@@ -590,7 +612,7 @@ func (cn *conn) rollback() (err error) {
_, commandTag, err := cn.simpleExec("ROLLBACK")
if err != nil {
if cn.isInTransaction() {
- cn.bad = true
+ cn.setBad()
}
return err
}
@@ -630,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)
}
}
@@ -652,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 {
@@ -663,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':
@@ -676,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
@@ -691,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)
}
}
@@ -784,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)
@@ -823,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 {
@@ -857,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)
@@ -891,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)
}
}
@@ -918,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
@@ -1288,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)
@@ -1302,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)
@@ -1318,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)
@@ -1331,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)
@@ -1418,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]
@@ -1430,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
@@ -1497,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)
@@ -1522,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) {
@@ -1717,7 +1753,7 @@ func (cn *conn) readReadyForQuery() {
cn.processReadyForQuery(r)
return
default:
- cn.bad = true
+ cn.setBad()
errorf("unexpected message %q; expected ReadyForQuery", t)
}
}
@@ -1737,7 +1773,7 @@ func (cn *conn) readParseResponse() {
cn.readReadyForQuery()
panic(err)
default:
- cn.bad = true
+ cn.setBad()
errorf("unexpected Parse response %q", t)
}
}
@@ -1762,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)
}
}
@@ -1780,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")
@@ -1796,7 +1832,7 @@ func (cn *conn) readBindResponse() {
cn.readReadyForQuery()
panic(err)
default:
- cn.bad = true
+ cn.setBad()
errorf("unexpected Bind response %q", t)
}
}
@@ -1823,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)
}
}
@@ -1836,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())
@@ -1850,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' {
@@ -1858,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)
}
}