mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-01-22 08:36:24 +01:00
[chore]: Bump github.com/jackc/pgx/v5 from 5.7.1 to 5.7.2 (#3663)
Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.7.1 to 5.7.2. - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
0096222c0e
commit
cfe6ac5a42
19 changed files with 559 additions and 98 deletions
2
go.mod
2
go.mod
|
@ -56,7 +56,7 @@ require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/feeds v1.2.0
|
github.com/gorilla/feeds v1.2.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/jackc/pgx/v5 v5.7.1
|
github.com/jackc/pgx/v5 v5.7.2
|
||||||
github.com/k3a/html2text v1.2.1
|
github.com/k3a/html2text v1.2.1
|
||||||
github.com/microcosm-cc/bluemonday v1.0.27
|
github.com/microcosm-cc/bluemonday v1.0.27
|
||||||
github.com/miekg/dns v1.1.62
|
github.com/miekg/dns v1.1.62
|
||||||
|
|
4
go.sum
generated
4
go.sum
generated
|
@ -355,8 +355,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
|
12
vendor/github.com/jackc/pgx/v5/CHANGELOG.md
generated
vendored
12
vendor/github.com/jackc/pgx/v5/CHANGELOG.md
generated
vendored
|
@ -1,3 +1,15 @@
|
||||||
|
# 5.7.2 (December 21, 2024)
|
||||||
|
|
||||||
|
* Fix prepared statement already exists on batch prepare failure
|
||||||
|
* Add commit query to tx options (Lucas Hild)
|
||||||
|
* Fix pgtype.Timestamp json unmarshal (Shean de Montigny-Desautels)
|
||||||
|
* Add message body size limits in frontend and backend (zene)
|
||||||
|
* Add xid8 type
|
||||||
|
* Ensure planning encodes and scans cannot infinitely recurse
|
||||||
|
* Implement pgtype.UUID.String() (Konstantin Grachev)
|
||||||
|
* Switch from ExecParams to Exec in ValidateConnectTargetSessionAttrs functions (Alexander Rumyantsev)
|
||||||
|
* Update golang.org/x/crypto
|
||||||
|
|
||||||
# 5.7.1 (September 10, 2024)
|
# 5.7.1 (September 10, 2024)
|
||||||
|
|
||||||
* Fix data race in tracelog.TraceLog
|
* Fix data race in tracelog.TraceLog
|
||||||
|
|
8
vendor/github.com/jackc/pgx/v5/README.md
generated
vendored
8
vendor/github.com/jackc/pgx/v5/README.md
generated
vendored
|
@ -84,7 +84,7 @@ It is also possible to use the `database/sql` interface and convert a connection
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
See CONTRIBUTING.md for setup instructions.
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ pgerrcode contains constants for the PostgreSQL error codes.
|
||||||
|
|
||||||
## Adapters for 3rd Party Tracers
|
## Adapters for 3rd Party Tracers
|
||||||
|
|
||||||
* [https://github.com/jackhopner/pgx-xray-tracer](https://github.com/jackhopner/pgx-xray-tracer)
|
* [github.com/jackhopner/pgx-xray-tracer](https://github.com/jackhopner/pgx-xray-tracer)
|
||||||
|
|
||||||
## Adapters for 3rd Party Loggers
|
## Adapters for 3rd Party Loggers
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ Library for scanning data from a database into Go structs and more.
|
||||||
A carefully designed SQL client for making using SQL easier,
|
A carefully designed SQL client for making using SQL easier,
|
||||||
more productive, and less error-prone on Golang.
|
more productive, and less error-prone on Golang.
|
||||||
|
|
||||||
### [https://github.com/otan/gopgkrb5](https://github.com/otan/gopgkrb5)
|
### [github.com/otan/gopgkrb5](https://github.com/otan/gopgkrb5)
|
||||||
|
|
||||||
Adds GSSAPI / Kerberos authentication support.
|
Adds GSSAPI / Kerberos authentication support.
|
||||||
|
|
||||||
|
@ -169,6 +169,6 @@ Explicit data mapping and scanning library for Go structs and slices.
|
||||||
Type safe and flexible package for scanning database data into Go types.
|
Type safe and flexible package for scanning database data into Go types.
|
||||||
Supports, structs, maps, slices and custom mapping functions.
|
Supports, structs, maps, slices and custom mapping functions.
|
||||||
|
|
||||||
### [https://github.com/z0ne-dev/mgx](https://github.com/z0ne-dev/mgx)
|
### [github.com/z0ne-dev/mgx](https://github.com/z0ne-dev/mgx)
|
||||||
|
|
||||||
Code first migration library for native pgx (no database/sql abstraction).
|
Code first migration library for native pgx (no database/sql abstraction).
|
||||||
|
|
109
vendor/github.com/jackc/pgx/v5/conn.go
generated
vendored
109
vendor/github.com/jackc/pgx/v5/conn.go
generated
vendored
|
@ -650,21 +650,32 @@ func (c *Conn) getRows(ctx context.Context, sql string, args []any) *baseRows {
|
||||||
// registered with pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are
|
// registered with pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are
|
||||||
// unregistered or ambiguous. e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know
|
// unregistered or ambiguous. e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know
|
||||||
// the PostgreSQL type can use a map[string]string directly as an argument. This mode cannot.
|
// the PostgreSQL type can use a map[string]string directly as an argument. This mode cannot.
|
||||||
|
//
|
||||||
|
// On rare occasions user defined types may behave differently when encoded in the text format instead of the binary
|
||||||
|
// format. For example, this could happen if a "type RomanNumeral int32" implements fmt.Stringer to format integers as
|
||||||
|
// Roman numerals (e.g. 7 is VII). The binary format would properly encode the integer 7 as the binary value for 7.
|
||||||
|
// But the text format would encode the integer 7 as the string "VII". As QueryExecModeExec uses the text format, it
|
||||||
|
// is possible that changing query mode from another mode to QueryExecModeExec could change the behavior of the query.
|
||||||
|
// This should not occur with types pgx supports directly and can be avoided by registering the types with
|
||||||
|
// pgtype.Map.RegisterDefaultPgType and implementing the appropriate type interfaces. In the cas of RomanNumeral, it
|
||||||
|
// should implement pgtype.Int64Valuer.
|
||||||
QueryExecModeExec
|
QueryExecModeExec
|
||||||
|
|
||||||
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments.
|
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments. Queries
|
||||||
// Queries are executed in a single round trip. Type mappings can be registered with
|
// are executed in a single round trip. Type mappings can be registered with pgtype.Map.RegisterDefaultPgType. Queries
|
||||||
// pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are unregistered or ambiguous.
|
// will be rejected that have arguments that are unregistered or ambiguous. e.g. A map[string]string may have the
|
||||||
// e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know the PostgreSQL type can use
|
// PostgreSQL type json or hstore. Modes that know the PostgreSQL type can use a map[string]string directly as an
|
||||||
// a map[string]string directly as an argument. This mode cannot.
|
// argument. This mode cannot.
|
||||||
//
|
//
|
||||||
// QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec with minor
|
// QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec. This includes
|
||||||
// exceptions such as behavior when multiple result returning queries are erroneously sent in a single string.
|
// the warning regarding differences in text format and binary format encoding with user defined types. There may be
|
||||||
|
// other minor exceptions such as behavior when multiple result returning queries are erroneously sent in a single
|
||||||
|
// string.
|
||||||
//
|
//
|
||||||
// QueryExecModeSimpleProtocol uses client side parameter interpolation. All values are quoted and escaped. Prefer
|
// QueryExecModeSimpleProtocol uses client side parameter interpolation. All values are quoted and escaped. Prefer
|
||||||
// QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol
|
// QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol should
|
||||||
// should only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does
|
// only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does not
|
||||||
// not support the extended protocol.
|
// support the extended protocol.
|
||||||
QueryExecModeSimpleProtocol
|
QueryExecModeSimpleProtocol
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -904,6 +915,9 @@ func (c *Conn) QueryRow(ctx context.Context, sql string, args ...any) Row {
|
||||||
// SendBatch sends all queued queries to the server at once. All queries are run in an implicit transaction unless
|
// SendBatch sends all queued queries to the server at once. All queries are run in an implicit transaction unless
|
||||||
// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection
|
// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection
|
||||||
// is used again.
|
// is used again.
|
||||||
|
//
|
||||||
|
// Depending on the QueryExecMode, all queries may be prepared before any are executed. This means that creating a table
|
||||||
|
// and using it in a subsequent query in the same batch can fail.
|
||||||
func (c *Conn) SendBatch(ctx context.Context, b *Batch) (br BatchResults) {
|
func (c *Conn) SendBatch(ctx context.Context, b *Batch) (br BatchResults) {
|
||||||
if c.batchTracer != nil {
|
if c.batchTracer != nil {
|
||||||
ctx = c.batchTracer.TraceBatchStart(ctx, c, TraceBatchStartData{Batch: b})
|
ctx = c.batchTracer.TraceBatchStart(ctx, c, TraceBatchStartData{Batch: b})
|
||||||
|
@ -1126,47 +1140,64 @@ func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b *Batch, d
|
||||||
|
|
||||||
// Prepare any needed queries
|
// Prepare any needed queries
|
||||||
if len(distinctNewQueries) > 0 {
|
if len(distinctNewQueries) > 0 {
|
||||||
for _, sd := range distinctNewQueries {
|
err := func() (err error) {
|
||||||
pipeline.SendPrepare(sd.Name, sd.SQL, nil)
|
for _, sd := range distinctNewQueries {
|
||||||
}
|
pipeline.SendPrepare(sd.Name, sd.SQL, nil)
|
||||||
|
}
|
||||||
|
|
||||||
err := pipeline.Sync()
|
// Store all statements we are preparing into the cache. It's fine if it overflows because HandleInvalidated will
|
||||||
if err != nil {
|
// clean them up later.
|
||||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
if sdCache != nil {
|
||||||
}
|
for _, sd := range distinctNewQueries {
|
||||||
|
sdCache.Put(sd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If something goes wrong preparing the statements, we need to invalidate the cache entries we just added.
|
||||||
|
defer func() {
|
||||||
|
if err != nil && sdCache != nil {
|
||||||
|
for _, sd := range distinctNewQueries {
|
||||||
|
sdCache.Invalidate(sd.SQL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = pipeline.Sync()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sd := range distinctNewQueries {
|
||||||
|
results, err := pipeline.GetResults()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resultSD, ok := results.(*pgconn.StatementDescription)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected statement description, got %T", results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in the previously empty / pending statement descriptions.
|
||||||
|
sd.ParamOIDs = resultSD.ParamOIDs
|
||||||
|
sd.Fields = resultSD.Fields
|
||||||
|
}
|
||||||
|
|
||||||
for _, sd := range distinctNewQueries {
|
|
||||||
results, err := pipeline.GetResults()
|
results, err := pipeline.GetResults()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
resultSD, ok := results.(*pgconn.StatementDescription)
|
_, ok := results.(*pgconn.PipelineSync)
|
||||||
if !ok {
|
if !ok {
|
||||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected statement description, got %T", results), closed: true}
|
return fmt.Errorf("expected sync, got %T", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the previously empty / pending statement descriptions.
|
return nil
|
||||||
sd.ParamOIDs = resultSD.ParamOIDs
|
}()
|
||||||
sd.Fields = resultSD.Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := pipeline.GetResults()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := results.(*pgconn.PipelineSync)
|
|
||||||
if !ok {
|
|
||||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected sync, got %T", results), closed: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put all statements into the cache. It's fine if it overflows because HandleInvalidated will clean them up later.
|
|
||||||
if sdCache != nil {
|
|
||||||
for _, sd := range distinctNewQueries {
|
|
||||||
sdCache.Put(sd)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue the queries.
|
// Queue the queries.
|
||||||
|
|
40
vendor/github.com/jackc/pgx/v5/pgconn/config.go
generated
vendored
40
vendor/github.com/jackc/pgx/v5/pgconn/config.go
generated
vendored
|
@ -861,12 +861,12 @@ func makeConnectTimeoutDialFunc(timeout time.Duration) DialFunc {
|
||||||
// ValidateConnectTargetSessionAttrsReadWrite is a ValidateConnectFunc that implements libpq compatible
|
// ValidateConnectTargetSessionAttrsReadWrite is a ValidateConnectFunc that implements libpq compatible
|
||||||
// target_session_attrs=read-write.
|
// target_session_attrs=read-write.
|
||||||
func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgConn *PgConn) error {
|
func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgConn *PgConn) error {
|
||||||
result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read()
|
result, err := pgConn.Exec(ctx, "show transaction_read_only").ReadAll()
|
||||||
if result.Err != nil {
|
if err != nil {
|
||||||
return result.Err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(result.Rows[0][0]) == "on" {
|
if string(result[0].Rows[0][0]) == "on" {
|
||||||
return errors.New("read only connection")
|
return errors.New("read only connection")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,12 +876,12 @@ func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgConn *PgC
|
||||||
// ValidateConnectTargetSessionAttrsReadOnly is a ValidateConnectFunc that implements libpq compatible
|
// ValidateConnectTargetSessionAttrsReadOnly is a ValidateConnectFunc that implements libpq compatible
|
||||||
// target_session_attrs=read-only.
|
// target_session_attrs=read-only.
|
||||||
func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgConn) error {
|
func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgConn) error {
|
||||||
result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read()
|
result, err := pgConn.Exec(ctx, "show transaction_read_only").ReadAll()
|
||||||
if result.Err != nil {
|
if err != nil {
|
||||||
return result.Err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(result.Rows[0][0]) != "on" {
|
if string(result[0].Rows[0][0]) != "on" {
|
||||||
return errors.New("connection is not read only")
|
return errors.New("connection is not read only")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,12 +891,12 @@ func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgCo
|
||||||
// ValidateConnectTargetSessionAttrsStandby is a ValidateConnectFunc that implements libpq compatible
|
// ValidateConnectTargetSessionAttrsStandby is a ValidateConnectFunc that implements libpq compatible
|
||||||
// target_session_attrs=standby.
|
// target_session_attrs=standby.
|
||||||
func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgConn) error {
|
func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgConn) error {
|
||||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||||
if result.Err != nil {
|
if err != nil {
|
||||||
return result.Err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(result.Rows[0][0]) != "t" {
|
if string(result[0].Rows[0][0]) != "t" {
|
||||||
return errors.New("server is not in hot standby mode")
|
return errors.New("server is not in hot standby mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,12 +906,12 @@ func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgCon
|
||||||
// ValidateConnectTargetSessionAttrsPrimary is a ValidateConnectFunc that implements libpq compatible
|
// ValidateConnectTargetSessionAttrsPrimary is a ValidateConnectFunc that implements libpq compatible
|
||||||
// target_session_attrs=primary.
|
// target_session_attrs=primary.
|
||||||
func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgConn) error {
|
func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgConn) error {
|
||||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||||
if result.Err != nil {
|
if err != nil {
|
||||||
return result.Err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(result.Rows[0][0]) == "t" {
|
if string(result[0].Rows[0][0]) == "t" {
|
||||||
return errors.New("server is in standby mode")
|
return errors.New("server is in standby mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,12 +921,12 @@ func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgCon
|
||||||
// ValidateConnectTargetSessionAttrsPreferStandby is a ValidateConnectFunc that implements libpq compatible
|
// ValidateConnectTargetSessionAttrsPreferStandby is a ValidateConnectFunc that implements libpq compatible
|
||||||
// target_session_attrs=prefer-standby.
|
// target_session_attrs=prefer-standby.
|
||||||
func ValidateConnectTargetSessionAttrsPreferStandby(ctx context.Context, pgConn *PgConn) error {
|
func ValidateConnectTargetSessionAttrsPreferStandby(ctx context.Context, pgConn *PgConn) error {
|
||||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||||
if result.Err != nil {
|
if err != nil {
|
||||||
return result.Err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(result.Rows[0][0]) != "t" {
|
if string(result[0].Rows[0][0]) != "t" {
|
||||||
return &NotPreferredError{err: errors.New("server is not in hot standby mode")}
|
return &NotPreferredError{err: errors.New("server is not in hot standby mode")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
vendor/github.com/jackc/pgx/v5/pgproto3/backend.go
generated
vendored
15
vendor/github.com/jackc/pgx/v5/pgproto3/backend.go
generated
vendored
|
@ -175,7 +175,13 @@ func (b *Backend) Receive() (FrontendMessage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b.msgType = header[0]
|
b.msgType = header[0]
|
||||||
b.bodyLen = int(binary.BigEndian.Uint32(header[1:])) - 4
|
|
||||||
|
msgLength := int(binary.BigEndian.Uint32(header[1:]))
|
||||||
|
if msgLength < 4 {
|
||||||
|
return nil, fmt.Errorf("invalid message length: %d", msgLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.bodyLen = msgLength - 4
|
||||||
if b.maxBodyLen > 0 && b.bodyLen > b.maxBodyLen {
|
if b.maxBodyLen > 0 && b.bodyLen > b.maxBodyLen {
|
||||||
return nil, &ExceededMaxBodyLenErr{b.maxBodyLen, b.bodyLen}
|
return nil, &ExceededMaxBodyLenErr{b.maxBodyLen, b.bodyLen}
|
||||||
}
|
}
|
||||||
|
@ -282,9 +288,10 @@ func (b *Backend) SetAuthType(authType uint32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMaxBodyLen sets the maximum length of a message body in octets. If a message body exceeds this length, Receive will return
|
// SetMaxBodyLen sets the maximum length of a message body in octets.
|
||||||
// an error. This is useful for protecting against malicious clients that send large messages with the intent of
|
// If a message body exceeds this length, Receive will return an error.
|
||||||
// causing memory exhaustion.
|
// This is useful for protecting against malicious clients that send
|
||||||
|
// large messages with the intent of causing memory exhaustion.
|
||||||
// The default value is 0.
|
// The default value is 0.
|
||||||
// If maxBodyLen is 0, then no maximum is enforced.
|
// If maxBodyLen is 0, then no maximum is enforced.
|
||||||
func (b *Backend) SetMaxBodyLen(maxBodyLen int) {
|
func (b *Backend) SetMaxBodyLen(maxBodyLen int) {
|
||||||
|
|
14
vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go
generated
vendored
14
vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go
generated
vendored
|
@ -54,6 +54,7 @@ functionCallResponse FunctionCallResponse
|
||||||
portalSuspended PortalSuspended
|
portalSuspended PortalSuspended
|
||||||
|
|
||||||
bodyLen int
|
bodyLen int
|
||||||
|
maxBodyLen int // maxBodyLen is the maximum length of a message body in octets. If a message body exceeds this length, Receive will return an error.
|
||||||
msgType byte
|
msgType byte
|
||||||
partialMsg bool
|
partialMsg bool
|
||||||
authType uint32
|
authType uint32
|
||||||
|
@ -317,6 +318,9 @@ func (f *Frontend) Receive() (BackendMessage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
f.bodyLen = msgLength - 4
|
f.bodyLen = msgLength - 4
|
||||||
|
if f.maxBodyLen > 0 && f.bodyLen > f.maxBodyLen {
|
||||||
|
return nil, &ExceededMaxBodyLenErr{f.maxBodyLen, f.bodyLen}
|
||||||
|
}
|
||||||
f.partialMsg = true
|
f.partialMsg = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,3 +456,13 @@ func (f *Frontend) GetAuthType() uint32 {
|
||||||
func (f *Frontend) ReadBufferLen() int {
|
func (f *Frontend) ReadBufferLen() int {
|
||||||
return f.cr.wp - f.cr.rp
|
return f.cr.wp - f.cr.rp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetMaxBodyLen sets the maximum length of a message body in octets.
|
||||||
|
// If a message body exceeds this length, Receive will return an error.
|
||||||
|
// This is useful for protecting against a corrupted server that sends
|
||||||
|
// messages with incorrect length, which can cause memory exhaustion.
|
||||||
|
// The default value is 0.
|
||||||
|
// If maxBodyLen is 0, then no maximum is enforced.
|
||||||
|
func (f *Frontend) SetMaxBodyLen(maxBodyLen int) {
|
||||||
|
f.maxBodyLen = maxBodyLen
|
||||||
|
}
|
||||||
|
|
4
vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb
generated
vendored
4
vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb
generated
vendored
|
@ -25,7 +25,7 @@ func BenchmarkQuery<%= format_name %>FormatDecode_PG_<%= pg_type %>_to_Go_<%= go
|
||||||
rows, _ := conn.Query(
|
rows, _ := conn.Query(
|
||||||
ctx,
|
ctx,
|
||||||
`select <% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>n::<%= pg_type %> + <%= col_idx%><% end %> from generate_series(1, <%= rows %>) n`,
|
`select <% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>n::<%= pg_type %> + <%= col_idx%><% end %> from generate_series(1, <%= rows %>) n`,
|
||||||
[]any{pgx.QueryResultFormats{<%= format_code %>}},
|
pgx.QueryResultFormats{<%= format_code %>},
|
||||||
)
|
)
|
||||||
_, err := pgx.ForEachRow(rows, []any{<% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>&v[<%= col_idx%>]<% end %>}, func() error { return nil })
|
_, err := pgx.ForEachRow(rows, []any{<% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>&v[<%= col_idx%>]<% end %>}, func() error { return nil })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,7 +49,7 @@ func BenchmarkQuery<%= format_name %>FormatDecode_PG_Int4Array_With_Go_Int4Array
|
||||||
rows, _ := conn.Query(
|
rows, _ := conn.Query(
|
||||||
ctx,
|
ctx,
|
||||||
`select array_agg(n) from generate_series(1, <%= array_size %>) n`,
|
`select array_agg(n) from generate_series(1, <%= array_size %>) n`,
|
||||||
[]any{pgx.QueryResultFormats{<%= format_code %>}},
|
pgx.QueryResultFormats{<%= format_code %>},
|
||||||
)
|
)
|
||||||
_, err := pgx.ForEachRow(rows, []any{&v}, func() error { return nil })
|
_, err := pgx.ForEachRow(rows, []any{&v}, func() error { return nil })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
20
vendor/github.com/jackc/pgx/v5/pgtype/json.go
generated
vendored
20
vendor/github.com/jackc/pgx/v5/pgtype/json.go
generated
vendored
|
@ -130,7 +130,7 @@ func (c *JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanP
|
||||||
// https://github.com/jackc/pgx/issues/1691 -- ** anything else
|
// https://github.com/jackc/pgx/issues/1691 -- ** anything else
|
||||||
|
|
||||||
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
||||||
if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
|
if nextPlan := m.planScan(oid, format, nextDst, 0); nextPlan != nil {
|
||||||
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
||||||
wrapperPlan.SetNext(nextPlan)
|
wrapperPlan.SetNext(nextPlan)
|
||||||
return wrapperPlan
|
return wrapperPlan
|
||||||
|
@ -143,10 +143,12 @@ func (c *JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanP
|
||||||
case BytesScanner:
|
case BytesScanner:
|
||||||
return scanPlanBinaryBytesToBytesScanner{}
|
return scanPlanBinaryBytesToBytesScanner{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot rely on sql.Scanner being handled later because scanPlanJSONToJSONUnmarshal will take precedence.
|
// Cannot rely on sql.Scanner being handled later because scanPlanJSONToJSONUnmarshal will take precedence.
|
||||||
//
|
//
|
||||||
// https://github.com/jackc/pgx/issues/1418
|
// https://github.com/jackc/pgx/issues/1418
|
||||||
case sql.Scanner:
|
if isSQLScanner(target) {
|
||||||
return &scanPlanSQLScanner{formatCode: format}
|
return &scanPlanSQLScanner{formatCode: format}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +157,20 @@ func (c *JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to check if the target is a pointer to a sql.Scanner (or any of the pointer ref tree implements a sql.Scanner).
|
||||||
|
//
|
||||||
|
// https://github.com/jackc/pgx/issues/2146
|
||||||
|
func isSQLScanner(v any) bool {
|
||||||
|
val := reflect.ValueOf(v)
|
||||||
|
for val.Kind() == reflect.Ptr {
|
||||||
|
if _, ok := val.Interface().(sql.Scanner); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val = val.Elem()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type scanPlanAnyToString struct{}
|
type scanPlanAnyToString struct{}
|
||||||
|
|
||||||
func (scanPlanAnyToString) Scan(src []byte, dst any) error {
|
func (scanPlanAnyToString) Scan(src []byte, dst any) error {
|
||||||
|
|
57
vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go
generated
vendored
57
vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go
generated
vendored
|
@ -29,6 +29,7 @@
|
||||||
XMLOID = 142
|
XMLOID = 142
|
||||||
XMLArrayOID = 143
|
XMLArrayOID = 143
|
||||||
JSONArrayOID = 199
|
JSONArrayOID = 199
|
||||||
|
XID8ArrayOID = 271
|
||||||
PointOID = 600
|
PointOID = 600
|
||||||
LsegOID = 601
|
LsegOID = 601
|
||||||
PathOID = 602
|
PathOID = 602
|
||||||
|
@ -117,6 +118,7 @@
|
||||||
TstzmultirangeOID = 4534
|
TstzmultirangeOID = 4534
|
||||||
DatemultirangeOID = 4535
|
DatemultirangeOID = 4535
|
||||||
Int8multirangeOID = 4536
|
Int8multirangeOID = 4536
|
||||||
|
XID8OID = 5069
|
||||||
Int4multirangeArrayOID = 6150
|
Int4multirangeArrayOID = 6150
|
||||||
NummultirangeArrayOID = 6151
|
NummultirangeArrayOID = 6151
|
||||||
TsmultirangeArrayOID = 6152
|
TsmultirangeArrayOID = 6152
|
||||||
|
@ -394,7 +396,12 @@ type scanPlanSQLScanner struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (plan *scanPlanSQLScanner) Scan(src []byte, dst any) error {
|
func (plan *scanPlanSQLScanner) Scan(src []byte, dst any) error {
|
||||||
scanner := dst.(sql.Scanner)
|
scanner := getSQLScanner(dst)
|
||||||
|
|
||||||
|
if scanner == nil {
|
||||||
|
return fmt.Errorf("cannot scan into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
if src == nil {
|
if src == nil {
|
||||||
// This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the
|
// This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the
|
||||||
// text format path would be converted to empty string.
|
// text format path would be converted to empty string.
|
||||||
|
@ -406,6 +413,21 @@ func (plan *scanPlanSQLScanner) Scan(src []byte, dst any) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we don't know if the target is a sql.Scanner or a pointer on a sql.Scanner, so we need to check recursively
|
||||||
|
func getSQLScanner(target any) sql.Scanner {
|
||||||
|
val := reflect.ValueOf(target)
|
||||||
|
for val.Kind() == reflect.Ptr {
|
||||||
|
if _, ok := val.Interface().(sql.Scanner); ok {
|
||||||
|
if val.IsNil() {
|
||||||
|
val.Set(reflect.New(val.Type().Elem()))
|
||||||
|
}
|
||||||
|
return val.Interface().(sql.Scanner)
|
||||||
|
}
|
||||||
|
val = val.Elem()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type scanPlanString struct{}
|
type scanPlanString struct{}
|
||||||
|
|
||||||
func (scanPlanString) Scan(src []byte, dst any) error {
|
func (scanPlanString) Scan(src []byte, dst any) error {
|
||||||
|
@ -449,14 +471,14 @@ func (plan *scanPlanFail) Scan(src []byte, dst any) error {
|
||||||
// As a horrible hack try all types to find anything that can scan into dst.
|
// As a horrible hack try all types to find anything that can scan into dst.
|
||||||
for oid := range plan.m.oidToType {
|
for oid := range plan.m.oidToType {
|
||||||
// using planScan instead of Scan or PlanScan to avoid polluting the planned scan cache.
|
// using planScan instead of Scan or PlanScan to avoid polluting the planned scan cache.
|
||||||
plan := plan.m.planScan(oid, plan.formatCode, dst)
|
plan := plan.m.planScan(oid, plan.formatCode, dst, 0)
|
||||||
if _, ok := plan.(*scanPlanFail); !ok {
|
if _, ok := plan.(*scanPlanFail); !ok {
|
||||||
return plan.Scan(src, dst)
|
return plan.Scan(src, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for oid := range defaultMap.oidToType {
|
for oid := range defaultMap.oidToType {
|
||||||
if _, ok := plan.m.oidToType[oid]; !ok {
|
if _, ok := plan.m.oidToType[oid]; !ok {
|
||||||
plan := plan.m.planScan(oid, plan.formatCode, dst)
|
plan := plan.m.planScan(oid, plan.formatCode, dst, 0)
|
||||||
if _, ok := plan.(*scanPlanFail); !ok {
|
if _, ok := plan.(*scanPlanFail); !ok {
|
||||||
return plan.Scan(src, dst)
|
return plan.Scan(src, dst)
|
||||||
}
|
}
|
||||||
|
@ -1064,6 +1086,14 @@ func (plan *wrapPtrArrayReflectScanPlan) Scan(src []byte, target any) error {
|
||||||
|
|
||||||
// PlanScan prepares a plan to scan a value into target.
|
// PlanScan prepares a plan to scan a value into target.
|
||||||
func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan {
|
func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan {
|
||||||
|
return m.planScanDepth(oid, formatCode, target, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Map) planScanDepth(oid uint32, formatCode int16, target any, depth int) ScanPlan {
|
||||||
|
if depth > 8 {
|
||||||
|
return &scanPlanFail{m: m, oid: oid, formatCode: formatCode}
|
||||||
|
}
|
||||||
|
|
||||||
oidMemo := m.memoizedScanPlans[oid]
|
oidMemo := m.memoizedScanPlans[oid]
|
||||||
if oidMemo == nil {
|
if oidMemo == nil {
|
||||||
oidMemo = make(map[reflect.Type][2]ScanPlan)
|
oidMemo = make(map[reflect.Type][2]ScanPlan)
|
||||||
|
@ -1073,7 +1103,7 @@ func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan {
|
||||||
typeMemo := oidMemo[targetReflectType]
|
typeMemo := oidMemo[targetReflectType]
|
||||||
plan := typeMemo[formatCode]
|
plan := typeMemo[formatCode]
|
||||||
if plan == nil {
|
if plan == nil {
|
||||||
plan = m.planScan(oid, formatCode, target)
|
plan = m.planScan(oid, formatCode, target, depth)
|
||||||
typeMemo[formatCode] = plan
|
typeMemo[formatCode] = plan
|
||||||
oidMemo[targetReflectType] = typeMemo
|
oidMemo[targetReflectType] = typeMemo
|
||||||
}
|
}
|
||||||
|
@ -1081,7 +1111,7 @@ func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan {
|
||||||
return plan
|
return plan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan {
|
func (m *Map) planScan(oid uint32, formatCode int16, target any, depth int) ScanPlan {
|
||||||
if target == nil {
|
if target == nil {
|
||||||
return &scanPlanFail{m: m, oid: oid, formatCode: formatCode}
|
return &scanPlanFail{m: m, oid: oid, formatCode: formatCode}
|
||||||
}
|
}
|
||||||
|
@ -1141,7 +1171,7 @@ func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan {
|
||||||
|
|
||||||
for _, f := range m.TryWrapScanPlanFuncs {
|
for _, f := range m.TryWrapScanPlanFuncs {
|
||||||
if wrapperPlan, nextDst, ok := f(target); ok {
|
if wrapperPlan, nextDst, ok := f(target); ok {
|
||||||
if nextPlan := m.planScan(oid, formatCode, nextDst); nextPlan != nil {
|
if nextPlan := m.planScanDepth(oid, formatCode, nextDst, depth+1); nextPlan != nil {
|
||||||
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
||||||
wrapperPlan.SetNext(nextPlan)
|
wrapperPlan.SetNext(nextPlan)
|
||||||
return wrapperPlan
|
return wrapperPlan
|
||||||
|
@ -1201,6 +1231,15 @@ func codecDecodeToTextFormat(codec Codec, m *Map, oid uint32, format int16, src
|
||||||
// PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be
|
// PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be
|
||||||
// found then nil is returned.
|
// found then nil is returned.
|
||||||
func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan {
|
func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan {
|
||||||
|
return m.planEncodeDepth(oid, format, value, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Map) planEncodeDepth(oid uint32, format int16, value any, depth int) EncodePlan {
|
||||||
|
// Guard against infinite recursion.
|
||||||
|
if depth > 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
oidMemo := m.memoizedEncodePlans[oid]
|
oidMemo := m.memoizedEncodePlans[oid]
|
||||||
if oidMemo == nil {
|
if oidMemo == nil {
|
||||||
oidMemo = make(map[reflect.Type][2]EncodePlan)
|
oidMemo = make(map[reflect.Type][2]EncodePlan)
|
||||||
|
@ -1210,7 +1249,7 @@ func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan {
|
||||||
typeMemo := oidMemo[targetReflectType]
|
typeMemo := oidMemo[targetReflectType]
|
||||||
plan := typeMemo[format]
|
plan := typeMemo[format]
|
||||||
if plan == nil {
|
if plan == nil {
|
||||||
plan = m.planEncode(oid, format, value)
|
plan = m.planEncode(oid, format, value, depth)
|
||||||
typeMemo[format] = plan
|
typeMemo[format] = plan
|
||||||
oidMemo[targetReflectType] = typeMemo
|
oidMemo[targetReflectType] = typeMemo
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1257,7 @@ func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan {
|
||||||
return plan
|
return plan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) planEncode(oid uint32, format int16, value any) EncodePlan {
|
func (m *Map) planEncode(oid uint32, format int16, value any, depth int) EncodePlan {
|
||||||
if format == TextFormatCode {
|
if format == TextFormatCode {
|
||||||
switch value.(type) {
|
switch value.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
@ -1249,7 +1288,7 @@ func (m *Map) planEncode(oid uint32, format int16, value any) EncodePlan {
|
||||||
|
|
||||||
for _, f := range m.TryWrapEncodePlanFuncs {
|
for _, f := range m.TryWrapEncodePlanFuncs {
|
||||||
if wrapperPlan, nextValue, ok := f(value); ok {
|
if wrapperPlan, nextValue, ok := f(value); ok {
|
||||||
if nextPlan := m.PlanEncode(oid, format, nextValue); nextPlan != nil {
|
if nextPlan := m.planEncodeDepth(oid, format, nextValue, depth+1); nextPlan != nil {
|
||||||
wrapperPlan.SetNext(nextPlan)
|
wrapperPlan.SetNext(nextPlan)
|
||||||
return wrapperPlan
|
return wrapperPlan
|
||||||
}
|
}
|
||||||
|
|
2
vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go
generated
vendored
2
vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go
generated
vendored
|
@ -90,6 +90,7 @@ func initDefaultMap() {
|
||||||
defaultMap.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}})
|
defaultMap.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}})
|
||||||
defaultMap.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}})
|
defaultMap.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}})
|
||||||
defaultMap.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}})
|
defaultMap.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}})
|
||||||
|
defaultMap.RegisterType(&Type{Name: "xid8", OID: XID8OID, Codec: Uint64Codec{}})
|
||||||
defaultMap.RegisterType(&Type{Name: "xml", OID: XMLOID, Codec: &XMLCodec{Marshal: xml.Marshal, Unmarshal: xml.Unmarshal}})
|
defaultMap.RegisterType(&Type{Name: "xml", OID: XMLOID, Codec: &XMLCodec{Marshal: xml.Marshal, Unmarshal: xml.Unmarshal}})
|
||||||
|
|
||||||
// Range types
|
// Range types
|
||||||
|
@ -155,6 +156,7 @@ func initDefaultMap() {
|
||||||
defaultMap.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarbitOID]}})
|
defaultMap.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarbitOID]}})
|
||||||
defaultMap.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarcharOID]}})
|
defaultMap.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarcharOID]}})
|
||||||
defaultMap.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XIDOID]}})
|
defaultMap.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XIDOID]}})
|
||||||
|
defaultMap.RegisterType(&Type{Name: "_xid8", OID: XID8ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XID8OID]}})
|
||||||
defaultMap.RegisterType(&Type{Name: "_xml", OID: XMLArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XMLOID]}})
|
defaultMap.RegisterType(&Type{Name: "_xml", OID: XMLArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XMLOID]}})
|
||||||
|
|
||||||
// Integer types that directly map to a PostgreSQL type
|
// Integer types that directly map to a PostgreSQL type
|
||||||
|
|
5
vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go
generated
vendored
5
vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go
generated
vendored
|
@ -104,8 +104,8 @@ func (ts *Timestamp) UnmarshalJSON(b []byte) error {
|
||||||
case "-infinity":
|
case "-infinity":
|
||||||
*ts = Timestamp{Valid: true, InfinityModifier: -Infinity}
|
*ts = Timestamp{Valid: true, InfinityModifier: -Infinity}
|
||||||
default:
|
default:
|
||||||
// PostgreSQL uses ISO 8601 for to_json function and casting from a string to timestamptz
|
// PostgreSQL uses ISO 8601 wihout timezone for to_json function and casting from a string to timestampt
|
||||||
tim, err := time.Parse(time.RFC3339Nano, *s)
|
tim, err := time.Parse(time.RFC3339Nano, *s+"Z")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,6 @@ func discardTimeZone(t time.Time) time.Time {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TimestampCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
|
func (c *TimestampCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case BinaryFormatCode:
|
case BinaryFormatCode:
|
||||||
switch target.(type) {
|
switch target.(type) {
|
||||||
|
|
322
vendor/github.com/jackc/pgx/v5/pgtype/uint64.go
generated
vendored
Normal file
322
vendor/github.com/jackc/pgx/v5/pgtype/uint64.go
generated
vendored
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
package pgtype
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/internal/pgio"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Uint64Scanner interface {
|
||||||
|
ScanUint64(v Uint64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Uint64Valuer interface {
|
||||||
|
Uint64Value() (Uint64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 is the core type that is used to represent PostgreSQL types such as XID8.
|
||||||
|
type Uint64 struct {
|
||||||
|
Uint64 uint64
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Uint64) ScanUint64(v Uint64) error {
|
||||||
|
*n = v
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Uint64) Uint64Value() (Uint64, error) {
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements the database/sql Scanner interface.
|
||||||
|
func (dst *Uint64) Scan(src any) error {
|
||||||
|
if src == nil {
|
||||||
|
*dst = Uint64{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var n uint64
|
||||||
|
|
||||||
|
switch src := src.(type) {
|
||||||
|
case int64:
|
||||||
|
if src < 0 {
|
||||||
|
return fmt.Errorf("%d is less than the minimum value for Uint64", src)
|
||||||
|
}
|
||||||
|
n = uint64(src)
|
||||||
|
case string:
|
||||||
|
un, err := strconv.ParseUint(src, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
n = un
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("cannot scan %T", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = Uint64{Uint64: n, Valid: true}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the database/sql/driver Valuer interface.
|
||||||
|
func (src Uint64) Value() (driver.Value, error) {
|
||||||
|
if !src.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the value is greater than the maximum value for int64, return it as a string instead of losing data or returning
|
||||||
|
// an error.
|
||||||
|
if src.Uint64 > math.MaxInt64 {
|
||||||
|
return strconv.FormatUint(src.Uint64, 10), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return int64(src.Uint64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Uint64Codec struct{}
|
||||||
|
|
||||||
|
func (Uint64Codec) FormatSupported(format int16) bool {
|
||||||
|
return format == TextFormatCode || format == BinaryFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Uint64Codec) PreferredFormat() int16 {
|
||||||
|
return BinaryFormatCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Uint64Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
|
||||||
|
switch format {
|
||||||
|
case BinaryFormatCode:
|
||||||
|
switch value.(type) {
|
||||||
|
case uint64:
|
||||||
|
return encodePlanUint64CodecBinaryUint64{}
|
||||||
|
case Uint64Valuer:
|
||||||
|
return encodePlanUint64CodecBinaryUint64Valuer{}
|
||||||
|
case Int64Valuer:
|
||||||
|
return encodePlanUint64CodecBinaryInt64Valuer{}
|
||||||
|
}
|
||||||
|
case TextFormatCode:
|
||||||
|
switch value.(type) {
|
||||||
|
case uint64:
|
||||||
|
return encodePlanUint64CodecTextUint64{}
|
||||||
|
case Int64Valuer:
|
||||||
|
return encodePlanUint64CodecTextInt64Valuer{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecBinaryUint64 struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecBinaryUint64) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v := value.(uint64)
|
||||||
|
return pgio.AppendUint64(buf, v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecBinaryUint64Valuer struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecBinaryUint64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v, err := value.(Uint64Valuer).Uint64Value()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return pgio.AppendUint64(buf, v.Uint64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecBinaryInt64Valuer struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v, err := value.(Int64Valuer).Int64Value()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Int64 < 0 {
|
||||||
|
return nil, fmt.Errorf("%d is less than minimum value for uint64", v.Int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pgio.AppendUint64(buf, uint64(v.Int64)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecTextUint64 struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecTextUint64) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v := value.(uint64)
|
||||||
|
return append(buf, strconv.FormatUint(uint64(v), 10)...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecTextUint64Valuer struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecTextUint64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v, err := value.(Uint64Valuer).Uint64Value()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(buf, strconv.FormatUint(v.Uint64, 10)...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodePlanUint64CodecTextInt64Valuer struct{}
|
||||||
|
|
||||||
|
func (encodePlanUint64CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
|
||||||
|
v, err := value.(Int64Valuer).Int64Value()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Int64 < 0 {
|
||||||
|
return nil, fmt.Errorf("%d is less than minimum value for uint64", v.Int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(buf, strconv.FormatInt(v.Int64, 10)...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Uint64Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
|
||||||
|
|
||||||
|
switch format {
|
||||||
|
case BinaryFormatCode:
|
||||||
|
switch target.(type) {
|
||||||
|
case *uint64:
|
||||||
|
return scanPlanBinaryUint64ToUint64{}
|
||||||
|
case Uint64Scanner:
|
||||||
|
return scanPlanBinaryUint64ToUint64Scanner{}
|
||||||
|
case TextScanner:
|
||||||
|
return scanPlanBinaryUint64ToTextScanner{}
|
||||||
|
}
|
||||||
|
case TextFormatCode:
|
||||||
|
switch target.(type) {
|
||||||
|
case *uint64:
|
||||||
|
return scanPlanTextAnyToUint64{}
|
||||||
|
case Uint64Scanner:
|
||||||
|
return scanPlanTextAnyToUint64Scanner{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Uint64Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
|
||||||
|
if src == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var n uint64
|
||||||
|
err := codecScan(c, m, oid, format, src, &n)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return int64(n), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Uint64Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
|
||||||
|
if src == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var n uint64
|
||||||
|
err := codecScan(c, m, oid, format, src, &n)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryUint64ToUint64 struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryUint64ToUint64) Scan(src []byte, dst any) error {
|
||||||
|
if src == nil {
|
||||||
|
return fmt.Errorf("cannot scan NULL into %T", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 8 {
|
||||||
|
return fmt.Errorf("invalid length for uint64: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
p := (dst).(*uint64)
|
||||||
|
*p = binary.BigEndian.Uint64(src)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryUint64ToUint64Scanner struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryUint64ToUint64Scanner) Scan(src []byte, dst any) error {
|
||||||
|
s, ok := (dst).(Uint64Scanner)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
if src == nil {
|
||||||
|
return s.ScanUint64(Uint64{})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 8 {
|
||||||
|
return fmt.Errorf("invalid length for uint64: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
n := binary.BigEndian.Uint64(src)
|
||||||
|
|
||||||
|
return s.ScanUint64(Uint64{Uint64: n, Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanBinaryUint64ToTextScanner struct{}
|
||||||
|
|
||||||
|
func (scanPlanBinaryUint64ToTextScanner) Scan(src []byte, dst any) error {
|
||||||
|
s, ok := (dst).(TextScanner)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
if src == nil {
|
||||||
|
return s.ScanText(Text{})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(src) != 8 {
|
||||||
|
return fmt.Errorf("invalid length for uint64: %v", len(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
n := uint64(binary.BigEndian.Uint64(src))
|
||||||
|
return s.ScanText(Text{String: strconv.FormatUint(n, 10), Valid: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanPlanTextAnyToUint64Scanner struct{}
|
||||||
|
|
||||||
|
func (scanPlanTextAnyToUint64Scanner) Scan(src []byte, dst any) error {
|
||||||
|
s, ok := (dst).(Uint64Scanner)
|
||||||
|
if !ok {
|
||||||
|
return ErrScanTargetTypeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
if src == nil {
|
||||||
|
return s.ScanUint64(Uint64{})
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := strconv.ParseUint(string(src), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.ScanUint64(Uint64{Uint64: n, Valid: true})
|
||||||
|
}
|
8
vendor/github.com/jackc/pgx/v5/pgtype/uuid.go
generated
vendored
8
vendor/github.com/jackc/pgx/v5/pgtype/uuid.go
generated
vendored
|
@ -96,6 +96,14 @@ func (src UUID) Value() (driver.Value, error) {
|
||||||
return encodeUUID(src.Bytes), nil
|
return encodeUUID(src.Bytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (src UUID) String() string {
|
||||||
|
if !src.Valid {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodeUUID(src.Bytes)
|
||||||
|
}
|
||||||
|
|
||||||
func (src UUID) MarshalJSON() ([]byte, error) {
|
func (src UUID) MarshalJSON() ([]byte, error) {
|
||||||
if !src.Valid {
|
if !src.Valid {
|
||||||
return []byte("null"), nil
|
return []byte("null"), nil
|
||||||
|
|
2
vendor/github.com/jackc/pgx/v5/pgtype/xml.go
generated
vendored
2
vendor/github.com/jackc/pgx/v5/pgtype/xml.go
generated
vendored
|
@ -113,7 +113,7 @@ func (c *XMLCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPl
|
||||||
// https://github.com/jackc/pgx/issues/1691 -- ** anything else
|
// https://github.com/jackc/pgx/issues/1691 -- ** anything else
|
||||||
|
|
||||||
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
||||||
if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
|
if nextPlan := m.planScan(oid, format, nextDst, 0); nextPlan != nil {
|
||||||
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
||||||
wrapperPlan.SetNext(nextPlan)
|
wrapperPlan.SetNext(nextPlan)
|
||||||
return wrapperPlan
|
return wrapperPlan
|
||||||
|
|
16
vendor/github.com/jackc/pgx/v5/pgxpool/pool.go
generated
vendored
16
vendor/github.com/jackc/pgx/v5/pgxpool/pool.go
generated
vendored
|
@ -281,20 +281,20 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
|
||||||
// ParseConfig builds a Config from connString. It parses connString with the same behavior as [pgx.ParseConfig] with the
|
// ParseConfig builds a Config from connString. It parses connString with the same behavior as [pgx.ParseConfig] with the
|
||||||
// addition of the following variables:
|
// addition of the following variables:
|
||||||
//
|
//
|
||||||
// - pool_max_conns: integer greater than 0
|
// - pool_max_conns: integer greater than 0 (default 4)
|
||||||
// - pool_min_conns: integer 0 or greater
|
// - pool_min_conns: integer 0 or greater (default 0)
|
||||||
// - pool_max_conn_lifetime: duration string
|
// - pool_max_conn_lifetime: duration string (default 1 hour)
|
||||||
// - pool_max_conn_idle_time: duration string
|
// - pool_max_conn_idle_time: duration string (default 30 minutes)
|
||||||
// - pool_health_check_period: duration string
|
// - pool_health_check_period: duration string (default 1 minute)
|
||||||
// - pool_max_conn_lifetime_jitter: duration string
|
// - pool_max_conn_lifetime_jitter: duration string (default 0)
|
||||||
//
|
//
|
||||||
// See Config for definitions of these arguments.
|
// See Config for definitions of these arguments.
|
||||||
//
|
//
|
||||||
// # Example Keyword/Value
|
// # Example Keyword/Value
|
||||||
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca pool_max_conns=10
|
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca pool_max_conns=10 pool_max_conn_lifetime=1h30m
|
||||||
//
|
//
|
||||||
// # Example URL
|
// # Example URL
|
||||||
// postgres://jack:secret@pg.example.com:5432/mydb?sslmode=verify-ca&pool_max_conns=10
|
// postgres://jack:secret@pg.example.com:5432/mydb?sslmode=verify-ca&pool_max_conns=10&pool_max_conn_lifetime=1h30m
|
||||||
func ParseConfig(connString string) (*Config, error) {
|
func ParseConfig(connString string) (*Config, error) {
|
||||||
connConfig, err := pgx.ParseConfig(connString)
|
connConfig, err := pgx.ParseConfig(connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
15
vendor/github.com/jackc/pgx/v5/tx.go
generated
vendored
15
vendor/github.com/jackc/pgx/v5/tx.go
generated
vendored
|
@ -48,6 +48,8 @@ type TxOptions struct {
|
||||||
// BeginQuery is the SQL query that will be executed to begin the transaction. This allows using non-standard syntax
|
// BeginQuery is the SQL query that will be executed to begin the transaction. This allows using non-standard syntax
|
||||||
// such as BEGIN PRIORITY HIGH with CockroachDB. If set this will override the other settings.
|
// such as BEGIN PRIORITY HIGH with CockroachDB. If set this will override the other settings.
|
||||||
BeginQuery string
|
BeginQuery string
|
||||||
|
// CommitQuery is the SQL query that will be executed to commit the transaction.
|
||||||
|
CommitQuery string
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyTxOptions TxOptions
|
var emptyTxOptions TxOptions
|
||||||
|
@ -105,7 +107,10 @@ func (c *Conn) BeginTx(ctx context.Context, txOptions TxOptions) (Tx, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dbTx{conn: c}, nil
|
return &dbTx{
|
||||||
|
conn: c,
|
||||||
|
commitQuery: txOptions.CommitQuery,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx represents a database transaction.
|
// Tx represents a database transaction.
|
||||||
|
@ -154,6 +159,7 @@ type dbTx struct {
|
||||||
conn *Conn
|
conn *Conn
|
||||||
savepointNum int64
|
savepointNum int64
|
||||||
closed bool
|
closed bool
|
||||||
|
commitQuery string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin starts a pseudo nested transaction implemented with a savepoint.
|
// Begin starts a pseudo nested transaction implemented with a savepoint.
|
||||||
|
@ -177,7 +183,12 @@ func (tx *dbTx) Commit(ctx context.Context) error {
|
||||||
return ErrTxClosed
|
return ErrTxClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
commandTag, err := tx.conn.Exec(ctx, "commit")
|
commandSQL := "commit"
|
||||||
|
if tx.commitQuery != "" {
|
||||||
|
commandSQL = tx.commitQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
commandTag, err := tx.conn.Exec(ctx, commandSQL)
|
||||||
tx.closed = true
|
tx.closed = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tx.conn.PgConn().TxStatus() != 'I' {
|
if tx.conn.PgConn().TxStatus() != 'I' {
|
||||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -416,7 +416,7 @@ github.com/jackc/pgpassfile
|
||||||
# github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761
|
# github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/jackc/pgservicefile
|
github.com/jackc/pgservicefile
|
||||||
# github.com/jackc/pgx/v5 v5.7.1
|
# github.com/jackc/pgx/v5 v5.7.2
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/jackc/pgx/v5
|
github.com/jackc/pgx/v5
|
||||||
github.com/jackc/pgx/v5/internal/iobufpool
|
github.com/jackc/pgx/v5/internal/iobufpool
|
||||||
|
|
Loading…
Reference in a new issue