mirror of https://github.com/jackc/pgx.git
commit
1819959d07
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
|
||||||
|
If possible, please provide runnable example such as:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer conn.Close(context.Background())
|
||||||
|
|
||||||
|
// Your code here...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Actual behavior**
|
||||||
|
A clear and concise description of what actually happened.
|
||||||
|
|
||||||
|
**Version**
|
||||||
|
- Go: `$ go version` -> [e.g. go version go1.18.3 darwin/amd64]
|
||||||
|
- PostgreSQL: `$ psql --no-psqlrc --tuples-only -c 'select version()'` -> [e.g. PostgreSQL 14.4 on x86_64-apple-darwin21.5.0, compiled by Apple clang version 13.1.6 (clang-1316.0.21.2.5), 64-bit]
|
||||||
|
- pgx: `$ grep 'github.com/jackc/pgx/v[0-9]' go.mod` -> [e.g. v4.16.1]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Other issues
|
||||||
|
about: Any issue that is not a bug or a feature request
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Please describe the issue in detail. If this is a question about how to use pgx please use discussions instead.
|
|
@ -70,6 +70,16 @@ func (cr *connResource) getPoolRows(c *Conn, r pgx.Rows) *poolRows {
|
||||||
return pr
|
return pr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detachedCtx wraps a context and will never be canceled, regardless of if
|
||||||
|
// the wrapped one is cancelled. The Err() method will never return any errors.
|
||||||
|
type detachedCtx struct {
|
||||||
|
context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (detachedCtx) Done() <-chan struct{} { return nil }
|
||||||
|
func (detachedCtx) Deadline() (time.Time, bool) { return time.Time{}, false }
|
||||||
|
func (detachedCtx) Err() error { return nil }
|
||||||
|
|
||||||
// Pool allows for connection reuse.
|
// Pool allows for connection reuse.
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
p *puddle.Pool[*connResource]
|
p *puddle.Pool[*connResource]
|
||||||
|
@ -189,6 +199,19 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
|
||||||
|
|
||||||
p.p = puddle.NewPool(
|
p.p = puddle.NewPool(
|
||||||
func(ctx context.Context) (*connResource, error) {
|
func(ctx context.Context) (*connResource, error) {
|
||||||
|
// we ignore cancellation on the original context because its either from
|
||||||
|
// the health check or its from a query and we don't want to cancel creating
|
||||||
|
// a connection just because the original query was cancelled since that
|
||||||
|
// could end up stampeding the server
|
||||||
|
// this will keep any Values in the original context and will just ignore
|
||||||
|
// cancellation
|
||||||
|
// see https://github.com/jackc/pgx/issues/1259
|
||||||
|
ctx = detachedCtx{ctx}
|
||||||
|
|
||||||
|
// But we do want to ensure that a connect won't hang forever.
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
connConfig := p.config.ConnConfig
|
connConfig := p.config.ConnConfig
|
||||||
|
|
||||||
if p.beforeConnect != nil {
|
if p.beforeConnect != nil {
|
||||||
|
@ -651,7 +674,7 @@ func (p *Pool) BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, er
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Tx{t: t, c: c}, err
|
return &Tx{t: t, c: c}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) {
|
func (p *Pool) CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) {
|
||||||
|
|
|
@ -47,6 +47,32 @@ func TestParseConfigExtractsPoolArguments(t *testing.T) {
|
||||||
assert.NotContains(t, config.ConnConfig.Config.RuntimeParams, "pool_min_conns")
|
assert.NotContains(t, config.ConnConfig.Config.RuntimeParams, "pool_min_conns")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConstructorIgnoresContext(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
config, err := pgxpool.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
var cancel func()
|
||||||
|
config.BeforeConnect = func(context.Context, *pgx.ConnConfig) error {
|
||||||
|
// cancel the query's context before we actually Dial to ensure the Dial's
|
||||||
|
// context isn't cancelled
|
||||||
|
cancel()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pool, err := pgxpool.NewWithConfig(context.Background(), config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, 0, pool.Stat().TotalConns())
|
||||||
|
|
||||||
|
var ctx context.Context
|
||||||
|
ctx, cancel = context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
_, err = pool.Exec(ctx, "SELECT 1")
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
assert.EqualValues(t, 1, pool.Stat().TotalConns())
|
||||||
|
}
|
||||||
|
|
||||||
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue