Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,26 @@ newer. Previously PostgreSQL 8.4 and newer were supported.

- Add support for NamedValueChecker interface ([#1125])

- The `pq.Error.ErrorWithDetail()` method prints a more detailed multiline
message, with the Detail, Hint, and error position (if any) ([#1219]):

ERROR: syntax error at or near ")" (42601)
CONTEXT: line 12, column 1:

10 | name varchar,
11 | version varchar,
12 | );
^

### Fixes

- Match HOME directory lookup logic with libpq: prefer $HOME over /etc/passwd,
ignore ENOTDIR errors, and use APPDATA on Windows ([#1214]).

- The `pq.Error.Error()` message now includes the SQLSTATE error code ([#1219]):

pq: syntax error at end of input (42601)

- Fix build with wasm ([#1184]), appengine ([#745]), and Plan 9 ([#1133]).

- Deprecate and type alias `pq.NullTime` to `sql.NullTime` ([#1211]).
Expand Down Expand Up @@ -47,6 +62,7 @@ newer. Previously PostgreSQL 8.4 and newer were supported.
[#1211]: https://github.com/lib/pq/pull/1211
[#1212]: https://github.com/lib/pq/pull/1212
[#1214]: https://github.com/lib/pq/pull/1214
[#1219]: https://github.com/lib/pq/pull/1219


v1.10.9 (2023-04-26)
Expand Down
36 changes: 17 additions & 19 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err
// done
return
case 'E':
err = parseError(r)
err = parseError(r, q)
case 'I':
res = emptyRows
case 'T', 'D':
Expand All @@ -730,7 +730,7 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err
}

func (cn *conn) simpleQuery(q string) (res *rows, err error) {
defer cn.errRecover(&err)
defer cn.errRecover(&err, q)

b := cn.writeBuf('Q')
b.string(q)
Expand Down Expand Up @@ -769,7 +769,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
return
case 'E':
res = nil
err = parseError(r)
err = parseError(r, q)
case 'D':
if res == nil {
cn.err.set(driver.ErrBadConn)
Expand Down Expand Up @@ -886,7 +886,7 @@ func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) {
if err := cn.err.get(); err != nil {
return nil, err
}
defer cn.errRecover(&err)
defer cn.errRecover(&err, q)

if len(q) >= 4 && strings.EqualFold(q[:4], "COPY") {
s, err := cn.prepareCopyIn(q)
Expand Down Expand Up @@ -928,7 +928,7 @@ func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) {
if cn.inCopy {
return nil, errCopyInProgress
}
defer cn.errRecover(&err)
defer cn.errRecover(&err, query)

// Check to see if we can use the "simpleQuery" interface, which is
// *much* faster than going through prepare/exec
Expand Down Expand Up @@ -959,7 +959,7 @@ func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err
if err := cn.err.get(); err != nil {
return nil, err
}
defer cn.errRecover(&err)
defer cn.errRecover(&err, query)

// Check to see if we can use the "simpleExec" interface, which is
// *much* faster than going through prepare/exec
Expand Down Expand Up @@ -1084,10 +1084,10 @@ func (cn *conn) recv() (t byte, r *readBuf) {
}
switch t {
case 'E':
panic(parseError(r))
panic(parseError(r, ""))
case 'N':
if n := cn.noticeHandler; n != nil {
n(parseError(r))
n(parseError(r, ""))
}
case 'A':
if n := cn.notificationHandler; n != nil {
Expand Down Expand Up @@ -1115,7 +1115,7 @@ func (cn *conn) recv1Buf(r *readBuf) byte {
}
case 'N':
if n := cn.noticeHandler; n != nil {
n(parseError(r))
n(parseError(r, ""))
}
case 'S':
cn.processParameterStatus(r)
Expand Down Expand Up @@ -1619,7 +1619,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
t := conn.recv1Buf(&rs.rb)
switch t {
case 'E':
err = parseError(&rs.rb)
err = parseError(&rs.rb, "")
case 'C', 'I':
if t == 'C' {
rs.result, rs.tag = conn.parseComplete(rs.rb.string())
Expand Down Expand Up @@ -1857,7 +1857,7 @@ func (cn *conn) readParseResponse() {
case '1':
return
case 'E':
err := parseError(r)
err := parseError(r, "")
cn.readReadyForQuery()
panic(err)
default:
Expand Down Expand Up @@ -1886,7 +1886,7 @@ func (cn *conn) readStatementDescribeResponse() (
colNames, colTyps = parseStatementRowDescribe(r)
return paramTyps, colNames, colTyps
case 'E':
err := parseError(r)
err := parseError(r, "")
cn.readReadyForQuery()
panic(err)
default:
Expand All @@ -1904,7 +1904,7 @@ func (cn *conn) readPortalDescribeResponse() rowsHeader {
case 'n':
return rowsHeader{}
case 'E':
err := parseError(r)
err := parseError(r, "")
cn.readReadyForQuery()
panic(err)
default:
Expand All @@ -1920,7 +1920,7 @@ func (cn *conn) readBindResponse() {
case '2':
return
case 'E':
err := parseError(r)
err := parseError(r, "")
cn.readReadyForQuery()
panic(err)
default:
Expand All @@ -1943,7 +1943,7 @@ func (cn *conn) postExecuteWorkaround() {
t, r := cn.recv1()
switch t {
case 'E':
err := parseError(r)
err := parseError(r, "")
cn.readReadyForQuery()
panic(err)
case 'C', 'D', 'I':
Expand All @@ -1958,9 +1958,7 @@ func (cn *conn) postExecuteWorkaround() {
}

// Only for Exec(), since we ignore the returned data
func (cn *conn) readExecuteResponse(
protocolState string,
) (res driver.Result, commandTag string, err error) {
func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, commandTag string, err error) {
for {
t, r := cn.recv1()
switch t {
Expand All @@ -1977,7 +1975,7 @@ func (cn *conn) readExecuteResponse(
}
return res, commandTag, err
case 'E':
err = parseError(r)
err = parseError(r, "")
case 'T', 'D', 'I':
if err != nil {
cn.err.set(driver.ErrBadConn)
Expand Down
6 changes: 3 additions & 3 deletions copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ awaitCopyInResponse:
err = errCopyToNotSupported
break awaitCopyInResponse
case 'E':
err = parseError(r)
err = parseError(r, q)
case 'Z':
if err == nil {
ci.setBad(driver.ErrBadConn)
Expand Down Expand Up @@ -170,14 +170,14 @@ func (ci *copyin) resploop() {
ci.setResult(res)
case 'N':
if n := ci.cn.noticeHandler; n != nil {
n(parseError(&r))
n(parseError(&r, ""))
}
case 'Z':
ci.cn.processReadyForQuery(&r)
ci.done <- true
return
case 'E':
err := parseError(&r)
err := parseError(&r, "")
ci.setError(err)
default:
ci.setBad(driver.ErrBadConn)
Expand Down
Loading
Loading