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/gorilla/feeds v1.2.0
|
||||
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/microcosm-cc/bluemonday v1.0.27
|
||||
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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
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.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
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/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
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)
|
||||
|
||||
* 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
|
||||
|
||||
See CONTRIBUTING.md for setup instructions.
|
||||
See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
@ -126,7 +126,7 @@ pgerrcode contains constants for the PostgreSQL error codes.
|
|||
|
||||
## 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
|
||||
|
||||
|
@ -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,
|
||||
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.
|
||||
|
||||
|
@ -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.
|
||||
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).
|
||||
|
|
73
vendor/github.com/jackc/pgx/v5/conn.go
generated
vendored
73
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
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
|
||||
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments.
|
||||
// Queries are executed in a single round trip. Type mappings can be 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 the PostgreSQL type can use
|
||||
// a map[string]string directly as an argument. This mode cannot.
|
||||
// Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments. Queries
|
||||
// are executed in a single round trip. Type mappings can be 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 the PostgreSQL type can use a map[string]string directly as an
|
||||
// argument. This mode cannot.
|
||||
//
|
||||
// QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec with minor
|
||||
// exceptions such as behavior when multiple result returning queries are erroneously sent in a single string.
|
||||
// QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec. This includes
|
||||
// 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
|
||||
// QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol
|
||||
// should only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does
|
||||
// not support the extended protocol.
|
||||
// QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol should
|
||||
// only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does not
|
||||
// support the extended protocol.
|
||||
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
|
||||
// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection
|
||||
// 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) {
|
||||
if c.batchTracer != nil {
|
||||
ctx = c.batchTracer.TraceBatchStart(ctx, c, TraceBatchStartData{Batch: b})
|
||||
|
@ -1126,24 +1140,42 @@ func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b *Batch, d
|
|||
|
||||
// Prepare any needed queries
|
||||
if len(distinctNewQueries) > 0 {
|
||||
err := func() (err error) {
|
||||
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
|
||||
// clean them up later.
|
||||
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 &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
||||
return err
|
||||
}
|
||||
|
||||
for _, sd := range distinctNewQueries {
|
||||
results, err := pipeline.GetResults()
|
||||
if err != nil {
|
||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
||||
return err
|
||||
}
|
||||
|
||||
resultSD, ok := results.(*pgconn.StatementDescription)
|
||||
if !ok {
|
||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected statement description, got %T", results), closed: true}
|
||||
return fmt.Errorf("expected statement description, got %T", results)
|
||||
}
|
||||
|
||||
// Fill in the previously empty / pending statement descriptions.
|
||||
|
@ -1153,19 +1185,18 @@ func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b *Batch, d
|
|||
|
||||
results, err := pipeline.GetResults()
|
||||
if err != nil {
|
||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
||||
return err
|
||||
}
|
||||
|
||||
_, ok := results.(*pgconn.PipelineSync)
|
||||
if !ok {
|
||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected sync, got %T", results), closed: true}
|
||||
}
|
||||
return fmt.Errorf("expected sync, got %T", results)
|
||||
}
|
||||
|
||||
// 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)
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
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
|
||||
// target_session_attrs=read-write.
|
||||
func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgConn *PgConn) error {
|
||||
result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read()
|
||||
if result.Err != nil {
|
||||
return result.Err
|
||||
result, err := pgConn.Exec(ctx, "show transaction_read_only").ReadAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if string(result.Rows[0][0]) == "on" {
|
||||
if string(result[0].Rows[0][0]) == "on" {
|
||||
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
|
||||
// target_session_attrs=read-only.
|
||||
func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgConn) error {
|
||||
result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read()
|
||||
if result.Err != nil {
|
||||
return result.Err
|
||||
result, err := pgConn.Exec(ctx, "show transaction_read_only").ReadAll()
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -891,12 +891,12 @@ func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgCo
|
|||
// ValidateConnectTargetSessionAttrsStandby is a ValidateConnectFunc that implements libpq compatible
|
||||
// target_session_attrs=standby.
|
||||
func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgConn) error {
|
||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
||||
if result.Err != nil {
|
||||
return result.Err
|
||||
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -906,12 +906,12 @@ func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgCon
|
|||
// ValidateConnectTargetSessionAttrsPrimary is a ValidateConnectFunc that implements libpq compatible
|
||||
// target_session_attrs=primary.
|
||||
func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgConn) error {
|
||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
||||
if result.Err != nil {
|
||||
return result.Err
|
||||
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -921,12 +921,12 @@ func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgCon
|
|||
// ValidateConnectTargetSessionAttrsPreferStandby is a ValidateConnectFunc that implements libpq compatible
|
||||
// target_session_attrs=prefer-standby.
|
||||
func ValidateConnectTargetSessionAttrsPreferStandby(ctx context.Context, pgConn *PgConn) error {
|
||||
result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read()
|
||||
if result.Err != nil {
|
||||
return result.Err
|
||||
result, err := pgConn.Exec(ctx, "select pg_is_in_recovery()").ReadAll()
|
||||
if err != nil {
|
||||
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")}
|
||||
}
|
||||
|
||||
|
|
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.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 {
|
||||
return nil, &ExceededMaxBodyLenErr{b.maxBodyLen, b.bodyLen}
|
||||
}
|
||||
|
@ -282,9 +288,10 @@ func (b *Backend) SetAuthType(authType uint32) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// 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 malicious clients that send large messages with the intent of
|
||||
// causing memory exhaustion.
|
||||
// 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 malicious clients that send
|
||||
// large messages with the intent of causing memory exhaustion.
|
||||
// The default value is 0.
|
||||
// If maxBodyLen is 0, then no maximum is enforced.
|
||||
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
|
||||
|
||||
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
|
||||
partialMsg bool
|
||||
authType uint32
|
||||
|
@ -317,6 +318,9 @@ func (f *Frontend) Receive() (BackendMessage, error) {
|
|||
}
|
||||
|
||||
f.bodyLen = msgLength - 4
|
||||
if f.maxBodyLen > 0 && f.bodyLen > f.maxBodyLen {
|
||||
return nil, &ExceededMaxBodyLenErr{f.maxBodyLen, f.bodyLen}
|
||||
}
|
||||
f.partialMsg = true
|
||||
}
|
||||
|
||||
|
@ -452,3 +456,13 @@ func (f *Frontend) GetAuthType() uint32 {
|
|||
func (f *Frontend) ReadBufferLen() int {
|
||||
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(
|
||||
ctx,
|
||||
`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 })
|
||||
if err != nil {
|
||||
|
@ -49,7 +49,7 @@ func BenchmarkQuery<%= format_name %>FormatDecode_PG_Int4Array_With_Go_Int4Array
|
|||
rows, _ := conn.Query(
|
||||
ctx,
|
||||
`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 })
|
||||
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
|
||||
|
||||
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 {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
return wrapperPlan
|
||||
|
@ -143,10 +143,12 @@ func (c *JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanP
|
|||
case BytesScanner:
|
||||
return scanPlanBinaryBytesToBytesScanner{}
|
||||
|
||||
}
|
||||
|
||||
// Cannot rely on sql.Scanner being handled later because scanPlanJSONToJSONUnmarshal will take precedence.
|
||||
//
|
||||
// https://github.com/jackc/pgx/issues/1418
|
||||
case sql.Scanner:
|
||||
if isSQLScanner(target) {
|
||||
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{}
|
||||
|
||||
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
|
||||
XMLArrayOID = 143
|
||||
JSONArrayOID = 199
|
||||
XID8ArrayOID = 271
|
||||
PointOID = 600
|
||||
LsegOID = 601
|
||||
PathOID = 602
|
||||
|
@ -117,6 +118,7 @@
|
|||
TstzmultirangeOID = 4534
|
||||
DatemultirangeOID = 4535
|
||||
Int8multirangeOID = 4536
|
||||
XID8OID = 5069
|
||||
Int4multirangeArrayOID = 6150
|
||||
NummultirangeArrayOID = 6151
|
||||
TsmultirangeArrayOID = 6152
|
||||
|
@ -394,7 +396,12 @@ type scanPlanSQLScanner struct {
|
|||
}
|
||||
|
||||
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 {
|
||||
// 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.
|
||||
|
@ -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{}
|
||||
|
||||
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.
|
||||
for oid := range plan.m.oidToType {
|
||||
// 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 {
|
||||
return plan.Scan(src, dst)
|
||||
}
|
||||
}
|
||||
for oid := range defaultMap.oidToType {
|
||||
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 {
|
||||
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.
|
||||
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]
|
||||
if oidMemo == nil {
|
||||
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]
|
||||
plan := typeMemo[formatCode]
|
||||
if plan == nil {
|
||||
plan = m.planScan(oid, formatCode, target)
|
||||
plan = m.planScan(oid, formatCode, target, depth)
|
||||
typeMemo[formatCode] = plan
|
||||
oidMemo[targetReflectType] = typeMemo
|
||||
}
|
||||
|
@ -1081,7 +1111,7 @@ func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan {
|
|||
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 {
|
||||
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 {
|
||||
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 {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
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
|
||||
// found then nil is returned.
|
||||
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]
|
||||
if oidMemo == nil {
|
||||
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]
|
||||
plan := typeMemo[format]
|
||||
if plan == nil {
|
||||
plan = m.planEncode(oid, format, value)
|
||||
plan = m.planEncode(oid, format, value, depth)
|
||||
typeMemo[format] = plan
|
||||
oidMemo[targetReflectType] = typeMemo
|
||||
}
|
||||
|
@ -1218,7 +1257,7 @@ func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan {
|
|||
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 {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
|
@ -1249,7 +1288,7 @@ func (m *Map) planEncode(oid uint32, format int16, value any) EncodePlan {
|
|||
|
||||
for _, f := range m.TryWrapEncodePlanFuncs {
|
||||
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)
|
||||
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: "varchar", OID: VarcharOID, Codec: TextCodec{}})
|
||||
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}})
|
||||
|
||||
// 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: "_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: "_xid8", OID: XID8ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XID8OID]}})
|
||||
defaultMap.RegisterType(&Type{Name: "_xml", OID: XMLArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XMLOID]}})
|
||||
|
||||
// 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":
|
||||
*ts = Timestamp{Valid: true, InfinityModifier: -Infinity}
|
||||
default:
|
||||
// PostgreSQL uses ISO 8601 for to_json function and casting from a string to timestamptz
|
||||
tim, err := time.Parse(time.RFC3339Nano, *s)
|
||||
// PostgreSQL uses ISO 8601 wihout timezone for to_json function and casting from a string to timestampt
|
||||
tim, err := time.Parse(time.RFC3339Nano, *s+"Z")
|
||||
if err != nil {
|
||||
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 {
|
||||
|
||||
switch format {
|
||||
case BinaryFormatCode:
|
||||
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
|
||||
}
|
||||
|
||||
func (src UUID) String() string {
|
||||
if !src.Valid {
|
||||
return ""
|
||||
}
|
||||
|
||||
return encodeUUID(src.Bytes)
|
||||
}
|
||||
|
||||
func (src UUID) MarshalJSON() ([]byte, error) {
|
||||
if !src.Valid {
|
||||
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
|
||||
|
||||
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 {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
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
|
||||
// addition of the following variables:
|
||||
//
|
||||
// - pool_max_conns: integer greater than 0
|
||||
// - pool_min_conns: integer 0 or greater
|
||||
// - pool_max_conn_lifetime: duration string
|
||||
// - pool_max_conn_idle_time: duration string
|
||||
// - pool_health_check_period: duration string
|
||||
// - pool_max_conn_lifetime_jitter: duration string
|
||||
// - pool_max_conns: integer greater than 0 (default 4)
|
||||
// - pool_min_conns: integer 0 or greater (default 0)
|
||||
// - pool_max_conn_lifetime: duration string (default 1 hour)
|
||||
// - pool_max_conn_idle_time: duration string (default 30 minutes)
|
||||
// - pool_health_check_period: duration string (default 1 minute)
|
||||
// - pool_max_conn_lifetime_jitter: duration string (default 0)
|
||||
//
|
||||
// See Config for definitions of these arguments.
|
||||
//
|
||||
// # 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
|
||||
// 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) {
|
||||
connConfig, err := pgx.ParseConfig(connString)
|
||||
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
|
||||
// such as BEGIN PRIORITY HIGH with CockroachDB. If set this will override the other settings.
|
||||
BeginQuery string
|
||||
// CommitQuery is the SQL query that will be executed to commit the transaction.
|
||||
CommitQuery string
|
||||
}
|
||||
|
||||
var emptyTxOptions TxOptions
|
||||
|
@ -105,7 +107,10 @@ func (c *Conn) BeginTx(ctx context.Context, txOptions TxOptions) (Tx, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return &dbTx{conn: c}, nil
|
||||
return &dbTx{
|
||||
conn: c,
|
||||
commitQuery: txOptions.CommitQuery,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Tx represents a database transaction.
|
||||
|
@ -154,6 +159,7 @@ type dbTx struct {
|
|||
conn *Conn
|
||||
savepointNum int64
|
||||
closed bool
|
||||
commitQuery string
|
||||
}
|
||||
|
||||
// Begin starts a pseudo nested transaction implemented with a savepoint.
|
||||
|
@ -177,7 +183,12 @@ func (tx *dbTx) Commit(ctx context.Context) error {
|
|||
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
|
||||
if err != nil {
|
||||
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
|
||||
## explicit; go 1.14
|
||||
github.com/jackc/pgservicefile
|
||||
# github.com/jackc/pgx/v5 v5.7.1
|
||||
# github.com/jackc/pgx/v5 v5.7.2
|
||||
## explicit; go 1.21
|
||||
github.com/jackc/pgx/v5
|
||||
github.com/jackc/pgx/v5/internal/iobufpool
|
||||
|
|
Loading…
Reference in a new issue