lib / pq

Pure Go Postgres driver for database/sql
https://pkg.go.dev/github.com/lib/pq
MIT License
8.89k stars 906 forks source link

stmt.QueryRowContext doesn't respect canceled context #1046

Closed michaelshobbs closed 2 years ago

michaelshobbs commented 3 years ago

Working on a project using https://github.com/jmoiron/sqlx, I ran into this issue when using PrepareContext()/QueryRowContext with a context with timeout.

The following test case exercises the problem

func TestIssue1046(t *testing.T) {
    ctxTimeout := time.Second * 2
    sleepSQL := `SELECT pg_sleep(10) AS id`

    db := openTestConn(t)
    defer db.Close()

    ctx, cancel := context.WithTimeout(context.Background(), ctxTimeout)
    defer cancel()

    stmt, err := db.PrepareContext(ctx, sleepSQL)
    if err != nil {
        t.Fatal(err)
    }

    var d []uint8
    err = stmt.QueryRowContext(ctx).Scan(&d)
    dl, _ := ctx.Deadline()
    since := time.Since(dl)
    if since > ctxTimeout {
        t.Logf("FAIL %s: query returned after context deadline: %v\n", t.Name(), since)
        t.Fail()
    }
    expectedErr := &Error{Message: "canceling statement due to user request"}
    if err == nil || err.Error() != expectedErr.Error() {
        t.Logf("ctx.Err(): [%T]%+v\n", ctx.Err(), ctx.Err())
        t.Logf("got err: [%T] %+v expected err: [%T] %+v", err, err, expectedErr, expectedErr)
        t.Fail()
    }
}
michaelshobbs commented 3 years ago

I found #921 and pulling that into master locally seems to resolve the issue. I'll open up a new PR and add test cases