aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/jackc/pgx/v5/pgproto3
diff options
context:
space:
mode:
authoruzhas <uzhas@ydb.tech>2023-11-16 16:04:50 +0300
committeruzhas <uzhas@ydb.tech>2023-11-16 17:46:46 +0300
commit46f0c0079bb50609d2eeb6586642bcf114fc5239 (patch)
tree84e4e4978d57fe5de321ba69bf9d0c290de60a66 /vendor/github.com/jackc/pgx/v5/pgproto3
parent73045e389397816cc2bdd6cd7818b4bce427b265 (diff)
downloadydb-46f0c0079bb50609d2eeb6586642bcf114fc5239.tar.gz
enable ya make for go projects
Diffstat (limited to 'vendor/github.com/jackc/pgx/v5/pgproto3')
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go52
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go59
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go68
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go77
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go52
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go76
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go81
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go81
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/backend.go262
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go51
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go37
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/bind.go216
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go58
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go90
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader_test.go75
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/close.go89
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go74
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go95
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response_test.go18
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go62
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go38
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go53
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go96
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go96
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go142
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/describe.go88
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/doc.go11
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go333
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/README.md53
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/main.go51
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/server.go104
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/ya.make10
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/example/ya.make1
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/execute.go65
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/flush.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go363
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go95
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go101
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/function_call_test.go62
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/fuzz_test.go57
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/gotest/ya.make9
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go49
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go49
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/json_test.go611
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go17
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go77
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go66
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go66
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/parse.go88
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go54
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go85
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/query.go50
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go61
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go165
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go94
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go61
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go49
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go96
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/sync.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go34
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa64
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f74
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c42144
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb44
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/trace.go440
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgproto3/ya.make83
72 files changed, 6084 insertions, 0 deletions
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go
new file mode 100644
index 0000000000..d8f98b9af0
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go
@@ -0,0 +1,52 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationCleartextPassword is a message sent from the backend indicating that a clear-text password is required.
+type AuthenticationCleartextPassword struct {
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationCleartextPassword) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationCleartextPassword) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationCleartextPassword) Decode(src []byte) error {
+ if len(src) != 4 {
+ return errors.New("bad authentication message size")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeCleartextPassword {
+ return errors.New("bad auth type")
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationCleartextPassword) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ dst = pgio.AppendInt32(dst, 8)
+ dst = pgio.AppendUint32(dst, AuthTypeCleartextPassword)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src AuthenticationCleartextPassword) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "AuthenticationCleartextPassword",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go
new file mode 100644
index 0000000000..0d234222fc
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go
@@ -0,0 +1,59 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type AuthenticationGSS struct{}
+
+func (a *AuthenticationGSS) Backend() {}
+
+func (a *AuthenticationGSS) AuthenticationResponse() {}
+
+func (a *AuthenticationGSS) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("authentication message too short")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeGSS {
+ return errors.New("bad auth type")
+ }
+ return nil
+}
+
+func (a *AuthenticationGSS) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ dst = pgio.AppendInt32(dst, 4)
+ dst = pgio.AppendUint32(dst, AuthTypeGSS)
+ return dst
+}
+
+func (a *AuthenticationGSS) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data []byte
+ }{
+ Type: "AuthenticationGSS",
+ })
+}
+
+func (a *AuthenticationGSS) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Type string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go
new file mode 100644
index 0000000000..63789dc1a5
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go
@@ -0,0 +1,68 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type AuthenticationGSSContinue struct {
+ Data []byte
+}
+
+func (a *AuthenticationGSSContinue) Backend() {}
+
+func (a *AuthenticationGSSContinue) AuthenticationResponse() {}
+
+func (a *AuthenticationGSSContinue) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("authentication message too short")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeGSSCont {
+ return errors.New("bad auth type")
+ }
+
+ a.Data = src[4:]
+ return nil
+}
+
+func (a *AuthenticationGSSContinue) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ dst = pgio.AppendInt32(dst, int32(len(a.Data))+8)
+ dst = pgio.AppendUint32(dst, AuthTypeGSSCont)
+ dst = append(dst, a.Data...)
+ return dst
+}
+
+func (a *AuthenticationGSSContinue) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data []byte
+ }{
+ Type: "AuthenticationGSSContinue",
+ Data: a.Data,
+ })
+}
+
+func (a *AuthenticationGSSContinue) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Type string
+ Data []byte
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ a.Data = msg.Data
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go
new file mode 100644
index 0000000000..5671c84c55
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go
@@ -0,0 +1,77 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationMD5Password is a message sent from the backend indicating that an MD5 hashed password is required.
+type AuthenticationMD5Password struct {
+ Salt [4]byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationMD5Password) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationMD5Password) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationMD5Password) Decode(src []byte) error {
+ if len(src) != 8 {
+ return errors.New("bad authentication message size")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeMD5Password {
+ return errors.New("bad auth type")
+ }
+
+ copy(dst.Salt[:], src[4:8])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationMD5Password) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ dst = pgio.AppendInt32(dst, 12)
+ dst = pgio.AppendUint32(dst, AuthTypeMD5Password)
+ dst = append(dst, src.Salt[:]...)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src AuthenticationMD5Password) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Salt [4]byte
+ }{
+ Type: "AuthenticationMD5Password",
+ Salt: src.Salt,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *AuthenticationMD5Password) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Type string
+ Salt [4]byte
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Salt = msg.Salt
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go
new file mode 100644
index 0000000000..88d648ae70
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go
@@ -0,0 +1,52 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationOk is a message sent from the backend indicating that authentication was successful.
+type AuthenticationOk struct {
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationOk) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationOk) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationOk) Decode(src []byte) error {
+ if len(src) != 4 {
+ return errors.New("bad authentication message size")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeOk {
+ return errors.New("bad auth type")
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationOk) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ dst = pgio.AppendInt32(dst, 8)
+ dst = pgio.AppendUint32(dst, AuthTypeOk)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src AuthenticationOk) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "AuthenticationOK",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go
new file mode 100644
index 0000000000..59650d4cd0
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go
@@ -0,0 +1,76 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationSASL is a message sent from the backend indicating that SASL authentication is required.
+type AuthenticationSASL struct {
+ AuthMechanisms []string
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationSASL) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationSASL) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationSASL) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("authentication message too short")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeSASL {
+ return errors.New("bad auth type")
+ }
+
+ authMechanisms := src[4:]
+ for len(authMechanisms) > 1 {
+ idx := bytes.IndexByte(authMechanisms, 0)
+ if idx == -1 {
+ return &invalidMessageFormatErr{messageType: "AuthenticationSASL", details: "unterminated string"}
+ }
+ dst.AuthMechanisms = append(dst.AuthMechanisms, string(authMechanisms[:idx]))
+ authMechanisms = authMechanisms[idx+1:]
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationSASL) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+ dst = pgio.AppendUint32(dst, AuthTypeSASL)
+
+ for _, s := range src.AuthMechanisms {
+ dst = append(dst, []byte(s)...)
+ dst = append(dst, 0)
+ }
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src AuthenticationSASL) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ AuthMechanisms []string
+ }{
+ Type: "AuthenticationSASL",
+ AuthMechanisms: src.AuthMechanisms,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go
new file mode 100644
index 0000000000..2ce70a4778
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go
@@ -0,0 +1,81 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationSASLContinue is a message sent from the backend containing a SASL challenge.
+type AuthenticationSASLContinue struct {
+ Data []byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationSASLContinue) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationSASLContinue) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationSASLContinue) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("authentication message too short")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeSASLContinue {
+ return errors.New("bad auth type")
+ }
+
+ dst.Data = src[4:]
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationSASLContinue) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+ dst = pgio.AppendUint32(dst, AuthTypeSASLContinue)
+
+ dst = append(dst, src.Data...)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src AuthenticationSASLContinue) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data string
+ }{
+ Type: "AuthenticationSASLContinue",
+ Data: string(src.Data),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *AuthenticationSASLContinue) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Data string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Data = []byte(msg.Data)
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go
new file mode 100644
index 0000000000..a38a8b9129
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go
@@ -0,0 +1,81 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+// AuthenticationSASLFinal is a message sent from the backend indicating a SASL authentication has completed.
+type AuthenticationSASLFinal struct {
+ Data []byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*AuthenticationSASLFinal) Backend() {}
+
+// Backend identifies this message as an authentication response.
+func (*AuthenticationSASLFinal) AuthenticationResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *AuthenticationSASLFinal) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("authentication message too short")
+ }
+
+ authType := binary.BigEndian.Uint32(src)
+
+ if authType != AuthTypeSASLFinal {
+ return errors.New("bad auth type")
+ }
+
+ dst.Data = src[4:]
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *AuthenticationSASLFinal) Encode(dst []byte) []byte {
+ dst = append(dst, 'R')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+ dst = pgio.AppendUint32(dst, AuthTypeSASLFinal)
+
+ dst = append(dst, src.Data...)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Unmarshaler.
+func (src AuthenticationSASLFinal) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data string
+ }{
+ Type: "AuthenticationSASLFinal",
+ Data: string(src.Data),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *AuthenticationSASLFinal) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Data string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Data = []byte(msg.Data)
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go b/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go
new file mode 100644
index 0000000000..6db77e4a2f
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go
@@ -0,0 +1,262 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "io"
+)
+
+// Backend acts as a server for the PostgreSQL wire protocol version 3.
+type Backend struct {
+ cr *chunkReader
+ w io.Writer
+
+ // tracer is used to trace messages when Send or Receive is called. This means an outbound message is traced
+ // before it is actually transmitted (i.e. before Flush).
+ tracer *tracer
+
+ wbuf []byte
+
+ // Frontend message flyweights
+ bind Bind
+ cancelRequest CancelRequest
+ _close Close
+ copyFail CopyFail
+ copyData CopyData
+ copyDone CopyDone
+ describe Describe
+ execute Execute
+ flush Flush
+ functionCall FunctionCall
+ gssEncRequest GSSEncRequest
+ parse Parse
+ query Query
+ sslRequest SSLRequest
+ startupMessage StartupMessage
+ sync Sync
+ terminate Terminate
+
+ bodyLen int
+ msgType byte
+ partialMsg bool
+ authType uint32
+}
+
+const (
+ minStartupPacketLen = 4 // minStartupPacketLen is a single 32-bit int version or code.
+ maxStartupPacketLen = 10000 // maxStartupPacketLen is MAX_STARTUP_PACKET_LENGTH from PG source.
+)
+
+// NewBackend creates a new Backend.
+func NewBackend(r io.Reader, w io.Writer) *Backend {
+ cr := newChunkReader(r, 0)
+ return &Backend{cr: cr, w: w}
+}
+
+// Send sends a message to the frontend (i.e. the client). The message is not guaranteed to be written until Flush is
+// called.
+func (b *Backend) Send(msg BackendMessage) {
+ prevLen := len(b.wbuf)
+ b.wbuf = msg.Encode(b.wbuf)
+ if b.tracer != nil {
+ b.tracer.traceMessage('B', int32(len(b.wbuf)-prevLen), msg)
+ }
+}
+
+// Flush writes any pending messages to the frontend (i.e. the client).
+func (b *Backend) Flush() error {
+ n, err := b.w.Write(b.wbuf)
+
+ const maxLen = 1024
+ if len(b.wbuf) > maxLen {
+ b.wbuf = make([]byte, 0, maxLen)
+ } else {
+ b.wbuf = b.wbuf[:0]
+ }
+
+ if err != nil {
+ return &writeError{err: err, safeToRetry: n == 0}
+ }
+
+ return nil
+}
+
+// Trace starts tracing the message traffic to w. It writes in a similar format to that produced by the libpq function
+// PQtrace.
+func (b *Backend) Trace(w io.Writer, options TracerOptions) {
+ b.tracer = &tracer{
+ w: w,
+ buf: &bytes.Buffer{},
+ TracerOptions: options,
+ }
+}
+
+// Untrace stops tracing.
+func (b *Backend) Untrace() {
+ b.tracer = nil
+}
+
+// ReceiveStartupMessage receives the initial connection message. This method is used of the normal Receive method
+// because the initial connection message is "special" and does not include the message type as the first byte. This
+// will return either a StartupMessage, SSLRequest, GSSEncRequest, or CancelRequest.
+func (b *Backend) ReceiveStartupMessage() (FrontendMessage, error) {
+ buf, err := b.cr.Next(4)
+ if err != nil {
+ return nil, err
+ }
+ msgSize := int(binary.BigEndian.Uint32(buf) - 4)
+
+ if msgSize < minStartupPacketLen || msgSize > maxStartupPacketLen {
+ return nil, fmt.Errorf("invalid length of startup packet: %d", msgSize)
+ }
+
+ buf, err = b.cr.Next(msgSize)
+ if err != nil {
+ return nil, translateEOFtoErrUnexpectedEOF(err)
+ }
+
+ code := binary.BigEndian.Uint32(buf)
+
+ switch code {
+ case ProtocolVersionNumber:
+ err = b.startupMessage.Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ return &b.startupMessage, nil
+ case sslRequestNumber:
+ err = b.sslRequest.Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ return &b.sslRequest, nil
+ case cancelRequestCode:
+ err = b.cancelRequest.Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ return &b.cancelRequest, nil
+ case gssEncReqNumber:
+ err = b.gssEncRequest.Decode(buf)
+ if err != nil {
+ return nil, err
+ }
+ return &b.gssEncRequest, nil
+ default:
+ return nil, fmt.Errorf("unknown startup message code: %d", code)
+ }
+}
+
+// Receive receives a message from the frontend. The returned message is only valid until the next call to Receive.
+func (b *Backend) Receive() (FrontendMessage, error) {
+ if !b.partialMsg {
+ header, err := b.cr.Next(5)
+ if err != nil {
+ return nil, translateEOFtoErrUnexpectedEOF(err)
+ }
+
+ b.msgType = header[0]
+ b.bodyLen = int(binary.BigEndian.Uint32(header[1:])) - 4
+ b.partialMsg = true
+ }
+
+ var msg FrontendMessage
+ switch b.msgType {
+ case 'B':
+ msg = &b.bind
+ case 'C':
+ msg = &b._close
+ case 'D':
+ msg = &b.describe
+ case 'E':
+ msg = &b.execute
+ case 'F':
+ msg = &b.functionCall
+ case 'f':
+ msg = &b.copyFail
+ case 'd':
+ msg = &b.copyData
+ case 'c':
+ msg = &b.copyDone
+ case 'H':
+ msg = &b.flush
+ case 'P':
+ msg = &b.parse
+ case 'p':
+ switch b.authType {
+ case AuthTypeSASL:
+ msg = &SASLInitialResponse{}
+ case AuthTypeSASLContinue:
+ msg = &SASLResponse{}
+ case AuthTypeSASLFinal:
+ msg = &SASLResponse{}
+ case AuthTypeGSS, AuthTypeGSSCont:
+ msg = &GSSResponse{}
+ case AuthTypeCleartextPassword, AuthTypeMD5Password:
+ fallthrough
+ default:
+ // to maintain backwards compatibility
+ msg = &PasswordMessage{}
+ }
+ case 'Q':
+ msg = &b.query
+ case 'S':
+ msg = &b.sync
+ case 'X':
+ msg = &b.terminate
+ default:
+ return nil, fmt.Errorf("unknown message type: %c", b.msgType)
+ }
+
+ msgBody, err := b.cr.Next(b.bodyLen)
+ if err != nil {
+ return nil, translateEOFtoErrUnexpectedEOF(err)
+ }
+
+ b.partialMsg = false
+
+ err = msg.Decode(msgBody)
+ if err != nil {
+ return nil, err
+ }
+
+ if b.tracer != nil {
+ b.tracer.traceMessage('F', int32(5+len(msgBody)), msg)
+ }
+
+ return msg, nil
+}
+
+// SetAuthType sets the authentication type in the backend.
+// Since multiple message types can start with 'p', SetAuthType allows
+// contextual identification of FrontendMessages. For example, in the
+// PG message flow documentation for PasswordMessage:
+//
+// Byte1('p')
+//
+// Identifies the message as a password response. Note that this is also used for
+// GSSAPI, SSPI and SASL response messages. The exact message type can be deduced from
+// the context.
+//
+// Since the Frontend does not know about the state of a backend, it is important
+// to call SetAuthType() after an authentication request is received by the Frontend.
+func (b *Backend) SetAuthType(authType uint32) error {
+ switch authType {
+ case AuthTypeOk,
+ AuthTypeCleartextPassword,
+ AuthTypeMD5Password,
+ AuthTypeSCMCreds,
+ AuthTypeGSS,
+ AuthTypeGSSCont,
+ AuthTypeSSPI,
+ AuthTypeSASL,
+ AuthTypeSASLContinue,
+ AuthTypeSASLFinal:
+ b.authType = authType
+ default:
+ return fmt.Errorf("authType not recognized: %d", authType)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go
new file mode 100644
index 0000000000..12c6081703
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go
@@ -0,0 +1,51 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type BackendKeyData struct {
+ ProcessID uint32
+ SecretKey uint32
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*BackendKeyData) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *BackendKeyData) Decode(src []byte) error {
+ if len(src) != 8 {
+ return &invalidMessageLenErr{messageType: "BackendKeyData", expectedLen: 8, actualLen: len(src)}
+ }
+
+ dst.ProcessID = binary.BigEndian.Uint32(src[:4])
+ dst.SecretKey = binary.BigEndian.Uint32(src[4:])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *BackendKeyData) Encode(dst []byte) []byte {
+ dst = append(dst, 'K')
+ dst = pgio.AppendUint32(dst, 12)
+ dst = pgio.AppendUint32(dst, src.ProcessID)
+ dst = pgio.AppendUint32(dst, src.SecretKey)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src BackendKeyData) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ProcessID uint32
+ SecretKey uint32
+ }{
+ Type: "BackendKeyData",
+ ProcessID: src.ProcessID,
+ SecretKey: src.SecretKey,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go b/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go
new file mode 100644
index 0000000000..f7bdb97eb7
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go
@@ -0,0 +1,37 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+)
+
+type BigEndianBuf [8]byte
+
+func (b BigEndianBuf) Int16(n int16) []byte {
+ buf := b[0:2]
+ binary.BigEndian.PutUint16(buf, uint16(n))
+ return buf
+}
+
+func (b BigEndianBuf) Uint16(n uint16) []byte {
+ buf := b[0:2]
+ binary.BigEndian.PutUint16(buf, n)
+ return buf
+}
+
+func (b BigEndianBuf) Int32(n int32) []byte {
+ buf := b[0:4]
+ binary.BigEndian.PutUint32(buf, uint32(n))
+ return buf
+}
+
+func (b BigEndianBuf) Uint32(n uint32) []byte {
+ buf := b[0:4]
+ binary.BigEndian.PutUint32(buf, n)
+ return buf
+}
+
+func (b BigEndianBuf) Int64(n int64) []byte {
+ buf := b[0:8]
+ binary.BigEndian.PutUint64(buf, uint64(n))
+ return buf
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go b/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go
new file mode 100644
index 0000000000..fdd2d3b812
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go
@@ -0,0 +1,216 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Bind struct {
+ DestinationPortal string
+ PreparedStatement string
+ ParameterFormatCodes []int16
+ Parameters [][]byte
+ ResultFormatCodes []int16
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Bind) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Bind) Decode(src []byte) error {
+ *dst = Bind{}
+
+ idx := bytes.IndexByte(src, 0)
+ if idx < 0 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ dst.DestinationPortal = string(src[:idx])
+ rp := idx + 1
+
+ idx = bytes.IndexByte(src[rp:], 0)
+ if idx < 0 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ dst.PreparedStatement = string(src[rp : rp+idx])
+ rp += idx + 1
+
+ if len(src[rp:]) < 2 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ parameterFormatCodeCount := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+
+ if parameterFormatCodeCount > 0 {
+ dst.ParameterFormatCodes = make([]int16, parameterFormatCodeCount)
+
+ if len(src[rp:]) < len(dst.ParameterFormatCodes)*2 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ for i := 0; i < parameterFormatCodeCount; i++ {
+ dst.ParameterFormatCodes[i] = int16(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+ }
+ }
+
+ if len(src[rp:]) < 2 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ parameterCount := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+
+ if parameterCount > 0 {
+ dst.Parameters = make([][]byte, parameterCount)
+
+ for i := 0; i < parameterCount; i++ {
+ if len(src[rp:]) < 4 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+
+ msgSize := int(int32(binary.BigEndian.Uint32(src[rp:])))
+ rp += 4
+
+ // null
+ if msgSize == -1 {
+ continue
+ }
+
+ if len(src[rp:]) < msgSize {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+
+ dst.Parameters[i] = src[rp : rp+msgSize]
+ rp += msgSize
+ }
+ }
+
+ if len(src[rp:]) < 2 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ resultFormatCodeCount := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+
+ dst.ResultFormatCodes = make([]int16, resultFormatCodeCount)
+ if len(src[rp:]) < len(dst.ResultFormatCodes)*2 {
+ return &invalidMessageFormatErr{messageType: "Bind"}
+ }
+ for i := 0; i < resultFormatCodeCount; i++ {
+ dst.ResultFormatCodes[i] = int16(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Bind) Encode(dst []byte) []byte {
+ dst = append(dst, 'B')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.DestinationPortal...)
+ dst = append(dst, 0)
+ dst = append(dst, src.PreparedStatement...)
+ dst = append(dst, 0)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.ParameterFormatCodes)))
+ for _, fc := range src.ParameterFormatCodes {
+ dst = pgio.AppendInt16(dst, fc)
+ }
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.Parameters)))
+ for _, p := range src.Parameters {
+ if p == nil {
+ dst = pgio.AppendInt32(dst, -1)
+ continue
+ }
+
+ dst = pgio.AppendInt32(dst, int32(len(p)))
+ dst = append(dst, p...)
+ }
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.ResultFormatCodes)))
+ for _, fc := range src.ResultFormatCodes {
+ dst = pgio.AppendInt16(dst, fc)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Bind) MarshalJSON() ([]byte, error) {
+ formattedParameters := make([]map[string]string, len(src.Parameters))
+ for i, p := range src.Parameters {
+ if p == nil {
+ continue
+ }
+
+ textFormat := true
+ if len(src.ParameterFormatCodes) == 1 {
+ textFormat = src.ParameterFormatCodes[0] == 0
+ } else if len(src.ParameterFormatCodes) > 1 {
+ textFormat = src.ParameterFormatCodes[i] == 0
+ }
+
+ if textFormat {
+ formattedParameters[i] = map[string]string{"text": string(p)}
+ } else {
+ formattedParameters[i] = map[string]string{"binary": hex.EncodeToString(p)}
+ }
+ }
+
+ return json.Marshal(struct {
+ Type string
+ DestinationPortal string
+ PreparedStatement string
+ ParameterFormatCodes []int16
+ Parameters []map[string]string
+ ResultFormatCodes []int16
+ }{
+ Type: "Bind",
+ DestinationPortal: src.DestinationPortal,
+ PreparedStatement: src.PreparedStatement,
+ ParameterFormatCodes: src.ParameterFormatCodes,
+ Parameters: formattedParameters,
+ ResultFormatCodes: src.ResultFormatCodes,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *Bind) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ DestinationPortal string
+ PreparedStatement string
+ ParameterFormatCodes []int16
+ Parameters []map[string]string
+ ResultFormatCodes []int16
+ }
+ err := json.Unmarshal(data, &msg)
+ if err != nil {
+ return err
+ }
+ dst.DestinationPortal = msg.DestinationPortal
+ dst.PreparedStatement = msg.PreparedStatement
+ dst.ParameterFormatCodes = msg.ParameterFormatCodes
+ dst.Parameters = make([][]byte, len(msg.Parameters))
+ dst.ResultFormatCodes = msg.ResultFormatCodes
+ for n, parameter := range msg.Parameters {
+ dst.Parameters[n], err = getValueFromJSON(parameter)
+ if err != nil {
+ return fmt.Errorf("cannot get param %d: %w", n, err)
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go
new file mode 100644
index 0000000000..3be256c897
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type BindComplete struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*BindComplete) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *BindComplete) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "BindComplete", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *BindComplete) Encode(dst []byte) []byte {
+ return append(dst, '2', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src BindComplete) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "BindComplete",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go
new file mode 100644
index 0000000000..8fcf8217ac
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go
@@ -0,0 +1,58 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+const cancelRequestCode = 80877102
+
+type CancelRequest struct {
+ ProcessID uint32
+ SecretKey uint32
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*CancelRequest) Frontend() {}
+
+func (dst *CancelRequest) Decode(src []byte) error {
+ if len(src) != 12 {
+ return errors.New("bad cancel request size")
+ }
+
+ requestCode := binary.BigEndian.Uint32(src)
+
+ if requestCode != cancelRequestCode {
+ return errors.New("bad cancel request code")
+ }
+
+ dst.ProcessID = binary.BigEndian.Uint32(src[4:])
+ dst.SecretKey = binary.BigEndian.Uint32(src[8:])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 4 byte message length.
+func (src *CancelRequest) Encode(dst []byte) []byte {
+ dst = pgio.AppendInt32(dst, 16)
+ dst = pgio.AppendInt32(dst, cancelRequestCode)
+ dst = pgio.AppendUint32(dst, src.ProcessID)
+ dst = pgio.AppendUint32(dst, src.SecretKey)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CancelRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ProcessID uint32
+ SecretKey uint32
+ }{
+ Type: "CancelRequest",
+ ProcessID: src.ProcessID,
+ SecretKey: src.SecretKey,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go
new file mode 100644
index 0000000000..fc0fa61e9c
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go
@@ -0,0 +1,90 @@
+package pgproto3
+
+import (
+ "io"
+
+ "github.com/jackc/pgx/v5/internal/iobufpool"
+)
+
+// chunkReader is a io.Reader wrapper that minimizes IO reads and memory allocations. It allocates memory in chunks and
+// will read as much as will fit in the current buffer in a single call regardless of how large a read is actually
+// requested. The memory returned via Next is only valid until the next call to Next.
+//
+// This is roughly equivalent to a bufio.Reader that only uses Peek and Discard to never copy bytes.
+type chunkReader struct {
+ r io.Reader
+
+ buf *[]byte
+ rp, wp int // buf read position and write position
+
+ minBufSize int
+}
+
+// newChunkReader creates and returns a new chunkReader for r with default configuration. If minBufSize is <= 0 it uses
+// a default value.
+func newChunkReader(r io.Reader, minBufSize int) *chunkReader {
+ if minBufSize <= 0 {
+ // By historical reasons Postgres currently has 8KB send buffer inside,
+ // so here we want to have at least the same size buffer.
+ // @see https://github.com/postgres/postgres/blob/249d64999615802752940e017ee5166e726bc7cd/src/backend/libpq/pqcomm.c#L134
+ // @see https://www.postgresql.org/message-id/0cdc5485-cb3c-5e16-4a46-e3b2f7a41322%40ya.ru
+ //
+ // In addition, testing has found no benefit of any larger buffer.
+ minBufSize = 8192
+ }
+
+ return &chunkReader{
+ r: r,
+ minBufSize: minBufSize,
+ buf: iobufpool.Get(minBufSize),
+ }
+}
+
+// Next returns buf filled with the next n bytes. buf is only valid until next call of Next. If an error occurs, buf
+// will be nil.
+func (r *chunkReader) Next(n int) (buf []byte, err error) {
+ // Reset the buffer if it is empty
+ if r.rp == r.wp {
+ if len(*r.buf) != r.minBufSize {
+ iobufpool.Put(r.buf)
+ r.buf = iobufpool.Get(r.minBufSize)
+ }
+ r.rp = 0
+ r.wp = 0
+ }
+
+ // n bytes already in buf
+ if (r.wp - r.rp) >= n {
+ buf = (*r.buf)[r.rp : r.rp+n : r.rp+n]
+ r.rp += n
+ return buf, err
+ }
+
+ // buf is smaller than requested number of bytes
+ if len(*r.buf) < n {
+ bigBuf := iobufpool.Get(n)
+ r.wp = copy((*bigBuf), (*r.buf)[r.rp:r.wp])
+ r.rp = 0
+ iobufpool.Put(r.buf)
+ r.buf = bigBuf
+ }
+
+ // buf is large enough, but need to shift filled area to start to make enough contiguous space
+ minReadCount := n - (r.wp - r.rp)
+ if (len(*r.buf) - r.wp) < minReadCount {
+ r.wp = copy((*r.buf), (*r.buf)[r.rp:r.wp])
+ r.rp = 0
+ }
+
+ // Read at least the required number of bytes from the underlying io.Reader
+ readBytesCount, err := io.ReadAtLeast(r.r, (*r.buf)[r.wp:], minReadCount)
+ r.wp += readBytesCount
+ // fmt.Println("read", n)
+ if err != nil {
+ return nil, err
+ }
+
+ buf = (*r.buf)[r.rp : r.rp+n : r.rp+n]
+ r.rp += n
+ return buf, nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader_test.go b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader_test.go
new file mode 100644
index 0000000000..e1c2b0da7c
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader_test.go
@@ -0,0 +1,75 @@
+package pgproto3
+
+import (
+ "bytes"
+ "math/rand"
+ "testing"
+)
+
+func TestChunkReaderNextDoesNotReadIfAlreadyBuffered(t *testing.T) {
+ server := &bytes.Buffer{}
+ r := newChunkReader(server, 4)
+
+ src := []byte{1, 2, 3, 4}
+ server.Write(src)
+
+ n1, err := r.Next(2)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if bytes.Compare(n1, src[0:2]) != 0 {
+ t.Fatalf("Expected read bytes to be %v, but they were %v", src[0:2], n1)
+ }
+
+ n2, err := r.Next(2)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if bytes.Compare(n2, src[2:4]) != 0 {
+ t.Fatalf("Expected read bytes to be %v, but they were %v", src[2:4], n2)
+ }
+
+ if bytes.Compare((*r.buf)[:len(src)], src) != 0 {
+ t.Fatalf("Expected r.buf to be %v, but it was %v", src, r.buf)
+ }
+
+ _, err = r.Next(0) // Trigger the buffer reset.
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if r.rp != 0 {
+ t.Fatalf("Expected r.rp to be %v, but it was %v", 0, r.rp)
+ }
+ if r.wp != 0 {
+ t.Fatalf("Expected r.wp to be %v, but it was %v", 0, r.wp)
+ }
+}
+
+type randomReader struct {
+ rnd *rand.Rand
+}
+
+// Read reads a random number of random bytes.
+func (r *randomReader) Read(p []byte) (n int, err error) {
+ n = r.rnd.Intn(len(p) + 1)
+ return r.rnd.Read(p[:n])
+}
+
+func TestChunkReaderNextFuzz(t *testing.T) {
+ rr := &randomReader{rnd: rand.New(rand.NewSource(1))}
+ r := newChunkReader(rr, 8192)
+
+ randomSizes := rand.New(rand.NewSource(0))
+
+ for i := 0; i < 100000; i++ {
+ size := randomSizes.Intn(16384) + 1
+ buf, err := r.Next(size)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(buf) != size {
+ t.Fatalf("Expected to get %v bytes but got %v bytes", size, len(buf))
+ }
+ }
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/close.go b/vendor/github.com/jackc/pgx/v5/pgproto3/close.go
new file mode 100644
index 0000000000..f99b594398
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/close.go
@@ -0,0 +1,89 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Close struct {
+ ObjectType byte // 'S' = prepared statement, 'P' = portal
+ Name string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Close) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Close) Decode(src []byte) error {
+ if len(src) < 2 {
+ return &invalidMessageFormatErr{messageType: "Close"}
+ }
+
+ dst.ObjectType = src[0]
+ rp := 1
+
+ idx := bytes.IndexByte(src[rp:], 0)
+ if idx != len(src[rp:])-1 {
+ return &invalidMessageFormatErr{messageType: "Close"}
+ }
+
+ dst.Name = string(src[rp : len(src)-1])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Close) Encode(dst []byte) []byte {
+ dst = append(dst, 'C')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.ObjectType)
+ dst = append(dst, src.Name...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Close) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ObjectType string
+ Name string
+ }{
+ Type: "Close",
+ ObjectType: string(src.ObjectType),
+ Name: src.Name,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *Close) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ ObjectType string
+ Name string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ if len(msg.ObjectType) != 1 {
+ return errors.New("invalid length for Close.ObjectType")
+ }
+
+ dst.ObjectType = byte(msg.ObjectType[0])
+ dst.Name = msg.Name
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go
new file mode 100644
index 0000000000..1d7b8f085a
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type CloseComplete struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CloseComplete) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CloseComplete) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "CloseComplete", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CloseComplete) Encode(dst []byte) []byte {
+ return append(dst, '3', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CloseComplete) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "CloseComplete",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go
new file mode 100644
index 0000000000..814027ca1a
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go
@@ -0,0 +1,74 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CommandComplete struct {
+ CommandTag []byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CommandComplete) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CommandComplete) Decode(src []byte) error {
+ idx := bytes.IndexByte(src, 0)
+ if idx == -1 {
+ return &invalidMessageFormatErr{messageType: "CommandComplete", details: "unterminated string"}
+ }
+ if idx != len(src)-1 {
+ return &invalidMessageFormatErr{messageType: "CommandComplete", details: "string terminated too early"}
+ }
+
+ dst.CommandTag = src[:idx]
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CommandComplete) Encode(dst []byte) []byte {
+ dst = append(dst, 'C')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.CommandTag...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CommandComplete) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ CommandTag string
+ }{
+ Type: "CommandComplete",
+ CommandTag: string(src.CommandTag),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *CommandComplete) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ CommandTag string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.CommandTag = []byte(msg.CommandTag)
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go
new file mode 100644
index 0000000000..8840a89ec0
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go
@@ -0,0 +1,95 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CopyBothResponse struct {
+ OverallFormat byte
+ ColumnFormatCodes []uint16
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CopyBothResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyBothResponse) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ if buf.Len() < 3 {
+ return &invalidMessageFormatErr{messageType: "CopyBothResponse"}
+ }
+
+ overallFormat := buf.Next(1)[0]
+
+ columnCount := int(binary.BigEndian.Uint16(buf.Next(2)))
+ if buf.Len() != columnCount*2 {
+ return &invalidMessageFormatErr{messageType: "CopyBothResponse"}
+ }
+
+ columnFormatCodes := make([]uint16, columnCount)
+ for i := 0; i < columnCount; i++ {
+ columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2))
+ }
+
+ *dst = CopyBothResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes}
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyBothResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'W')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+ dst = append(dst, src.OverallFormat)
+ dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
+ for _, fc := range src.ColumnFormatCodes {
+ dst = pgio.AppendUint16(dst, fc)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyBothResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ColumnFormatCodes []uint16
+ }{
+ Type: "CopyBothResponse",
+ ColumnFormatCodes: src.ColumnFormatCodes,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *CopyBothResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ OverallFormat string
+ ColumnFormatCodes []uint16
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ if len(msg.OverallFormat) != 1 {
+ return errors.New("invalid length for CopyBothResponse.OverallFormat")
+ }
+
+ dst.OverallFormat = msg.OverallFormat[0]
+ dst.ColumnFormatCodes = msg.ColumnFormatCodes
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response_test.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response_test.go
new file mode 100644
index 0000000000..4437de1daf
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response_test.go
@@ -0,0 +1,18 @@
+package pgproto3_test
+
+import (
+ "testing"
+
+ "github.com/jackc/pgx/v5/pgproto3"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEncodeDecode(t *testing.T) {
+ srcBytes := []byte{'W', 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}
+ dstResp := pgproto3.CopyBothResponse{}
+ err := dstResp.Decode(srcBytes[5:])
+ assert.NoError(t, err, "No errors on decode")
+ dstBytes := []byte{}
+ dstBytes = dstResp.Encode(dstBytes)
+ assert.EqualValues(t, srcBytes, dstBytes, "Expecting src & dest bytes to match")
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go
new file mode 100644
index 0000000000..59e3dd9429
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go
@@ -0,0 +1,62 @@
+package pgproto3
+
+import (
+ "encoding/hex"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CopyData struct {
+ Data []byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CopyData) Backend() {}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*CopyData) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyData) Decode(src []byte) error {
+ dst.Data = src
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyData) Encode(dst []byte) []byte {
+ dst = append(dst, 'd')
+ dst = pgio.AppendInt32(dst, int32(4+len(src.Data)))
+ dst = append(dst, src.Data...)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyData) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data string
+ }{
+ Type: "CopyData",
+ Data: hex.EncodeToString(src.Data),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *CopyData) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Data string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Data = []byte(msg.Data)
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go
new file mode 100644
index 0000000000..0e13282bff
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go
@@ -0,0 +1,38 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type CopyDone struct {
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CopyDone) Backend() {}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*CopyDone) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyDone) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "CopyDone", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyDone) Encode(dst []byte) []byte {
+ return append(dst, 'c', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyDone) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "CopyDone",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go
new file mode 100644
index 0000000000..0041bbb1d3
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go
@@ -0,0 +1,53 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CopyFail struct {
+ Message string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*CopyFail) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyFail) Decode(src []byte) error {
+ idx := bytes.IndexByte(src, 0)
+ if idx != len(src)-1 {
+ return &invalidMessageFormatErr{messageType: "CopyFail"}
+ }
+
+ dst.Message = string(src[:idx])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyFail) Encode(dst []byte) []byte {
+ dst = append(dst, 'f')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.Message...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyFail) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Message string
+ }{
+ Type: "CopyFail",
+ Message: src.Message,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go
new file mode 100644
index 0000000000..4584f7df2d
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go
@@ -0,0 +1,96 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CopyInResponse struct {
+ OverallFormat byte
+ ColumnFormatCodes []uint16
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*CopyInResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyInResponse) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ if buf.Len() < 3 {
+ return &invalidMessageFormatErr{messageType: "CopyInResponse"}
+ }
+
+ overallFormat := buf.Next(1)[0]
+
+ columnCount := int(binary.BigEndian.Uint16(buf.Next(2)))
+ if buf.Len() != columnCount*2 {
+ return &invalidMessageFormatErr{messageType: "CopyInResponse"}
+ }
+
+ columnFormatCodes := make([]uint16, columnCount)
+ for i := 0; i < columnCount; i++ {
+ columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2))
+ }
+
+ *dst = CopyInResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes}
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyInResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'G')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.OverallFormat)
+ dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
+ for _, fc := range src.ColumnFormatCodes {
+ dst = pgio.AppendUint16(dst, fc)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyInResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ColumnFormatCodes []uint16
+ }{
+ Type: "CopyInResponse",
+ ColumnFormatCodes: src.ColumnFormatCodes,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *CopyInResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ OverallFormat string
+ ColumnFormatCodes []uint16
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ if len(msg.OverallFormat) != 1 {
+ return errors.New("invalid length for CopyInResponse.OverallFormat")
+ }
+
+ dst.OverallFormat = msg.OverallFormat[0]
+ dst.ColumnFormatCodes = msg.ColumnFormatCodes
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go
new file mode 100644
index 0000000000..3175c6a40c
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go
@@ -0,0 +1,96 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type CopyOutResponse struct {
+ OverallFormat byte
+ ColumnFormatCodes []uint16
+}
+
+func (*CopyOutResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *CopyOutResponse) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ if buf.Len() < 3 {
+ return &invalidMessageFormatErr{messageType: "CopyOutResponse"}
+ }
+
+ overallFormat := buf.Next(1)[0]
+
+ columnCount := int(binary.BigEndian.Uint16(buf.Next(2)))
+ if buf.Len() != columnCount*2 {
+ return &invalidMessageFormatErr{messageType: "CopyOutResponse"}
+ }
+
+ columnFormatCodes := make([]uint16, columnCount)
+ for i := 0; i < columnCount; i++ {
+ columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2))
+ }
+
+ *dst = CopyOutResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes}
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *CopyOutResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'H')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.OverallFormat)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
+ for _, fc := range src.ColumnFormatCodes {
+ dst = pgio.AppendUint16(dst, fc)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src CopyOutResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ColumnFormatCodes []uint16
+ }{
+ Type: "CopyOutResponse",
+ ColumnFormatCodes: src.ColumnFormatCodes,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *CopyOutResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ OverallFormat string
+ ColumnFormatCodes []uint16
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ if len(msg.OverallFormat) != 1 {
+ return errors.New("invalid length for CopyOutResponse.OverallFormat")
+ }
+
+ dst.OverallFormat = msg.OverallFormat[0]
+ dst.ColumnFormatCodes = msg.ColumnFormatCodes
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go b/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go
new file mode 100644
index 0000000000..4de7797721
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go
@@ -0,0 +1,142 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type DataRow struct {
+ Values [][]byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*DataRow) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *DataRow) Decode(src []byte) error {
+ if len(src) < 2 {
+ return &invalidMessageFormatErr{messageType: "DataRow"}
+ }
+ rp := 0
+ fieldCount := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+
+ // If the capacity of the values slice is too small OR substantially too
+ // large reallocate. This is too avoid one row with many columns from
+ // permanently allocating memory.
+ if cap(dst.Values) < fieldCount || cap(dst.Values)-fieldCount > 32 {
+ newCap := 32
+ if newCap < fieldCount {
+ newCap = fieldCount
+ }
+ dst.Values = make([][]byte, fieldCount, newCap)
+ } else {
+ dst.Values = dst.Values[:fieldCount]
+ }
+
+ for i := 0; i < fieldCount; i++ {
+ if len(src[rp:]) < 4 {
+ return &invalidMessageFormatErr{messageType: "DataRow"}
+ }
+
+ valueLen := int(int32(binary.BigEndian.Uint32(src[rp:])))
+ rp += 4
+
+ // null
+ if valueLen == -1 {
+ dst.Values[i] = nil
+ } else {
+ if len(src[rp:]) < valueLen || valueLen < 0 {
+ return &invalidMessageFormatErr{messageType: "DataRow"}
+ }
+
+ dst.Values[i] = src[rp : rp+valueLen : rp+valueLen]
+ rp += valueLen
+ }
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *DataRow) Encode(dst []byte) []byte {
+ dst = append(dst, 'D')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.Values)))
+ for _, v := range src.Values {
+ if v == nil {
+ dst = pgio.AppendInt32(dst, -1)
+ continue
+ }
+
+ dst = pgio.AppendInt32(dst, int32(len(v)))
+ dst = append(dst, v...)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src DataRow) MarshalJSON() ([]byte, error) {
+ formattedValues := make([]map[string]string, len(src.Values))
+ for i, v := range src.Values {
+ if v == nil {
+ continue
+ }
+
+ var hasNonPrintable bool
+ for _, b := range v {
+ if b < 32 {
+ hasNonPrintable = true
+ break
+ }
+ }
+
+ if hasNonPrintable {
+ formattedValues[i] = map[string]string{"binary": hex.EncodeToString(v)}
+ } else {
+ formattedValues[i] = map[string]string{"text": string(v)}
+ }
+ }
+
+ return json.Marshal(struct {
+ Type string
+ Values []map[string]string
+ }{
+ Type: "DataRow",
+ Values: formattedValues,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *DataRow) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Values []map[string]string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Values = make([][]byte, len(msg.Values))
+ for n, parameter := range msg.Values {
+ var err error
+ dst.Values[n], err = getValueFromJSON(parameter)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go b/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go
new file mode 100644
index 0000000000..f131d1f482
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go
@@ -0,0 +1,88 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Describe struct {
+ ObjectType byte // 'S' = prepared statement, 'P' = portal
+ Name string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Describe) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Describe) Decode(src []byte) error {
+ if len(src) < 2 {
+ return &invalidMessageFormatErr{messageType: "Describe"}
+ }
+
+ dst.ObjectType = src[0]
+ rp := 1
+
+ idx := bytes.IndexByte(src[rp:], 0)
+ if idx != len(src[rp:])-1 {
+ return &invalidMessageFormatErr{messageType: "Describe"}
+ }
+
+ dst.Name = string(src[rp : len(src)-1])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Describe) Encode(dst []byte) []byte {
+ dst = append(dst, 'D')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.ObjectType)
+ dst = append(dst, src.Name...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Describe) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ObjectType string
+ Name string
+ }{
+ Type: "Describe",
+ ObjectType: string(src.ObjectType),
+ Name: src.Name,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *Describe) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ ObjectType string
+ Name string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ if len(msg.ObjectType) != 1 {
+ return errors.New("invalid length for Describe.ObjectType")
+ }
+
+ dst.ObjectType = byte(msg.ObjectType[0])
+ dst.Name = msg.Name
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go b/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go
new file mode 100644
index 0000000000..e0e1cf8721
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go
@@ -0,0 +1,11 @@
+// Package pgproto3 is a encoder and decoder of the PostgreSQL wire protocol version 3.
+//
+// The primary interfaces are Frontend and Backend. They correspond to a client and server respectively. Messages are
+// sent with Send (or a specialized Send variant). Messages are automatically bufferred to minimize small writes. Call
+// Flush to ensure a message has actually been sent.
+//
+// The Trace method of Frontend and Backend can be used to examine the wire-level message traffic. It outputs in a
+// similar format to the PQtrace function in libpq.
+//
+// See https://www.postgresql.org/docs/current/protocol-message-formats.html for meanings of the different messages.
+package pgproto3
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go
new file mode 100644
index 0000000000..2b85e744bc
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type EmptyQueryResponse struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*EmptyQueryResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *EmptyQueryResponse) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "EmptyQueryResponse", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *EmptyQueryResponse) Encode(dst []byte) []byte {
+ return append(dst, 'I', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src EmptyQueryResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "EmptyQueryResponse",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go
new file mode 100644
index 0000000000..45c9a9810f
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go
@@ -0,0 +1,333 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "strconv"
+)
+
+type ErrorResponse struct {
+ Severity string
+ SeverityUnlocalized string // only in 9.6 and greater
+ Code string
+ Message string
+ Detail string
+ Hint string
+ Position int32
+ InternalPosition int32
+ InternalQuery string
+ Where string
+ SchemaName string
+ TableName string
+ ColumnName string
+ DataTypeName string
+ ConstraintName string
+ File string
+ Line int32
+ Routine string
+
+ UnknownFields map[byte]string
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*ErrorResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *ErrorResponse) Decode(src []byte) error {
+ *dst = ErrorResponse{}
+
+ buf := bytes.NewBuffer(src)
+
+ for {
+ k, err := buf.ReadByte()
+ if err != nil {
+ return err
+ }
+ if k == 0 {
+ break
+ }
+
+ vb, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ v := string(vb[:len(vb)-1])
+
+ switch k {
+ case 'S':
+ dst.Severity = v
+ case 'V':
+ dst.SeverityUnlocalized = v
+ case 'C':
+ dst.Code = v
+ case 'M':
+ dst.Message = v
+ case 'D':
+ dst.Detail = v
+ case 'H':
+ dst.Hint = v
+ case 'P':
+ s := v
+ n, _ := strconv.ParseInt(s, 10, 32)
+ dst.Position = int32(n)
+ case 'p':
+ s := v
+ n, _ := strconv.ParseInt(s, 10, 32)
+ dst.InternalPosition = int32(n)
+ case 'q':
+ dst.InternalQuery = v
+ case 'W':
+ dst.Where = v
+ case 's':
+ dst.SchemaName = v
+ case 't':
+ dst.TableName = v
+ case 'c':
+ dst.ColumnName = v
+ case 'd':
+ dst.DataTypeName = v
+ case 'n':
+ dst.ConstraintName = v
+ case 'F':
+ dst.File = v
+ case 'L':
+ s := v
+ n, _ := strconv.ParseInt(s, 10, 32)
+ dst.Line = int32(n)
+ case 'R':
+ dst.Routine = v
+
+ default:
+ if dst.UnknownFields == nil {
+ dst.UnknownFields = make(map[byte]string)
+ }
+ dst.UnknownFields[k] = v
+ }
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *ErrorResponse) Encode(dst []byte) []byte {
+ return append(dst, src.marshalBinary('E')...)
+}
+
+func (src *ErrorResponse) marshalBinary(typeByte byte) []byte {
+ var bigEndian BigEndianBuf
+ buf := &bytes.Buffer{}
+
+ buf.WriteByte(typeByte)
+ buf.Write(bigEndian.Uint32(0))
+
+ if src.Severity != "" {
+ buf.WriteByte('S')
+ buf.WriteString(src.Severity)
+ buf.WriteByte(0)
+ }
+ if src.SeverityUnlocalized != "" {
+ buf.WriteByte('V')
+ buf.WriteString(src.SeverityUnlocalized)
+ buf.WriteByte(0)
+ }
+ if src.Code != "" {
+ buf.WriteByte('C')
+ buf.WriteString(src.Code)
+ buf.WriteByte(0)
+ }
+ if src.Message != "" {
+ buf.WriteByte('M')
+ buf.WriteString(src.Message)
+ buf.WriteByte(0)
+ }
+ if src.Detail != "" {
+ buf.WriteByte('D')
+ buf.WriteString(src.Detail)
+ buf.WriteByte(0)
+ }
+ if src.Hint != "" {
+ buf.WriteByte('H')
+ buf.WriteString(src.Hint)
+ buf.WriteByte(0)
+ }
+ if src.Position != 0 {
+ buf.WriteByte('P')
+ buf.WriteString(strconv.Itoa(int(src.Position)))
+ buf.WriteByte(0)
+ }
+ if src.InternalPosition != 0 {
+ buf.WriteByte('p')
+ buf.WriteString(strconv.Itoa(int(src.InternalPosition)))
+ buf.WriteByte(0)
+ }
+ if src.InternalQuery != "" {
+ buf.WriteByte('q')
+ buf.WriteString(src.InternalQuery)
+ buf.WriteByte(0)
+ }
+ if src.Where != "" {
+ buf.WriteByte('W')
+ buf.WriteString(src.Where)
+ buf.WriteByte(0)
+ }
+ if src.SchemaName != "" {
+ buf.WriteByte('s')
+ buf.WriteString(src.SchemaName)
+ buf.WriteByte(0)
+ }
+ if src.TableName != "" {
+ buf.WriteByte('t')
+ buf.WriteString(src.TableName)
+ buf.WriteByte(0)
+ }
+ if src.ColumnName != "" {
+ buf.WriteByte('c')
+ buf.WriteString(src.ColumnName)
+ buf.WriteByte(0)
+ }
+ if src.DataTypeName != "" {
+ buf.WriteByte('d')
+ buf.WriteString(src.DataTypeName)
+ buf.WriteByte(0)
+ }
+ if src.ConstraintName != "" {
+ buf.WriteByte('n')
+ buf.WriteString(src.ConstraintName)
+ buf.WriteByte(0)
+ }
+ if src.File != "" {
+ buf.WriteByte('F')
+ buf.WriteString(src.File)
+ buf.WriteByte(0)
+ }
+ if src.Line != 0 {
+ buf.WriteByte('L')
+ buf.WriteString(strconv.Itoa(int(src.Line)))
+ buf.WriteByte(0)
+ }
+ if src.Routine != "" {
+ buf.WriteByte('R')
+ buf.WriteString(src.Routine)
+ buf.WriteByte(0)
+ }
+
+ for k, v := range src.UnknownFields {
+ buf.WriteByte(k)
+ buf.WriteString(v)
+ buf.WriteByte(0)
+ }
+
+ buf.WriteByte(0)
+
+ binary.BigEndian.PutUint32(buf.Bytes()[1:5], uint32(buf.Len()-1))
+
+ return buf.Bytes()
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src ErrorResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Severity string
+ SeverityUnlocalized string // only in 9.6 and greater
+ Code string
+ Message string
+ Detail string
+ Hint string
+ Position int32
+ InternalPosition int32
+ InternalQuery string
+ Where string
+ SchemaName string
+ TableName string
+ ColumnName string
+ DataTypeName string
+ ConstraintName string
+ File string
+ Line int32
+ Routine string
+
+ UnknownFields map[byte]string
+ }{
+ Type: "ErrorResponse",
+ Severity: src.Severity,
+ SeverityUnlocalized: src.SeverityUnlocalized,
+ Code: src.Code,
+ Message: src.Message,
+ Detail: src.Detail,
+ Hint: src.Hint,
+ Position: src.Position,
+ InternalPosition: src.InternalPosition,
+ InternalQuery: src.InternalQuery,
+ Where: src.Where,
+ SchemaName: src.SchemaName,
+ TableName: src.TableName,
+ ColumnName: src.ColumnName,
+ DataTypeName: src.DataTypeName,
+ ConstraintName: src.ConstraintName,
+ File: src.File,
+ Line: src.Line,
+ Routine: src.Routine,
+ UnknownFields: src.UnknownFields,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *ErrorResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Type string
+ Severity string
+ SeverityUnlocalized string // only in 9.6 and greater
+ Code string
+ Message string
+ Detail string
+ Hint string
+ Position int32
+ InternalPosition int32
+ InternalQuery string
+ Where string
+ SchemaName string
+ TableName string
+ ColumnName string
+ DataTypeName string
+ ConstraintName string
+ File string
+ Line int32
+ Routine string
+
+ UnknownFields map[byte]string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+
+ dst.Severity = msg.Severity
+ dst.SeverityUnlocalized = msg.SeverityUnlocalized
+ dst.Code = msg.Code
+ dst.Message = msg.Message
+ dst.Detail = msg.Detail
+ dst.Hint = msg.Hint
+ dst.Position = msg.Position
+ dst.InternalPosition = msg.InternalPosition
+ dst.InternalQuery = msg.InternalQuery
+ dst.Where = msg.Where
+ dst.SchemaName = msg.SchemaName
+ dst.TableName = msg.TableName
+ dst.ColumnName = msg.ColumnName
+ dst.DataTypeName = msg.DataTypeName
+ dst.ConstraintName = msg.ConstraintName
+ dst.File = msg.File
+ dst.Line = msg.Line
+ dst.Routine = msg.Routine
+
+ dst.UnknownFields = msg.UnknownFields
+
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/README.md b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/README.md
new file mode 100644
index 0000000000..c181c38a02
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/README.md
@@ -0,0 +1,53 @@
+# pgfortune
+
+pgfortune is a mock PostgreSQL server that responds to every query with a fortune.
+
+## Installation
+
+Install `fortune` and `cowsay`. They should be available in any Unix package manager (apt, yum, brew, etc.)
+
+```
+go get -u github.com/jackc/pgproto3/example/pgfortune
+```
+
+## Usage
+
+```
+$ pgfortune
+```
+
+By default pgfortune listens on 127.0.0.1:15432 and responds to queries with `fortune | cowsay -f elephant`. These are
+configurable with the `listen` and `response-command` arguments respectively.
+
+While `pgfortune` is running connect to it with `psql`.
+
+```
+$ psql -h 127.0.0.1 -p 15432
+Timing is on.
+Null display is "∅".
+Line style is unicode.
+psql (11.5, server 0.0.0)
+Type "help" for help.
+
+jack@127.0.0.1:15432 jack=# select foo;
+ fortune
+─────────────────────────────────────────────
+ _________________________________________ ↵
+ / Ships are safe in harbor, but they were \↵
+ \ never meant to stay there. /↵
+ ----------------------------------------- ↵
+ \ /\ ___ /\ ↵
+ \ // \/ \/ \\ ↵
+ (( O O )) ↵
+ \\ / \ // ↵
+ \/ | | \/ ↵
+ | | | | ↵
+ | | | | ↵
+ | o | ↵
+ | | | | ↵
+ |m| |m| ↵
+
+(1 row)
+
+Time: 28.161 ms
+```
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/main.go b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/main.go
new file mode 100644
index 0000000000..0c25510b90
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/main.go
@@ -0,0 +1,51 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "os/exec"
+)
+
+var options struct {
+ listenAddress string
+ responseCommand string
+}
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "usage: %s [options]\n", os.Args[0])
+ flag.PrintDefaults()
+ }
+
+ flag.StringVar(&options.listenAddress, "listen", "127.0.0.1:15432", "Listen address")
+ flag.StringVar(&options.responseCommand, "response-command", "fortune | cowsay -f elephant", "Command to execute to generate query response")
+ flag.Parse()
+
+ ln, err := net.Listen("tcp", options.listenAddress)
+ if err != nil {
+ log.Fatal(err)
+ }
+ log.Println("Listening on", ln.Addr())
+
+ for {
+ conn, err := ln.Accept()
+ if err != nil {
+ log.Fatal(err)
+ }
+ log.Println("Accepted connection from", conn.RemoteAddr())
+
+ b := NewPgFortuneBackend(conn, func() ([]byte, error) {
+ return exec.Command("sh", "-c", options.responseCommand).CombinedOutput()
+ })
+ go func() {
+ err := b.Run()
+ if err != nil {
+ log.Println(err)
+ }
+ log.Println("Closed connection from", conn.RemoteAddr())
+ }()
+ }
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/server.go b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/server.go
new file mode 100644
index 0000000000..14ae71f839
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/server.go
@@ -0,0 +1,104 @@
+package main
+
+import (
+ "fmt"
+ "net"
+
+ "github.com/jackc/pgx/v5/pgproto3"
+)
+
+type PgFortuneBackend struct {
+ backend *pgproto3.Backend
+ conn net.Conn
+ responder func() ([]byte, error)
+}
+
+func NewPgFortuneBackend(conn net.Conn, responder func() ([]byte, error)) *PgFortuneBackend {
+ backend := pgproto3.NewBackend(conn, conn)
+
+ connHandler := &PgFortuneBackend{
+ backend: backend,
+ conn: conn,
+ responder: responder,
+ }
+
+ return connHandler
+}
+
+func (p *PgFortuneBackend) Run() error {
+ defer p.Close()
+
+ err := p.handleStartup()
+ if err != nil {
+ return err
+ }
+
+ for {
+ msg, err := p.backend.Receive()
+ if err != nil {
+ return fmt.Errorf("error receiving message: %w", err)
+ }
+
+ switch msg.(type) {
+ case *pgproto3.Query:
+ response, err := p.responder()
+ if err != nil {
+ return fmt.Errorf("error generating query response: %w", err)
+ }
+
+ buf := (&pgproto3.RowDescription{Fields: []pgproto3.FieldDescription{
+ {
+ Name: []byte("fortune"),
+ TableOID: 0,
+ TableAttributeNumber: 0,
+ DataTypeOID: 25,
+ DataTypeSize: -1,
+ TypeModifier: -1,
+ Format: 0,
+ },
+ }}).Encode(nil)
+ buf = (&pgproto3.DataRow{Values: [][]byte{response}}).Encode(buf)
+ buf = (&pgproto3.CommandComplete{CommandTag: []byte("SELECT 1")}).Encode(buf)
+ buf = (&pgproto3.ReadyForQuery{TxStatus: 'I'}).Encode(buf)
+ _, err = p.conn.Write(buf)
+ if err != nil {
+ return fmt.Errorf("error writing query response: %w", err)
+ }
+ case *pgproto3.Terminate:
+ return nil
+ default:
+ return fmt.Errorf("received message other than Query from client: %#v", msg)
+ }
+ }
+}
+
+func (p *PgFortuneBackend) handleStartup() error {
+ startupMessage, err := p.backend.ReceiveStartupMessage()
+ if err != nil {
+ return fmt.Errorf("error receiving startup message: %w", err)
+ }
+
+ switch startupMessage.(type) {
+ case *pgproto3.StartupMessage:
+ buf := (&pgproto3.AuthenticationOk{}).Encode(nil)
+ buf = (&pgproto3.ReadyForQuery{TxStatus: 'I'}).Encode(buf)
+ _, err = p.conn.Write(buf)
+ if err != nil {
+ return fmt.Errorf("error sending ready for query: %w", err)
+ }
+ case *pgproto3.SSLRequest:
+ _, err = p.conn.Write([]byte("N"))
+ if err != nil {
+ return fmt.Errorf("error sending deny SSL request: %w", err)
+ }
+ return p.handleStartup()
+ default:
+ return fmt.Errorf("unknown startup message: %#v", startupMessage)
+ }
+
+ return nil
+}
+
+func (p *PgFortuneBackend) Close() error {
+ return p.conn.Close()
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/ya.make b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/ya.make
new file mode 100644
index 0000000000..b3f4b71ae6
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/example/pgfortune/ya.make
@@ -0,0 +1,10 @@
+GO_PROGRAM()
+
+LICENSE(MIT)
+
+SRCS(
+ main.go
+ server.go
+)
+
+END()
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/example/ya.make b/vendor/github.com/jackc/pgx/v5/pgproto3/example/ya.make
new file mode 100644
index 0000000000..f1859a1003
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/example/ya.make
@@ -0,0 +1 @@
+RECURSE(pgfortune)
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go b/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go
new file mode 100644
index 0000000000..a5fee7cb91
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go
@@ -0,0 +1,65 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Execute struct {
+ Portal string
+ MaxRows uint32
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Execute) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Execute) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ b, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ dst.Portal = string(b[:len(b)-1])
+
+ if buf.Len() < 4 {
+ return &invalidMessageFormatErr{messageType: "Execute"}
+ }
+ dst.MaxRows = binary.BigEndian.Uint32(buf.Next(4))
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Execute) Encode(dst []byte) []byte {
+ dst = append(dst, 'E')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.Portal...)
+ dst = append(dst, 0)
+
+ dst = pgio.AppendUint32(dst, src.MaxRows)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Execute) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Portal string
+ MaxRows uint32
+ }{
+ Type: "Execute",
+ Portal: src.Portal,
+ MaxRows: src.MaxRows,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go b/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go
new file mode 100644
index 0000000000..2725f68942
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type Flush struct{}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Flush) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Flush) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "Flush", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Flush) Encode(dst []byte) []byte {
+ return append(dst, 'H', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Flush) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "Flush",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go b/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go
new file mode 100644
index 0000000000..83dea96383
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go
@@ -0,0 +1,363 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// Frontend acts as a client for the PostgreSQL wire protocol version 3.
+type Frontend struct {
+ cr *chunkReader
+ w io.Writer
+
+ // tracer is used to trace messages when Send or Receive is called. This means an outbound message is traced
+ // before it is actually transmitted (i.e. before Flush). It is safe to change this variable when the Frontend is
+ // idle. Setting and unsetting tracer provides equivalent functionality to PQtrace and PQuntrace in libpq.
+ tracer *tracer
+
+ wbuf []byte
+
+ // Backend message flyweights
+ authenticationOk AuthenticationOk
+ authenticationCleartextPassword AuthenticationCleartextPassword
+ authenticationMD5Password AuthenticationMD5Password
+ authenticationGSS AuthenticationGSS
+ authenticationGSSContinue AuthenticationGSSContinue
+ authenticationSASL AuthenticationSASL
+ authenticationSASLContinue AuthenticationSASLContinue
+ authenticationSASLFinal AuthenticationSASLFinal
+ backendKeyData BackendKeyData
+ bindComplete BindComplete
+ closeComplete CloseComplete
+ commandComplete CommandComplete
+ copyBothResponse CopyBothResponse
+ copyData CopyData
+ copyInResponse CopyInResponse
+ copyOutResponse CopyOutResponse
+ copyDone CopyDone
+ dataRow DataRow
+ emptyQueryResponse EmptyQueryResponse
+ errorResponse ErrorResponse
+ functionCallResponse FunctionCallResponse
+ noData NoData
+ noticeResponse NoticeResponse
+ notificationResponse NotificationResponse
+ parameterDescription ParameterDescription
+ parameterStatus ParameterStatus
+ parseComplete ParseComplete
+ readyForQuery ReadyForQuery
+ rowDescription RowDescription
+ portalSuspended PortalSuspended
+
+ bodyLen int
+ msgType byte
+ partialMsg bool
+ authType uint32
+}
+
+// NewFrontend creates a new Frontend.
+func NewFrontend(r io.Reader, w io.Writer) *Frontend {
+ cr := newChunkReader(r, 0)
+ return &Frontend{cr: cr, w: w}
+}
+
+// Send sends a message to the backend (i.e. the server). The message is not guaranteed to be written until Flush is
+// called.
+//
+// Send can work with any FrontendMessage. Some commonly used message types such as Bind have specialized send methods
+// such as SendBind. These methods should be preferred when the type of message is known up front (e.g. when building an
+// extended query protocol query) as they may be faster due to knowing the type of msg rather than it being hidden
+// behind an interface.
+func (f *Frontend) Send(msg FrontendMessage) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceMessage('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// Flush writes any pending messages to the backend (i.e. the server).
+func (f *Frontend) Flush() error {
+ if len(f.wbuf) == 0 {
+ return nil
+ }
+
+ n, err := f.w.Write(f.wbuf)
+
+ const maxLen = 1024
+ if len(f.wbuf) > maxLen {
+ f.wbuf = make([]byte, 0, maxLen)
+ } else {
+ f.wbuf = f.wbuf[:0]
+ }
+
+ if err != nil {
+ return &writeError{err: err, safeToRetry: n == 0}
+ }
+
+ return nil
+}
+
+// Trace starts tracing the message traffic to w. It writes in a similar format to that produced by the libpq function
+// PQtrace.
+func (f *Frontend) Trace(w io.Writer, options TracerOptions) {
+ f.tracer = &tracer{
+ w: w,
+ buf: &bytes.Buffer{},
+ TracerOptions: options,
+ }
+}
+
+// Untrace stops tracing.
+func (f *Frontend) Untrace() {
+ f.tracer = nil
+}
+
+// SendBind sends a Bind message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendBind(msg *Bind) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceBind('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendParse sends a Parse message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendParse(msg *Parse) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceParse('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendClose sends a Close message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendClose(msg *Close) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceClose('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendDescribe sends a Describe message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendDescribe(msg *Describe) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceDescribe('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendExecute sends a Execute message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendExecute(msg *Execute) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.TraceQueryute('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendSync sends a Sync message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendSync(msg *Sync) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceSync('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendQuery sends a Query message to the backend (i.e. the server). The message is not guaranteed to be written until
+// Flush is called.
+func (f *Frontend) SendQuery(msg *Query) {
+ prevLen := len(f.wbuf)
+ f.wbuf = msg.Encode(f.wbuf)
+ if f.tracer != nil {
+ f.tracer.traceQuery('F', int32(len(f.wbuf)-prevLen), msg)
+ }
+}
+
+// SendUnbufferedEncodedCopyData immediately sends an encoded CopyData message to the backend (i.e. the server). This method
+// is more efficient than sending a CopyData message with Send as the message data is not copied to the internal buffer
+// before being written out. The internal buffer is flushed before the message is sent.
+func (f *Frontend) SendUnbufferedEncodedCopyData(msg []byte) error {
+ err := f.Flush()
+ if err != nil {
+ return err
+ }
+
+ n, err := f.w.Write(msg)
+ if err != nil {
+ return &writeError{err: err, safeToRetry: n == 0}
+ }
+
+ if f.tracer != nil {
+ f.tracer.traceCopyData('F', int32(len(msg)-1), &CopyData{})
+ }
+
+ return nil
+}
+
+func translateEOFtoErrUnexpectedEOF(err error) error {
+ if err == io.EOF {
+ return io.ErrUnexpectedEOF
+ }
+ return err
+}
+
+// Receive receives a message from the backend. The returned message is only valid until the next call to Receive.
+func (f *Frontend) Receive() (BackendMessage, error) {
+ if !f.partialMsg {
+ header, err := f.cr.Next(5)
+ if err != nil {
+ return nil, translateEOFtoErrUnexpectedEOF(err)
+ }
+
+ f.msgType = header[0]
+
+ msgLength := int(binary.BigEndian.Uint32(header[1:]))
+ if msgLength < 4 {
+ return nil, fmt.Errorf("invalid message length: %d", msgLength)
+ }
+
+ f.bodyLen = msgLength - 4
+ f.partialMsg = true
+ }
+
+ msgBody, err := f.cr.Next(f.bodyLen)
+ if err != nil {
+ return nil, translateEOFtoErrUnexpectedEOF(err)
+ }
+
+ f.partialMsg = false
+
+ var msg BackendMessage
+ switch f.msgType {
+ case '1':
+ msg = &f.parseComplete
+ case '2':
+ msg = &f.bindComplete
+ case '3':
+ msg = &f.closeComplete
+ case 'A':
+ msg = &f.notificationResponse
+ case 'c':
+ msg = &f.copyDone
+ case 'C':
+ msg = &f.commandComplete
+ case 'd':
+ msg = &f.copyData
+ case 'D':
+ msg = &f.dataRow
+ case 'E':
+ msg = &f.errorResponse
+ case 'G':
+ msg = &f.copyInResponse
+ case 'H':
+ msg = &f.copyOutResponse
+ case 'I':
+ msg = &f.emptyQueryResponse
+ case 'K':
+ msg = &f.backendKeyData
+ case 'n':
+ msg = &f.noData
+ case 'N':
+ msg = &f.noticeResponse
+ case 'R':
+ var err error
+ msg, err = f.findAuthenticationMessageType(msgBody)
+ if err != nil {
+ return nil, err
+ }
+ case 's':
+ msg = &f.portalSuspended
+ case 'S':
+ msg = &f.parameterStatus
+ case 't':
+ msg = &f.parameterDescription
+ case 'T':
+ msg = &f.rowDescription
+ case 'V':
+ msg = &f.functionCallResponse
+ case 'W':
+ msg = &f.copyBothResponse
+ case 'Z':
+ msg = &f.readyForQuery
+ default:
+ return nil, fmt.Errorf("unknown message type: %c", f.msgType)
+ }
+
+ err = msg.Decode(msgBody)
+ if err != nil {
+ return nil, err
+ }
+
+ if f.tracer != nil {
+ f.tracer.traceMessage('B', int32(5+len(msgBody)), msg)
+ }
+
+ return msg, nil
+}
+
+// Authentication message type constants.
+// See src/include/libpq/pqcomm.h for all
+// constants.
+const (
+ AuthTypeOk = 0
+ AuthTypeCleartextPassword = 3
+ AuthTypeMD5Password = 5
+ AuthTypeSCMCreds = 6
+ AuthTypeGSS = 7
+ AuthTypeGSSCont = 8
+ AuthTypeSSPI = 9
+ AuthTypeSASL = 10
+ AuthTypeSASLContinue = 11
+ AuthTypeSASLFinal = 12
+)
+
+func (f *Frontend) findAuthenticationMessageType(src []byte) (BackendMessage, error) {
+ if len(src) < 4 {
+ return nil, errors.New("authentication message too short")
+ }
+ f.authType = binary.BigEndian.Uint32(src[:4])
+
+ switch f.authType {
+ case AuthTypeOk:
+ return &f.authenticationOk, nil
+ case AuthTypeCleartextPassword:
+ return &f.authenticationCleartextPassword, nil
+ case AuthTypeMD5Password:
+ return &f.authenticationMD5Password, nil
+ case AuthTypeSCMCreds:
+ return nil, errors.New("AuthTypeSCMCreds is unimplemented")
+ case AuthTypeGSS:
+ return &f.authenticationGSS, nil
+ case AuthTypeGSSCont:
+ return &f.authenticationGSSContinue, nil
+ case AuthTypeSSPI:
+ return nil, errors.New("AuthTypeSSPI is unimplemented")
+ case AuthTypeSASL:
+ return &f.authenticationSASL, nil
+ case AuthTypeSASLContinue:
+ return &f.authenticationSASLContinue, nil
+ case AuthTypeSASLFinal:
+ return &f.authenticationSASLFinal, nil
+ default:
+ return nil, fmt.Errorf("unknown authentication type: %d", f.authType)
+ }
+}
+
+// GetAuthType returns the authType used in the current state of the frontend.
+// See SetAuthType for more information.
+func (f *Frontend) GetAuthType() uint32 {
+ return f.authType
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go
new file mode 100644
index 0000000000..2c4f38dfd5
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go
@@ -0,0 +1,95 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type FunctionCall struct {
+ Function uint32
+ ArgFormatCodes []uint16
+ Arguments [][]byte
+ ResultFormatCode uint16
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*FunctionCall) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *FunctionCall) Decode(src []byte) error {
+ *dst = FunctionCall{}
+ rp := 0
+ // Specifies the object ID of the function to call.
+ dst.Function = binary.BigEndian.Uint32(src[rp:])
+ rp += 4
+ // The number of argument format codes that follow (denoted C below).
+ // This can be zero to indicate that there are no arguments or that the arguments all use the default format (text);
+ // or one, in which case the specified format code is applied to all arguments;
+ // or it can equal the actual number of arguments.
+ nArgumentCodes := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+ argumentCodes := make([]uint16, nArgumentCodes)
+ for i := 0; i < nArgumentCodes; i++ {
+ // The argument format codes. Each must presently be zero (text) or one (binary).
+ ac := binary.BigEndian.Uint16(src[rp:])
+ if ac != 0 && ac != 1 {
+ return &invalidMessageFormatErr{messageType: "FunctionCall"}
+ }
+ argumentCodes[i] = ac
+ rp += 2
+ }
+ dst.ArgFormatCodes = argumentCodes
+
+ // Specifies the number of arguments being supplied to the function.
+ nArguments := int(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+ arguments := make([][]byte, nArguments)
+ for i := 0; i < nArguments; i++ {
+ // The length of the argument value, in bytes (this count does not include itself). Can be zero.
+ // As a special case, -1 indicates a NULL argument value. No value bytes follow in the NULL case.
+ argumentLength := int(binary.BigEndian.Uint32(src[rp:]))
+ rp += 4
+ if argumentLength == -1 {
+ arguments[i] = nil
+ } else {
+ // The value of the argument, in the format indicated by the associated format code. n is the above length.
+ argumentValue := src[rp : rp+argumentLength]
+ rp += argumentLength
+ arguments[i] = argumentValue
+ }
+ }
+ dst.Arguments = arguments
+ // The format code for the function result. Must presently be zero (text) or one (binary).
+ resultFormatCode := binary.BigEndian.Uint16(src[rp:])
+ if resultFormatCode != 0 && resultFormatCode != 1 {
+ return &invalidMessageFormatErr{messageType: "FunctionCall"}
+ }
+ dst.ResultFormatCode = resultFormatCode
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *FunctionCall) Encode(dst []byte) []byte {
+ dst = append(dst, 'F')
+ sp := len(dst)
+ dst = pgio.AppendUint32(dst, 0) // Unknown length, set it at the end
+ dst = pgio.AppendUint32(dst, src.Function)
+ dst = pgio.AppendUint16(dst, uint16(len(src.ArgFormatCodes)))
+ for _, argFormatCode := range src.ArgFormatCodes {
+ dst = pgio.AppendUint16(dst, argFormatCode)
+ }
+ dst = pgio.AppendUint16(dst, uint16(len(src.Arguments)))
+ for _, argument := range src.Arguments {
+ if argument == nil {
+ dst = pgio.AppendInt32(dst, -1)
+ } else {
+ dst = pgio.AppendInt32(dst, int32(len(argument)))
+ dst = append(dst, argument...)
+ }
+ }
+ dst = pgio.AppendUint16(dst, src.ResultFormatCode)
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+ return dst
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go
new file mode 100644
index 0000000000..3d3606ddb3
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go
@@ -0,0 +1,101 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type FunctionCallResponse struct {
+ Result []byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*FunctionCallResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *FunctionCallResponse) Decode(src []byte) error {
+ if len(src) < 4 {
+ return &invalidMessageFormatErr{messageType: "FunctionCallResponse"}
+ }
+ rp := 0
+ resultSize := int(binary.BigEndian.Uint32(src[rp:]))
+ rp += 4
+
+ if resultSize == -1 {
+ dst.Result = nil
+ return nil
+ }
+
+ if len(src[rp:]) != resultSize {
+ return &invalidMessageFormatErr{messageType: "FunctionCallResponse"}
+ }
+
+ dst.Result = src[rp:]
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *FunctionCallResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'V')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ if src.Result == nil {
+ dst = pgio.AppendInt32(dst, -1)
+ } else {
+ dst = pgio.AppendInt32(dst, int32(len(src.Result)))
+ dst = append(dst, src.Result...)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src FunctionCallResponse) MarshalJSON() ([]byte, error) {
+ var formattedValue map[string]string
+ var hasNonPrintable bool
+ for _, b := range src.Result {
+ if b < 32 {
+ hasNonPrintable = true
+ break
+ }
+ }
+
+ if hasNonPrintable {
+ formattedValue = map[string]string{"binary": hex.EncodeToString(src.Result)}
+ } else {
+ formattedValue = map[string]string{"text": string(src.Result)}
+ }
+
+ return json.Marshal(struct {
+ Type string
+ Result map[string]string
+ }{
+ Type: "FunctionCallResponse",
+ Result: formattedValue,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *FunctionCallResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ Result map[string]string
+ }
+ err := json.Unmarshal(data, &msg)
+ if err != nil {
+ return err
+ }
+ dst.Result, err = getValueFromJSON(msg.Result)
+ return err
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_test.go b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_test.go
new file mode 100644
index 0000000000..8c08bb240e
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_test.go
@@ -0,0 +1,62 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "reflect"
+ "testing"
+)
+
+func TestFunctionCall_EncodeDecode(t *testing.T) {
+ type fields struct {
+ Function uint32
+ ArgFormatCodes []uint16
+ Arguments [][]byte
+ ResultFormatCode uint16
+ }
+ tests := []struct {
+ name string
+ fields fields
+ wantErr bool
+ }{
+ {"valid", fields{uint32(123), []uint16{0, 1, 0, 1}, [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}, uint16(1)}, false},
+ {"invalid format code", fields{uint32(123), []uint16{2, 1, 0, 1}, [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}, uint16(0)}, true},
+ {"invalid result format code", fields{uint32(123), []uint16{1, 1, 0, 1}, [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}, uint16(2)}, true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ src := &FunctionCall{
+ Function: tt.fields.Function,
+ ArgFormatCodes: tt.fields.ArgFormatCodes,
+ Arguments: tt.fields.Arguments,
+ ResultFormatCode: tt.fields.ResultFormatCode,
+ }
+ encoded := src.Encode([]byte{})
+ dst := &FunctionCall{}
+ // Check the header
+ msgTypeCode := encoded[0]
+ if msgTypeCode != 'F' {
+ t.Errorf("msgTypeCode %v should be 'F'", msgTypeCode)
+ return
+ }
+ // Check length, does not include type code character
+ l := binary.BigEndian.Uint32(encoded[1:5])
+ if int(l) != (len(encoded) - 1) {
+ t.Errorf("Incorrect message length, got = %v, wanted = %v", l, len(encoded))
+ }
+ // Check decoding works as expected
+ err := dst.Decode(encoded[5:])
+ if err != nil {
+ if !tt.wantErr {
+ t.Errorf("FunctionCall.Decode() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ return
+ }
+
+ if !reflect.DeepEqual(src, dst) {
+ t.Error("difference after encode / decode cycle")
+ t.Errorf("src = %v", src)
+ t.Errorf("dst = %v", dst)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/fuzz_test.go b/vendor/github.com/jackc/pgx/v5/pgproto3/fuzz_test.go
new file mode 100644
index 0000000000..332596aba1
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/fuzz_test.go
@@ -0,0 +1,57 @@
+package pgproto3_test
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+ "github.com/jackc/pgx/v5/pgproto3"
+ "github.com/stretchr/testify/require"
+)
+
+func FuzzFrontend(f *testing.F) {
+ testcases := []struct {
+ msgType byte
+ msgLen uint32
+ msgBody []byte
+ }{
+ {
+ msgType: 'Z',
+ msgLen: 2,
+ msgBody: []byte{'I'},
+ },
+ {
+ msgType: 'Z',
+ msgLen: 5,
+ msgBody: []byte{'I'},
+ },
+ }
+ for _, tc := range testcases {
+ f.Add(tc.msgType, tc.msgLen, tc.msgBody)
+ }
+ f.Fuzz(func(t *testing.T, msgType byte, msgLen uint32, msgBody []byte) {
+ // Prune any msgLen > len(msgBody) because they would hang the test waiting for more input.
+ if int(msgLen) > len(msgBody)+4 {
+ return
+ }
+
+ // Prune any messages that are too long.
+ if msgLen > 128 || len(msgBody) > 128 {
+ return
+ }
+
+ r := &bytes.Buffer{}
+ w := &bytes.Buffer{}
+ fe := pgproto3.NewFrontend(r, w)
+
+ var encodedMsg []byte
+ encodedMsg = append(encodedMsg, msgType)
+ encodedMsg = pgio.AppendUint32(encodedMsg, msgLen)
+ encodedMsg = append(encodedMsg, msgBody...)
+ _, err := r.Write(encodedMsg)
+ require.NoError(t, err)
+
+ // Not checking anything other than no panic.
+ fe.Receive()
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/gotest/ya.make b/vendor/github.com/jackc/pgx/v5/pgproto3/gotest/ya.make
new file mode 100644
index 0000000000..8d865120b6
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/gotest/ya.make
@@ -0,0 +1,9 @@
+GO_TEST_FOR(vendor/github.com/jackc/pgx/v5/pgproto3)
+
+LICENSE(MIT)
+
+DATA(arcadia/vendor/github.com/jackc/pgx/v5/pgproto3/testdata)
+
+TEST_CWD(vendor/github.com/jackc/pgx/v5/pgproto3)
+
+END()
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go
new file mode 100644
index 0000000000..30ffc08d27
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go
@@ -0,0 +1,49 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+const gssEncReqNumber = 80877104
+
+type GSSEncRequest struct {
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*GSSEncRequest) Frontend() {}
+
+func (dst *GSSEncRequest) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("gss encoding request too short")
+ }
+
+ requestCode := binary.BigEndian.Uint32(src)
+
+ if requestCode != gssEncReqNumber {
+ return errors.New("bad gss encoding request code")
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 4 byte message length.
+func (src *GSSEncRequest) Encode(dst []byte) []byte {
+ dst = pgio.AppendInt32(dst, 8)
+ dst = pgio.AppendInt32(dst, gssEncReqNumber)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src GSSEncRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ProtocolVersion uint32
+ Parameters map[string]string
+ }{
+ Type: "GSSEncRequest",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go
new file mode 100644
index 0000000000..64bfbd049a
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go
@@ -0,0 +1,49 @@
+package pgproto3
+
+import (
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type GSSResponse struct {
+ Data []byte
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (g *GSSResponse) Frontend() {}
+
+func (g *GSSResponse) Decode(data []byte) error {
+ g.Data = data
+ return nil
+}
+
+func (g *GSSResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'p')
+ dst = pgio.AppendInt32(dst, int32(4+len(g.Data)))
+ dst = append(dst, g.Data...)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (g *GSSResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data []byte
+ }{
+ Type: "GSSResponse",
+ Data: g.Data,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (g *GSSResponse) UnmarshalJSON(data []byte) error {
+ var msg struct {
+ Data []byte
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ g.Data = msg.Data
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/json_test.go b/vendor/github.com/jackc/pgx/v5/pgproto3/json_test.go
new file mode 100644
index 0000000000..8fad4f8824
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/json_test.go
@@ -0,0 +1,611 @@
+package pgproto3
+
+import (
+ "encoding/hex"
+ "encoding/json"
+ "reflect"
+ "testing"
+)
+
+func TestJSONUnmarshalAuthenticationMD5Password(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationMD5Password", "Salt":[97,98,99,100]}`)
+ want := AuthenticationMD5Password{
+ Salt: [4]byte{'a', 'b', 'c', 'd'},
+ }
+
+ var got AuthenticationMD5Password
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationMD5Password struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalAuthenticationSASL(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationSASL","AuthMechanisms":["SCRAM-SHA-256"]}`)
+ want := AuthenticationSASL{
+ []string{"SCRAM-SHA-256"},
+ }
+
+ var got AuthenticationSASL
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationSASL struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalAuthenticationGSS(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationGSS"}`)
+ want := AuthenticationGSS{}
+
+ var got AuthenticationGSS
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationGSS struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalAuthenticationGSSContinue(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationGSSContinue","Data":[1,2,3,4]}`)
+ want := AuthenticationGSSContinue{Data: []byte{1, 2, 3, 4}}
+
+ var got AuthenticationGSSContinue
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationGSSContinue struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalAuthenticationSASLContinue(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationSASLContinue", "Data":"1"}`)
+ want := AuthenticationSASLContinue{
+ Data: []byte{'1'},
+ }
+
+ var got AuthenticationSASLContinue
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationSASLContinue struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalAuthenticationSASLFinal(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationSASLFinal", "Data":"1"}`)
+ want := AuthenticationSASLFinal{
+ Data: []byte{'1'},
+ }
+
+ var got AuthenticationSASLFinal
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationSASLFinal struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalBackendKeyData(t *testing.T) {
+ data := []byte(`{"Type":"BackendKeyData","ProcessID":8864,"SecretKey":3641487067}`)
+ want := BackendKeyData{
+ ProcessID: 8864,
+ SecretKey: 3641487067,
+ }
+
+ var got BackendKeyData
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled BackendKeyData struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCommandComplete(t *testing.T) {
+ data := []byte(`{"Type":"CommandComplete","CommandTag":"SELECT 1"}`)
+ want := CommandComplete{
+ CommandTag: []byte("SELECT 1"),
+ }
+
+ var got CommandComplete
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CommandComplete struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCopyBothResponse(t *testing.T) {
+ data := []byte(`{"Type":"CopyBothResponse", "OverallFormat": "W"}`)
+ want := CopyBothResponse{
+ OverallFormat: 'W',
+ }
+
+ var got CopyBothResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CopyBothResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCopyData(t *testing.T) {
+ data := []byte(`{"Type":"CopyData"}`)
+ want := CopyData{
+ Data: []byte{},
+ }
+
+ var got CopyData
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CopyData struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCopyInResponse(t *testing.T) {
+ data := []byte(`{"Type":"CopyBothResponse", "OverallFormat": "W"}`)
+ want := CopyBothResponse{
+ OverallFormat: 'W',
+ }
+
+ var got CopyBothResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CopyBothResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCopyOutResponse(t *testing.T) {
+ data := []byte(`{"Type":"CopyOutResponse", "OverallFormat": "W"}`)
+ want := CopyOutResponse{
+ OverallFormat: 'W',
+ }
+
+ var got CopyOutResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CopyOutResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalDataRow(t *testing.T) {
+ data := []byte(`{"Type":"DataRow","Values":[{"text":"abc"},{"text":"this is a test"},{"binary":"000263d3114d2e34"}]}`)
+ want := DataRow{
+ Values: [][]byte{
+ []byte("abc"),
+ []byte("this is a test"),
+ {0, 2, 99, 211, 17, 77, 46, 52},
+ },
+ }
+
+ var got DataRow
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled DataRow struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalErrorResponse(t *testing.T) {
+ data := []byte(`{"Type":"ErrorResponse", "UnknownFields": {"97": "foo"}}`)
+ want := ErrorResponse{
+ UnknownFields: map[byte]string{
+ 'a': "foo",
+ },
+ }
+
+ var got ErrorResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled ErrorResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalFunctionCallResponse(t *testing.T) {
+ data := []byte(`{"Type":"FunctionCallResponse"}`)
+ want := FunctionCallResponse{}
+
+ var got FunctionCallResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled FunctionCallResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalNoticeResponse(t *testing.T) {
+ data := []byte(`{"Type":"NoticeResponse", "UnknownFields": {"97": "foo"}}`)
+ want := NoticeResponse{
+ UnknownFields: map[byte]string{
+ 'a': "foo",
+ },
+ }
+
+ var got NoticeResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled NoticeResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalNotificationResponse(t *testing.T) {
+ data := []byte(`{"Type":"NotificationResponse"}`)
+ want := NotificationResponse{}
+
+ var got NotificationResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled NotificationResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalParameterDescription(t *testing.T) {
+ data := []byte(`{"Type":"ParameterDescription", "ParameterOIDs": [25]}`)
+ want := ParameterDescription{
+ ParameterOIDs: []uint32{25},
+ }
+
+ var got ParameterDescription
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled ParameterDescription struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalParameterStatus(t *testing.T) {
+ data := []byte(`{"Type":"ParameterStatus","Name":"TimeZone","Value":"Europe/Amsterdam"}`)
+ want := ParameterStatus{
+ Name: "TimeZone",
+ Value: "Europe/Amsterdam",
+ }
+
+ var got ParameterStatus
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled ParameterDescription struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalReadyForQuery(t *testing.T) {
+ data := []byte(`{"Type":"ReadyForQuery","TxStatus":"I"}`)
+ want := ReadyForQuery{
+ TxStatus: 'I',
+ }
+
+ var got ReadyForQuery
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled ParameterDescription struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalRowDescription(t *testing.T) {
+ data := []byte(`{"Type":"RowDescription","Fields":[{"Name":"generate_series","TableOID":0,"TableAttributeNumber":0,"DataTypeOID":23,"DataTypeSize":4,"TypeModifier":-1,"Format":0}]}`)
+ want := RowDescription{
+ Fields: []FieldDescription{
+ {
+ Name: []byte("generate_series"),
+ DataTypeOID: 23,
+ DataTypeSize: 4,
+ TypeModifier: -1,
+ },
+ },
+ }
+
+ var got RowDescription
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled RowDescription struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalBind(t *testing.T) {
+ var testCases = []struct {
+ desc string
+ data []byte
+ }{
+ {
+ "textual",
+ []byte(`{"Type":"Bind","DestinationPortal":"","PreparedStatement":"lrupsc_1_0","ParameterFormatCodes":[0],"Parameters":[{"text":"ABC-123"}],"ResultFormatCodes":[0,0,0,0,0,1,1]}`),
+ },
+ {
+ "binary",
+ []byte(`{"Type":"Bind","DestinationPortal":"","PreparedStatement":"lrupsc_1_0","ParameterFormatCodes":[0],"Parameters":[{"binary":"` + hex.EncodeToString([]byte("ABC-123")) + `"}],"ResultFormatCodes":[0,0,0,0,0,1,1]}`),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ var want = Bind{
+ PreparedStatement: "lrupsc_1_0",
+ ParameterFormatCodes: []int16{0},
+ Parameters: [][]byte{[]byte("ABC-123")},
+ ResultFormatCodes: []int16{0, 0, 0, 0, 0, 1, 1},
+ }
+
+ var got Bind
+ if err := json.Unmarshal(tc.data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Bind struct doesn't match expected value")
+ }
+ })
+ }
+}
+
+func TestJSONUnmarshalCancelRequest(t *testing.T) {
+ data := []byte(`{"Type":"CancelRequest","ProcessID":8864,"SecretKey":3641487067}`)
+ want := CancelRequest{
+ ProcessID: 8864,
+ SecretKey: 3641487067,
+ }
+
+ var got CancelRequest
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CancelRequest struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalClose(t *testing.T) {
+ data := []byte(`{"Type":"Close","ObjectType":"S","Name":"abc"}`)
+ want := Close{
+ ObjectType: 'S',
+ Name: "abc",
+ }
+
+ var got Close
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Close struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalCopyFail(t *testing.T) {
+ data := []byte(`{"Type":"CopyFail","Message":"abc"}`)
+ want := CopyFail{
+ Message: "abc",
+ }
+
+ var got CopyFail
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled CopyFail struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalDescribe(t *testing.T) {
+ data := []byte(`{"Type":"Describe","ObjectType":"S","Name":"abc"}`)
+ want := Describe{
+ ObjectType: 'S',
+ Name: "abc",
+ }
+
+ var got Describe
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Describe struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalExecute(t *testing.T) {
+ data := []byte(`{"Type":"Execute","Portal":"","MaxRows":0}`)
+ want := Execute{}
+
+ var got Execute
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Execute struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalParse(t *testing.T) {
+ data := []byte(`{"Type":"Parse","Name":"lrupsc_1_0","Query":"SELECT id, name FROM t WHERE id = $1","ParameterOIDs":null}`)
+ want := Parse{
+ Name: "lrupsc_1_0",
+ Query: "SELECT id, name FROM t WHERE id = $1",
+ }
+
+ var got Parse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Parse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalPasswordMessage(t *testing.T) {
+ data := []byte(`{"Type":"PasswordMessage","Password":"abcdef"}`)
+ want := PasswordMessage{
+ Password: "abcdef",
+ }
+
+ var got PasswordMessage
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled PasswordMessage struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalQuery(t *testing.T) {
+ data := []byte(`{"Type":"Query","String":"SELECT 1"}`)
+ want := Query{
+ String: "SELECT 1",
+ }
+
+ var got Query
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled Query struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalSASLInitialResponse(t *testing.T) {
+ data := []byte(`{"Type":"SASLInitialResponse", "AuthMechanism":"SCRAM-SHA-256", "Data": "6D"}`)
+ want := SASLInitialResponse{
+ AuthMechanism: "SCRAM-SHA-256",
+ Data: []byte{109},
+ }
+
+ var got SASLInitialResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled SASLInitialResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalSASLResponse(t *testing.T) {
+ data := []byte(`{"Type":"SASLResponse","Message":"abc"}`)
+ want := SASLResponse{}
+
+ var got SASLResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled SASLResponse struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalStartupMessage(t *testing.T) {
+ data := []byte(`{"Type":"StartupMessage","ProtocolVersion":196608,"Parameters":{"database":"testing","user":"postgres"}}`)
+ want := StartupMessage{
+ ProtocolVersion: 196608,
+ Parameters: map[string]string{
+ "database": "testing",
+ "user": "postgres",
+ },
+ }
+
+ var got StartupMessage
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled StartupMessage struct doesn't match expected value")
+ }
+}
+
+func TestAuthenticationOK(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationOK"}`)
+ want := AuthenticationOk{}
+
+ var got AuthenticationOk
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationOK struct doesn't match expected value")
+ }
+}
+
+func TestAuthenticationCleartextPassword(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationCleartextPassword"}`)
+ want := AuthenticationCleartextPassword{}
+
+ var got AuthenticationCleartextPassword
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationCleartextPassword struct doesn't match expected value")
+ }
+}
+
+func TestAuthenticationMD5Password(t *testing.T) {
+ data := []byte(`{"Type":"AuthenticationMD5Password","Salt":[1,2,3,4]}`)
+ want := AuthenticationMD5Password{
+ Salt: [4]byte{1, 2, 3, 4},
+ }
+
+ var got AuthenticationMD5Password
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled AuthenticationMD5Password struct doesn't match expected value")
+ }
+}
+
+func TestJSONUnmarshalGSSResponse(t *testing.T) {
+ data := []byte(`{"Type":"GSSResponse","Data":[10,20,30,40]}`)
+ want := GSSResponse{Data: []byte{10, 20, 30, 40}}
+
+ var got GSSResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled GSSResponse struct doesn't match expected value")
+ }
+}
+
+func TestErrorResponse(t *testing.T) {
+ data := []byte(`{"Type":"ErrorResponse","UnknownFields":{"112":"foo"},"Code": "Fail","Position":1,"Message":"this is an error"}`)
+ want := ErrorResponse{
+ UnknownFields: map[byte]string{
+ 'p': "foo",
+ },
+ Code: "Fail",
+ Position: 1,
+ Message: "this is an error",
+ }
+
+ var got ErrorResponse
+ if err := json.Unmarshal(data, &got); err != nil {
+ t.Errorf("cannot JSON unmarshal %v", err)
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Error("unmarshaled ErrorResponse struct doesn't match expected value")
+ }
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go
new file mode 100644
index 0000000000..d8f85d38a7
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type NoData struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*NoData) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *NoData) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "NoData", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *NoData) Encode(dst []byte) []byte {
+ return append(dst, 'n', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src NoData) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "NoData",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go
new file mode 100644
index 0000000000..4ac28a7911
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go
@@ -0,0 +1,17 @@
+package pgproto3
+
+type NoticeResponse ErrorResponse
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*NoticeResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *NoticeResponse) Decode(src []byte) error {
+ return (*ErrorResponse)(dst).Decode(src)
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *NoticeResponse) Encode(dst []byte) []byte {
+ return append(dst, (*ErrorResponse)(src).marshalBinary('N')...)
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go
new file mode 100644
index 0000000000..228e0dac39
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go
@@ -0,0 +1,77 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type NotificationResponse struct {
+ PID uint32
+ Channel string
+ Payload string
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*NotificationResponse) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *NotificationResponse) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ if buf.Len() < 4 {
+ return &invalidMessageFormatErr{messageType: "NotificationResponse", details: "too short"}
+ }
+
+ pid := binary.BigEndian.Uint32(buf.Next(4))
+
+ b, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ channel := string(b[:len(b)-1])
+
+ b, err = buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ payload := string(b[:len(b)-1])
+
+ *dst = NotificationResponse{PID: pid, Channel: channel, Payload: payload}
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *NotificationResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'A')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = pgio.AppendUint32(dst, src.PID)
+ dst = append(dst, src.Channel...)
+ dst = append(dst, 0)
+ dst = append(dst, src.Payload...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src NotificationResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ PID uint32
+ Channel string
+ Payload string
+ }{
+ Type: "NotificationResponse",
+ PID: src.PID,
+ Channel: src.Channel,
+ Payload: src.Payload,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go
new file mode 100644
index 0000000000..374d38a399
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go
@@ -0,0 +1,66 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type ParameterDescription struct {
+ ParameterOIDs []uint32
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*ParameterDescription) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *ParameterDescription) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ if buf.Len() < 2 {
+ return &invalidMessageFormatErr{messageType: "ParameterDescription"}
+ }
+
+ // Reported parameter count will be incorrect when number of args is greater than uint16
+ buf.Next(2)
+ // Instead infer parameter count by remaining size of message
+ parameterCount := buf.Len() / 4
+
+ *dst = ParameterDescription{ParameterOIDs: make([]uint32, parameterCount)}
+
+ for i := 0; i < parameterCount; i++ {
+ dst.ParameterOIDs[i] = binary.BigEndian.Uint32(buf.Next(4))
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *ParameterDescription) Encode(dst []byte) []byte {
+ dst = append(dst, 't')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
+ for _, oid := range src.ParameterOIDs {
+ dst = pgio.AppendUint32(dst, oid)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src ParameterDescription) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ParameterOIDs []uint32
+ }{
+ Type: "ParameterDescription",
+ ParameterOIDs: src.ParameterOIDs,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go
new file mode 100644
index 0000000000..a303e45364
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go
@@ -0,0 +1,66 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type ParameterStatus struct {
+ Name string
+ Value string
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*ParameterStatus) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *ParameterStatus) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ b, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ name := string(b[:len(b)-1])
+
+ b, err = buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ value := string(b[:len(b)-1])
+
+ *dst = ParameterStatus{Name: name, Value: value}
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *ParameterStatus) Encode(dst []byte) []byte {
+ dst = append(dst, 'S')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.Name...)
+ dst = append(dst, 0)
+ dst = append(dst, src.Value...)
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (ps ParameterStatus) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Name string
+ Value string
+ }{
+ Type: "ParameterStatus",
+ Name: ps.Name,
+ Value: ps.Value,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go
new file mode 100644
index 0000000000..b53200dca8
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go
@@ -0,0 +1,88 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Parse struct {
+ Name string
+ Query string
+ ParameterOIDs []uint32
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Parse) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Parse) Decode(src []byte) error {
+ *dst = Parse{}
+
+ buf := bytes.NewBuffer(src)
+
+ b, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ dst.Name = string(b[:len(b)-1])
+
+ b, err = buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ dst.Query = string(b[:len(b)-1])
+
+ if buf.Len() < 2 {
+ return &invalidMessageFormatErr{messageType: "Parse"}
+ }
+ parameterOIDCount := int(binary.BigEndian.Uint16(buf.Next(2)))
+
+ for i := 0; i < parameterOIDCount; i++ {
+ if buf.Len() < 4 {
+ return &invalidMessageFormatErr{messageType: "Parse"}
+ }
+ dst.ParameterOIDs = append(dst.ParameterOIDs, binary.BigEndian.Uint32(buf.Next(4)))
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Parse) Encode(dst []byte) []byte {
+ dst = append(dst, 'P')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, src.Name...)
+ dst = append(dst, 0)
+ dst = append(dst, src.Query...)
+ dst = append(dst, 0)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
+ for _, oid := range src.ParameterOIDs {
+ dst = pgio.AppendUint32(dst, oid)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Parse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Name string
+ Query string
+ ParameterOIDs []uint32
+ }{
+ Type: "Parse",
+ Name: src.Name,
+ Query: src.Query,
+ ParameterOIDs: src.ParameterOIDs,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go
new file mode 100644
index 0000000000..92c9498b6d
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type ParseComplete struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*ParseComplete) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *ParseComplete) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "ParseComplete", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *ParseComplete) Encode(dst []byte) []byte {
+ return append(dst, '1', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src ParseComplete) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "ParseComplete",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go b/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go
new file mode 100644
index 0000000000..41f98692be
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go
@@ -0,0 +1,54 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type PasswordMessage struct {
+ Password string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*PasswordMessage) Frontend() {}
+
+// Frontend identifies this message as an authentication response.
+func (*PasswordMessage) InitialResponse() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *PasswordMessage) Decode(src []byte) error {
+ buf := bytes.NewBuffer(src)
+
+ b, err := buf.ReadBytes(0)
+ if err != nil {
+ return err
+ }
+ dst.Password = string(b[:len(b)-1])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *PasswordMessage) Encode(dst []byte) []byte {
+ dst = append(dst, 'p')
+ dst = pgio.AppendInt32(dst, int32(4+len(src.Password)+1))
+
+ dst = append(dst, src.Password...)
+ dst = append(dst, 0)
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src PasswordMessage) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Password string
+ }{
+ Type: "PasswordMessage",
+ Password: src.Password,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go b/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go
new file mode 100644
index 0000000000..ef5a54896b
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go
@@ -0,0 +1,85 @@
+package pgproto3
+
+import (
+ "encoding/hex"
+ "errors"
+ "fmt"
+)
+
+// Message is the interface implemented by an object that can decode and encode
+// a particular PostgreSQL message.
+type Message interface {
+ // Decode is allowed and expected to retain a reference to data after
+ // returning (unlike encoding.BinaryUnmarshaler).
+ Decode(data []byte) error
+
+ // Encode appends itself to dst and returns the new buffer.
+ Encode(dst []byte) []byte
+}
+
+// FrontendMessage is a message sent by the frontend (i.e. the client).
+type FrontendMessage interface {
+ Message
+ Frontend() // no-op method to distinguish frontend from backend methods
+}
+
+// BackendMessage is a message sent by the backend (i.e. the server).
+type BackendMessage interface {
+ Message
+ Backend() // no-op method to distinguish frontend from backend methods
+}
+
+type AuthenticationResponseMessage interface {
+ BackendMessage
+ AuthenticationResponse() // no-op method to distinguish authentication responses
+}
+
+type invalidMessageLenErr struct {
+ messageType string
+ expectedLen int
+ actualLen int
+}
+
+func (e *invalidMessageLenErr) Error() string {
+ return fmt.Sprintf("%s body must have length of %d, but it is %d", e.messageType, e.expectedLen, e.actualLen)
+}
+
+type invalidMessageFormatErr struct {
+ messageType string
+ details string
+}
+
+func (e *invalidMessageFormatErr) Error() string {
+ return fmt.Sprintf("%s body is invalid %s", e.messageType, e.details)
+}
+
+type writeError struct {
+ err error
+ safeToRetry bool
+}
+
+func (e *writeError) Error() string {
+ return fmt.Sprintf("write failed: %s", e.err.Error())
+}
+
+func (e *writeError) SafeToRetry() bool {
+ return e.safeToRetry
+}
+
+func (e *writeError) Unwrap() error {
+ return e.err
+}
+
+// getValueFromJSON gets the value from a protocol message representation in JSON.
+func getValueFromJSON(v map[string]string) ([]byte, error) {
+ if v == nil {
+ return nil, nil
+ }
+ if text, ok := v["text"]; ok {
+ return []byte(text), nil
+ }
+ if binary, ok := v["binary"]; ok {
+ return hex.DecodeString(binary)
+ }
+ return nil, errors.New("unknown protocol representation")
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go b/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go
new file mode 100644
index 0000000000..1a9e7bfb1a
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type PortalSuspended struct{}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*PortalSuspended) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *PortalSuspended) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "PortalSuspended", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *PortalSuspended) Encode(dst []byte) []byte {
+ return append(dst, 's', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src PortalSuspended) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "PortalSuspended",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/query.go b/vendor/github.com/jackc/pgx/v5/pgproto3/query.go
new file mode 100644
index 0000000000..e963a0ecea
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/query.go
@@ -0,0 +1,50 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type Query struct {
+ String string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Query) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Query) Decode(src []byte) error {
+ i := bytes.IndexByte(src, 0)
+ if i != len(src)-1 {
+ return &invalidMessageFormatErr{messageType: "Query"}
+ }
+
+ dst.String = string(src[:i])
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Query) Encode(dst []byte) []byte {
+ dst = append(dst, 'Q')
+ dst = pgio.AppendInt32(dst, int32(4+len(src.String)+1))
+
+ dst = append(dst, src.String...)
+ dst = append(dst, 0)
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Query) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ String string
+ }{
+ Type: "Query",
+ String: src.String,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go b/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go
new file mode 100644
index 0000000000..67a39be395
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go
@@ -0,0 +1,61 @@
+package pgproto3
+
+import (
+ "encoding/json"
+ "errors"
+)
+
+type ReadyForQuery struct {
+ TxStatus byte
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*ReadyForQuery) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *ReadyForQuery) Decode(src []byte) error {
+ if len(src) != 1 {
+ return &invalidMessageLenErr{messageType: "ReadyForQuery", expectedLen: 1, actualLen: len(src)}
+ }
+
+ dst.TxStatus = src[0]
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *ReadyForQuery) Encode(dst []byte) []byte {
+ return append(dst, 'Z', 0, 0, 0, 5, src.TxStatus)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src ReadyForQuery) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ TxStatus string
+ }{
+ Type: "ReadyForQuery",
+ TxStatus: string(src.TxStatus),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *ReadyForQuery) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ TxStatus string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ if len(msg.TxStatus) != 1 {
+ return errors.New("invalid length for ReadyForQuery.TxStatus")
+ }
+ dst.TxStatus = msg.TxStatus[0]
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go b/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go
new file mode 100644
index 0000000000..6f6f06817d
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go
@@ -0,0 +1,165 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+const (
+ TextFormat = 0
+ BinaryFormat = 1
+)
+
+type FieldDescription struct {
+ Name []byte
+ TableOID uint32
+ TableAttributeNumber uint16
+ DataTypeOID uint32
+ DataTypeSize int16
+ TypeModifier int32
+ Format int16
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (fd FieldDescription) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Name string
+ TableOID uint32
+ TableAttributeNumber uint16
+ DataTypeOID uint32
+ DataTypeSize int16
+ TypeModifier int32
+ Format int16
+ }{
+ Name: string(fd.Name),
+ TableOID: fd.TableOID,
+ TableAttributeNumber: fd.TableAttributeNumber,
+ DataTypeOID: fd.DataTypeOID,
+ DataTypeSize: fd.DataTypeSize,
+ TypeModifier: fd.TypeModifier,
+ Format: fd.Format,
+ })
+}
+
+type RowDescription struct {
+ Fields []FieldDescription
+}
+
+// Backend identifies this message as sendable by the PostgreSQL backend.
+func (*RowDescription) Backend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *RowDescription) Decode(src []byte) error {
+
+ if len(src) < 2 {
+ return &invalidMessageFormatErr{messageType: "RowDescription"}
+ }
+ fieldCount := int(binary.BigEndian.Uint16(src))
+ rp := 2
+
+ dst.Fields = dst.Fields[0:0]
+
+ for i := 0; i < fieldCount; i++ {
+ var fd FieldDescription
+
+ idx := bytes.IndexByte(src[rp:], 0)
+ if idx < 0 {
+ return &invalidMessageFormatErr{messageType: "RowDescription"}
+ }
+ fd.Name = src[rp : rp+idx]
+ rp += idx + 1
+
+ // Since buf.Next() doesn't return an error if we hit the end of the buffer
+ // check Len ahead of time
+ if len(src[rp:]) < 18 {
+ return &invalidMessageFormatErr{messageType: "RowDescription"}
+ }
+
+ fd.TableOID = binary.BigEndian.Uint32(src[rp:])
+ rp += 4
+ fd.TableAttributeNumber = binary.BigEndian.Uint16(src[rp:])
+ rp += 2
+ fd.DataTypeOID = binary.BigEndian.Uint32(src[rp:])
+ rp += 4
+ fd.DataTypeSize = int16(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+ fd.TypeModifier = int32(binary.BigEndian.Uint32(src[rp:]))
+ rp += 4
+ fd.Format = int16(binary.BigEndian.Uint16(src[rp:]))
+ rp += 2
+
+ dst.Fields = append(dst.Fields, fd)
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *RowDescription) Encode(dst []byte) []byte {
+ dst = append(dst, 'T')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = pgio.AppendUint16(dst, uint16(len(src.Fields)))
+ for _, fd := range src.Fields {
+ dst = append(dst, fd.Name...)
+ dst = append(dst, 0)
+
+ dst = pgio.AppendUint32(dst, fd.TableOID)
+ dst = pgio.AppendUint16(dst, fd.TableAttributeNumber)
+ dst = pgio.AppendUint32(dst, fd.DataTypeOID)
+ dst = pgio.AppendInt16(dst, fd.DataTypeSize)
+ dst = pgio.AppendInt32(dst, fd.TypeModifier)
+ dst = pgio.AppendInt16(dst, fd.Format)
+ }
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src RowDescription) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Fields []FieldDescription
+ }{
+ Type: "RowDescription",
+ Fields: src.Fields,
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *RowDescription) UnmarshalJSON(data []byte) error {
+ var msg struct {
+ Fields []struct {
+ Name string
+ TableOID uint32
+ TableAttributeNumber uint16
+ DataTypeOID uint32
+ DataTypeSize int16
+ TypeModifier int32
+ Format int16
+ }
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ dst.Fields = make([]FieldDescription, len(msg.Fields))
+ for n, field := range msg.Fields {
+ dst.Fields[n] = FieldDescription{
+ Name: []byte(field.Name),
+ TableOID: field.TableOID,
+ TableAttributeNumber: field.TableAttributeNumber,
+ DataTypeOID: field.DataTypeOID,
+ DataTypeSize: field.DataTypeSize,
+ TypeModifier: field.TypeModifier,
+ Format: field.Format,
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go
new file mode 100644
index 0000000000..eeda4691ab
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go
@@ -0,0 +1,94 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type SASLInitialResponse struct {
+ AuthMechanism string
+ Data []byte
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*SASLInitialResponse) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *SASLInitialResponse) Decode(src []byte) error {
+ *dst = SASLInitialResponse{}
+
+ rp := 0
+
+ idx := bytes.IndexByte(src, 0)
+ if idx < 0 {
+ return errors.New("invalid SASLInitialResponse")
+ }
+
+ dst.AuthMechanism = string(src[rp:idx])
+ rp = idx + 1
+
+ rp += 4 // The rest of the message is data so we can just skip the size
+ dst.Data = src[rp:]
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *SASLInitialResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'p')
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = append(dst, []byte(src.AuthMechanism)...)
+ dst = append(dst, 0)
+
+ dst = pgio.AppendInt32(dst, int32(len(src.Data)))
+ dst = append(dst, src.Data...)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src SASLInitialResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ AuthMechanism string
+ Data string
+ }{
+ Type: "SASLInitialResponse",
+ AuthMechanism: src.AuthMechanism,
+ Data: string(src.Data),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *SASLInitialResponse) UnmarshalJSON(data []byte) error {
+ // Ignore null, like in the main JSON package.
+ if string(data) == "null" {
+ return nil
+ }
+
+ var msg struct {
+ AuthMechanism string
+ Data string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ dst.AuthMechanism = msg.AuthMechanism
+ if msg.Data != "" {
+ decoded, err := hex.DecodeString(msg.Data)
+ if err != nil {
+ return err
+ }
+ dst.Data = decoded
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go
new file mode 100644
index 0000000000..54c3d96f32
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go
@@ -0,0 +1,61 @@
+package pgproto3
+
+import (
+ "encoding/hex"
+ "encoding/json"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+type SASLResponse struct {
+ Data []byte
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*SASLResponse) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *SASLResponse) Decode(src []byte) error {
+ *dst = SASLResponse{Data: src}
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *SASLResponse) Encode(dst []byte) []byte {
+ dst = append(dst, 'p')
+ dst = pgio.AppendInt32(dst, int32(4+len(src.Data)))
+
+ dst = append(dst, src.Data...)
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src SASLResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ Data string
+ }{
+ Type: "SASLResponse",
+ Data: string(src.Data),
+ })
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler.
+func (dst *SASLResponse) UnmarshalJSON(data []byte) error {
+ var msg struct {
+ Data string
+ }
+ if err := json.Unmarshal(data, &msg); err != nil {
+ return err
+ }
+ if msg.Data != "" {
+ decoded, err := hex.DecodeString(msg.Data)
+ if err != nil {
+ return err
+ }
+ dst.Data = decoded
+ }
+ return nil
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go
new file mode 100644
index 0000000000..1b00c16b39
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go
@@ -0,0 +1,49 @@
+package pgproto3
+
+import (
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+const sslRequestNumber = 80877103
+
+type SSLRequest struct {
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*SSLRequest) Frontend() {}
+
+func (dst *SSLRequest) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("ssl request too short")
+ }
+
+ requestCode := binary.BigEndian.Uint32(src)
+
+ if requestCode != sslRequestNumber {
+ return errors.New("bad ssl request code")
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 4 byte message length.
+func (src *SSLRequest) Encode(dst []byte) []byte {
+ dst = pgio.AppendInt32(dst, 8)
+ dst = pgio.AppendInt32(dst, sslRequestNumber)
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src SSLRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ProtocolVersion uint32
+ Parameters map[string]string
+ }{
+ Type: "SSLRequest",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go b/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go
new file mode 100644
index 0000000000..5c974f02ab
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go
@@ -0,0 +1,96 @@
+package pgproto3
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "github.com/jackc/pgx/v5/internal/pgio"
+)
+
+const ProtocolVersionNumber = 196608 // 3.0
+
+type StartupMessage struct {
+ ProtocolVersion uint32
+ Parameters map[string]string
+}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*StartupMessage) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *StartupMessage) Decode(src []byte) error {
+ if len(src) < 4 {
+ return errors.New("startup message too short")
+ }
+
+ dst.ProtocolVersion = binary.BigEndian.Uint32(src)
+ rp := 4
+
+ if dst.ProtocolVersion != ProtocolVersionNumber {
+ return fmt.Errorf("Bad startup message version number. Expected %d, got %d", ProtocolVersionNumber, dst.ProtocolVersion)
+ }
+
+ dst.Parameters = make(map[string]string)
+ for {
+ idx := bytes.IndexByte(src[rp:], 0)
+ if idx < 0 {
+ return &invalidMessageFormatErr{messageType: "StartupMesage"}
+ }
+ key := string(src[rp : rp+idx])
+ rp += idx + 1
+
+ idx = bytes.IndexByte(src[rp:], 0)
+ if idx < 0 {
+ return &invalidMessageFormatErr{messageType: "StartupMesage"}
+ }
+ value := string(src[rp : rp+idx])
+ rp += idx + 1
+
+ dst.Parameters[key] = value
+
+ if len(src[rp:]) == 1 {
+ if src[rp] != 0 {
+ return fmt.Errorf("Bad startup message last byte. Expected 0, got %d", src[rp])
+ }
+ break
+ }
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *StartupMessage) Encode(dst []byte) []byte {
+ sp := len(dst)
+ dst = pgio.AppendInt32(dst, -1)
+
+ dst = pgio.AppendUint32(dst, src.ProtocolVersion)
+ for k, v := range src.Parameters {
+ dst = append(dst, k...)
+ dst = append(dst, 0)
+ dst = append(dst, v...)
+ dst = append(dst, 0)
+ }
+ dst = append(dst, 0)
+
+ pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
+
+ return dst
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src StartupMessage) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ ProtocolVersion uint32
+ Parameters map[string]string
+ }{
+ Type: "StartupMessage",
+ ProtocolVersion: src.ProtocolVersion,
+ Parameters: src.Parameters,
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go
new file mode 100644
index 0000000000..5db8e07ac1
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type Sync struct{}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Sync) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Sync) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "Sync", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Sync) Encode(dst []byte) []byte {
+ return append(dst, 'S', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Sync) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "Sync",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go b/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go
new file mode 100644
index 0000000000..135191eaee
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go
@@ -0,0 +1,34 @@
+package pgproto3
+
+import (
+ "encoding/json"
+)
+
+type Terminate struct{}
+
+// Frontend identifies this message as sendable by a PostgreSQL frontend.
+func (*Terminate) Frontend() {}
+
+// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
+// type identifier and 4 byte message length.
+func (dst *Terminate) Decode(src []byte) error {
+ if len(src) != 0 {
+ return &invalidMessageLenErr{messageType: "Terminate", expectedLen: 0, actualLen: len(src)}
+ }
+
+ return nil
+}
+
+// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
+func (src *Terminate) Encode(dst []byte) []byte {
+ return append(dst, 'X', 0, 0, 0, 4)
+}
+
+// MarshalJSON implements encoding/json.Marshaler.
+func (src Terminate) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type string
+ }{
+ Type: "Terminate",
+ })
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6 b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6
new file mode 100644
index 0000000000..d1c612d356
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/39c5e864da4707fc15fea48f7062d6a07796fdc43b33e0ba9dbd7074a0211fa6
@@ -0,0 +1,4 @@
+go test fuzz v1
+byte('A')
+uint32(5)
+[]byte("0")
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7 b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7
new file mode 100644
index 0000000000..763b70ae46
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/9b06792b1aaac8a907dbfa04d526ae14326c8573b7409032caac8461e83065f7
@@ -0,0 +1,4 @@
+go test fuzz v1
+byte('D')
+uint32(21)
+[]byte("00\xb300000000000000")
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214 b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214
new file mode 100644
index 0000000000..3d995c2812
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/a661fb98e802839f0a7361160fbc6e28794612a411d00bde104364ee281c4214
@@ -0,0 +1,4 @@
+go test fuzz v1
+byte('C')
+uint32(4)
+[]byte("0")
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4 b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4
new file mode 100644
index 0000000000..45f0ba8178
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/testdata/fuzz/FuzzFrontend/fc98dcd487a5173b38763a5f7dd023933f3a86ab566e3f2b091eb36248107eb4
@@ -0,0 +1,4 @@
+go test fuzz v1
+byte('R')
+uint32(13)
+[]byte("\x00\x00\x00\n0\x12\xebG\x8dI']G\xdac\x95\xb7\x18\xb0\x02\xe8m\xc2\x00\xef\x03\x12\x1b\xbdj\x10\x9f\xf9\xeb\xb8")
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go b/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go
new file mode 100644
index 0000000000..c09f68d1a6
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go
@@ -0,0 +1,440 @@
+package pgproto3
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// tracer traces the messages send to and from a Backend or Frontend. The format it produces roughly mimics the
+// format produced by the libpq C function PQtrace.
+type tracer struct {
+ w io.Writer
+ buf *bytes.Buffer
+ TracerOptions
+}
+
+// TracerOptions controls tracing behavior. It is roughly equivalent to the libpq function PQsetTraceFlags.
+type TracerOptions struct {
+ // SuppressTimestamps prevents printing of timestamps.
+ SuppressTimestamps bool
+
+ // RegressMode redacts fields that may be vary between executions.
+ RegressMode bool
+}
+
+func (t *tracer) traceMessage(sender byte, encodedLen int32, msg Message) {
+ switch msg := msg.(type) {
+ case *AuthenticationCleartextPassword:
+ t.traceAuthenticationCleartextPassword(sender, encodedLen, msg)
+ case *AuthenticationGSS:
+ t.traceAuthenticationGSS(sender, encodedLen, msg)
+ case *AuthenticationGSSContinue:
+ t.traceAuthenticationGSSContinue(sender, encodedLen, msg)
+ case *AuthenticationMD5Password:
+ t.traceAuthenticationMD5Password(sender, encodedLen, msg)
+ case *AuthenticationOk:
+ t.traceAuthenticationOk(sender, encodedLen, msg)
+ case *AuthenticationSASL:
+ t.traceAuthenticationSASL(sender, encodedLen, msg)
+ case *AuthenticationSASLContinue:
+ t.traceAuthenticationSASLContinue(sender, encodedLen, msg)
+ case *AuthenticationSASLFinal:
+ t.traceAuthenticationSASLFinal(sender, encodedLen, msg)
+ case *BackendKeyData:
+ t.traceBackendKeyData(sender, encodedLen, msg)
+ case *Bind:
+ t.traceBind(sender, encodedLen, msg)
+ case *BindComplete:
+ t.traceBindComplete(sender, encodedLen, msg)
+ case *CancelRequest:
+ t.traceCancelRequest(sender, encodedLen, msg)
+ case *Close:
+ t.traceClose(sender, encodedLen, msg)
+ case *CloseComplete:
+ t.traceCloseComplete(sender, encodedLen, msg)
+ case *CommandComplete:
+ t.traceCommandComplete(sender, encodedLen, msg)
+ case *CopyBothResponse:
+ t.traceCopyBothResponse(sender, encodedLen, msg)
+ case *CopyData:
+ t.traceCopyData(sender, encodedLen, msg)
+ case *CopyDone:
+ t.traceCopyDone(sender, encodedLen, msg)
+ case *CopyFail:
+ t.traceCopyFail(sender, encodedLen, msg)
+ case *CopyInResponse:
+ t.traceCopyInResponse(sender, encodedLen, msg)
+ case *CopyOutResponse:
+ t.traceCopyOutResponse(sender, encodedLen, msg)
+ case *DataRow:
+ t.traceDataRow(sender, encodedLen, msg)
+ case *Describe:
+ t.traceDescribe(sender, encodedLen, msg)
+ case *EmptyQueryResponse:
+ t.traceEmptyQueryResponse(sender, encodedLen, msg)
+ case *ErrorResponse:
+ t.traceErrorResponse(sender, encodedLen, msg)
+ case *Execute:
+ t.TraceQueryute(sender, encodedLen, msg)
+ case *Flush:
+ t.traceFlush(sender, encodedLen, msg)
+ case *FunctionCall:
+ t.traceFunctionCall(sender, encodedLen, msg)
+ case *FunctionCallResponse:
+ t.traceFunctionCallResponse(sender, encodedLen, msg)
+ case *GSSEncRequest:
+ t.traceGSSEncRequest(sender, encodedLen, msg)
+ case *NoData:
+ t.traceNoData(sender, encodedLen, msg)
+ case *NoticeResponse:
+ t.traceNoticeResponse(sender, encodedLen, msg)
+ case *NotificationResponse:
+ t.traceNotificationResponse(sender, encodedLen, msg)
+ case *ParameterDescription:
+ t.traceParameterDescription(sender, encodedLen, msg)
+ case *ParameterStatus:
+ t.traceParameterStatus(sender, encodedLen, msg)
+ case *Parse:
+ t.traceParse(sender, encodedLen, msg)
+ case *ParseComplete:
+ t.traceParseComplete(sender, encodedLen, msg)
+ case *PortalSuspended:
+ t.tracePortalSuspended(sender, encodedLen, msg)
+ case *Query:
+ t.traceQuery(sender, encodedLen, msg)
+ case *ReadyForQuery:
+ t.traceReadyForQuery(sender, encodedLen, msg)
+ case *RowDescription:
+ t.traceRowDescription(sender, encodedLen, msg)
+ case *SSLRequest:
+ t.traceSSLRequest(sender, encodedLen, msg)
+ case *StartupMessage:
+ t.traceStartupMessage(sender, encodedLen, msg)
+ case *Sync:
+ t.traceSync(sender, encodedLen, msg)
+ case *Terminate:
+ t.traceTerminate(sender, encodedLen, msg)
+ default:
+ t.beginTrace(sender, encodedLen, "Unknown")
+ t.finishTrace()
+ }
+}
+
+func (t *tracer) traceAuthenticationCleartextPassword(sender byte, encodedLen int32, msg *AuthenticationCleartextPassword) {
+ t.beginTrace(sender, encodedLen, "AuthenticationCleartextPassword")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationGSS(sender byte, encodedLen int32, msg *AuthenticationGSS) {
+ t.beginTrace(sender, encodedLen, "AuthenticationGSS")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationGSSContinue(sender byte, encodedLen int32, msg *AuthenticationGSSContinue) {
+ t.beginTrace(sender, encodedLen, "AuthenticationGSSContinue")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationMD5Password(sender byte, encodedLen int32, msg *AuthenticationMD5Password) {
+ t.beginTrace(sender, encodedLen, "AuthenticationMD5Password")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationOk(sender byte, encodedLen int32, msg *AuthenticationOk) {
+ t.beginTrace(sender, encodedLen, "AuthenticationOk")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationSASL(sender byte, encodedLen int32, msg *AuthenticationSASL) {
+ t.beginTrace(sender, encodedLen, "AuthenticationSASL")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationSASLContinue(sender byte, encodedLen int32, msg *AuthenticationSASLContinue) {
+ t.beginTrace(sender, encodedLen, "AuthenticationSASLContinue")
+ t.finishTrace()
+}
+
+func (t *tracer) traceAuthenticationSASLFinal(sender byte, encodedLen int32, msg *AuthenticationSASLFinal) {
+ t.beginTrace(sender, encodedLen, "AuthenticationSASLFinal")
+ t.finishTrace()
+}
+
+func (t *tracer) traceBackendKeyData(sender byte, encodedLen int32, msg *BackendKeyData) {
+ t.beginTrace(sender, encodedLen, "BackendKeyData")
+ if t.RegressMode {
+ t.buf.WriteString("\t NNNN NNNN")
+ } else {
+ fmt.Fprintf(t.buf, "\t %d %d", msg.ProcessID, msg.SecretKey)
+ }
+ t.finishTrace()
+}
+
+func (t *tracer) traceBind(sender byte, encodedLen int32, msg *Bind) {
+ t.beginTrace(sender, encodedLen, "Bind")
+ fmt.Fprintf(t.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(msg.DestinationPortal)), traceDoubleQuotedString([]byte(msg.PreparedStatement)), len(msg.ParameterFormatCodes))
+ for _, fc := range msg.ParameterFormatCodes {
+ fmt.Fprintf(t.buf, " %d", fc)
+ }
+ fmt.Fprintf(t.buf, " %d", len(msg.Parameters))
+ for _, p := range msg.Parameters {
+ fmt.Fprintf(t.buf, " %s", traceSingleQuotedString(p))
+ }
+ fmt.Fprintf(t.buf, " %d", len(msg.ResultFormatCodes))
+ for _, fc := range msg.ResultFormatCodes {
+ fmt.Fprintf(t.buf, " %d", fc)
+ }
+ t.finishTrace()
+}
+
+func (t *tracer) traceBindComplete(sender byte, encodedLen int32, msg *BindComplete) {
+ t.beginTrace(sender, encodedLen, "BindComplete")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCancelRequest(sender byte, encodedLen int32, msg *CancelRequest) {
+ t.beginTrace(sender, encodedLen, "CancelRequest")
+ t.finishTrace()
+}
+
+func (t *tracer) traceClose(sender byte, encodedLen int32, msg *Close) {
+ t.beginTrace(sender, encodedLen, "Close")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCloseComplete(sender byte, encodedLen int32, msg *CloseComplete) {
+ t.beginTrace(sender, encodedLen, "CloseComplete")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCommandComplete(sender byte, encodedLen int32, msg *CommandComplete) {
+ t.beginTrace(sender, encodedLen, "CommandComplete")
+ fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString(msg.CommandTag))
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyBothResponse(sender byte, encodedLen int32, msg *CopyBothResponse) {
+ t.beginTrace(sender, encodedLen, "CopyBothResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyData(sender byte, encodedLen int32, msg *CopyData) {
+ t.beginTrace(sender, encodedLen, "CopyData")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyDone(sender byte, encodedLen int32, msg *CopyDone) {
+ t.beginTrace(sender, encodedLen, "CopyDone")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyFail(sender byte, encodedLen int32, msg *CopyFail) {
+ t.beginTrace(sender, encodedLen, "CopyFail")
+ fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString([]byte(msg.Message)))
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyInResponse(sender byte, encodedLen int32, msg *CopyInResponse) {
+ t.beginTrace(sender, encodedLen, "CopyInResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceCopyOutResponse(sender byte, encodedLen int32, msg *CopyOutResponse) {
+ t.beginTrace(sender, encodedLen, "CopyOutResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceDataRow(sender byte, encodedLen int32, msg *DataRow) {
+ t.beginTrace(sender, encodedLen, "DataRow")
+ fmt.Fprintf(t.buf, "\t %d", len(msg.Values))
+ for _, v := range msg.Values {
+ if v == nil {
+ t.buf.WriteString(" -1")
+ } else {
+ fmt.Fprintf(t.buf, " %d %s", len(v), traceSingleQuotedString(v))
+ }
+ }
+ t.finishTrace()
+}
+
+func (t *tracer) traceDescribe(sender byte, encodedLen int32, msg *Describe) {
+ t.beginTrace(sender, encodedLen, "Describe")
+ fmt.Fprintf(t.buf, "\t %c %s", msg.ObjectType, traceDoubleQuotedString([]byte(msg.Name)))
+ t.finishTrace()
+}
+
+func (t *tracer) traceEmptyQueryResponse(sender byte, encodedLen int32, msg *EmptyQueryResponse) {
+ t.beginTrace(sender, encodedLen, "EmptyQueryResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceErrorResponse(sender byte, encodedLen int32, msg *ErrorResponse) {
+ t.beginTrace(sender, encodedLen, "ErrorResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) TraceQueryute(sender byte, encodedLen int32, msg *Execute) {
+ t.beginTrace(sender, encodedLen, "Execute")
+ fmt.Fprintf(t.buf, "\t %s %d", traceDoubleQuotedString([]byte(msg.Portal)), msg.MaxRows)
+ t.finishTrace()
+}
+
+func (t *tracer) traceFlush(sender byte, encodedLen int32, msg *Flush) {
+ t.beginTrace(sender, encodedLen, "Flush")
+ t.finishTrace()
+}
+
+func (t *tracer) traceFunctionCall(sender byte, encodedLen int32, msg *FunctionCall) {
+ t.beginTrace(sender, encodedLen, "FunctionCall")
+ t.finishTrace()
+}
+
+func (t *tracer) traceFunctionCallResponse(sender byte, encodedLen int32, msg *FunctionCallResponse) {
+ t.beginTrace(sender, encodedLen, "FunctionCallResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceGSSEncRequest(sender byte, encodedLen int32, msg *GSSEncRequest) {
+ t.beginTrace(sender, encodedLen, "GSSEncRequest")
+ t.finishTrace()
+}
+
+func (t *tracer) traceNoData(sender byte, encodedLen int32, msg *NoData) {
+ t.beginTrace(sender, encodedLen, "NoData")
+ t.finishTrace()
+}
+
+func (t *tracer) traceNoticeResponse(sender byte, encodedLen int32, msg *NoticeResponse) {
+ t.beginTrace(sender, encodedLen, "NoticeResponse")
+ t.finishTrace()
+}
+
+func (t *tracer) traceNotificationResponse(sender byte, encodedLen int32, msg *NotificationResponse) {
+ t.beginTrace(sender, encodedLen, "NotificationResponse")
+ fmt.Fprintf(t.buf, "\t %d %s %s", msg.PID, traceDoubleQuotedString([]byte(msg.Channel)), traceDoubleQuotedString([]byte(msg.Payload)))
+ t.finishTrace()
+}
+
+func (t *tracer) traceParameterDescription(sender byte, encodedLen int32, msg *ParameterDescription) {
+ t.beginTrace(sender, encodedLen, "ParameterDescription")
+ t.finishTrace()
+}
+
+func (t *tracer) traceParameterStatus(sender byte, encodedLen int32, msg *ParameterStatus) {
+ t.beginTrace(sender, encodedLen, "ParameterStatus")
+ fmt.Fprintf(t.buf, "\t %s %s", traceDoubleQuotedString([]byte(msg.Name)), traceDoubleQuotedString([]byte(msg.Value)))
+ t.finishTrace()
+}
+
+func (t *tracer) traceParse(sender byte, encodedLen int32, msg *Parse) {
+ t.beginTrace(sender, encodedLen, "Parse")
+ fmt.Fprintf(t.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(msg.Name)), traceDoubleQuotedString([]byte(msg.Query)), len(msg.ParameterOIDs))
+ for _, oid := range msg.ParameterOIDs {
+ fmt.Fprintf(t.buf, " %d", oid)
+ }
+ t.finishTrace()
+}
+
+func (t *tracer) traceParseComplete(sender byte, encodedLen int32, msg *ParseComplete) {
+ t.beginTrace(sender, encodedLen, "ParseComplete")
+ t.finishTrace()
+}
+
+func (t *tracer) tracePortalSuspended(sender byte, encodedLen int32, msg *PortalSuspended) {
+ t.beginTrace(sender, encodedLen, "PortalSuspended")
+ t.finishTrace()
+}
+
+func (t *tracer) traceQuery(sender byte, encodedLen int32, msg *Query) {
+ t.beginTrace(sender, encodedLen, "Query")
+ fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString([]byte(msg.String)))
+ t.finishTrace()
+}
+
+func (t *tracer) traceReadyForQuery(sender byte, encodedLen int32, msg *ReadyForQuery) {
+ t.beginTrace(sender, encodedLen, "ReadyForQuery")
+ fmt.Fprintf(t.buf, "\t %c", msg.TxStatus)
+ t.finishTrace()
+}
+
+func (t *tracer) traceRowDescription(sender byte, encodedLen int32, msg *RowDescription) {
+ t.beginTrace(sender, encodedLen, "RowDescription")
+ fmt.Fprintf(t.buf, "\t %d", len(msg.Fields))
+ for _, fd := range msg.Fields {
+ fmt.Fprintf(t.buf, ` %s %d %d %d %d %d %d`, traceDoubleQuotedString(fd.Name), fd.TableOID, fd.TableAttributeNumber, fd.DataTypeOID, fd.DataTypeSize, fd.TypeModifier, fd.Format)
+ }
+ t.finishTrace()
+}
+
+func (t *tracer) traceSSLRequest(sender byte, encodedLen int32, msg *SSLRequest) {
+ t.beginTrace(sender, encodedLen, "SSLRequest")
+ t.finishTrace()
+}
+
+func (t *tracer) traceStartupMessage(sender byte, encodedLen int32, msg *StartupMessage) {
+ t.beginTrace(sender, encodedLen, "StartupMessage")
+ t.finishTrace()
+}
+
+func (t *tracer) traceSync(sender byte, encodedLen int32, msg *Sync) {
+ t.beginTrace(sender, encodedLen, "Sync")
+ t.finishTrace()
+}
+
+func (t *tracer) traceTerminate(sender byte, encodedLen int32, msg *Terminate) {
+ t.beginTrace(sender, encodedLen, "Terminate")
+ t.finishTrace()
+}
+
+func (t *tracer) beginTrace(sender byte, encodedLen int32, msgType string) {
+ if !t.SuppressTimestamps {
+ now := time.Now()
+ t.buf.WriteString(now.Format("2006-01-02 15:04:05.000000"))
+ t.buf.WriteByte('\t')
+ }
+
+ t.buf.WriteByte(sender)
+ t.buf.WriteByte('\t')
+ t.buf.WriteString(msgType)
+ t.buf.WriteByte('\t')
+ t.buf.WriteString(strconv.FormatInt(int64(encodedLen), 10))
+}
+
+func (t *tracer) finishTrace() {
+ t.buf.WriteByte('\n')
+ t.buf.WriteTo(t.w)
+
+ if t.buf.Cap() > 1024 {
+ t.buf = &bytes.Buffer{}
+ } else {
+ t.buf.Reset()
+ }
+}
+
+// traceDoubleQuotedString returns t.buf as a double-quoted string without any escaping. It is roughly equivalent to
+// pqTraceOutputString in libpq.
+func traceDoubleQuotedString(buf []byte) string {
+ return `"` + string(buf) + `"`
+}
+
+// traceSingleQuotedString returns buf as a single-quoted string with non-printable characters hex-escaped. It is
+// roughly equivalent to pqTraceOutputNchar in libpq.
+func traceSingleQuotedString(buf []byte) string {
+ sb := &strings.Builder{}
+
+ sb.WriteByte('\'')
+ for _, b := range buf {
+ if b < 32 || b > 126 {
+ fmt.Fprintf(sb, `\x%x`, b)
+ } else {
+ sb.WriteByte(b)
+ }
+ }
+ sb.WriteByte('\'')
+
+ return sb.String()
+}
diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/ya.make b/vendor/github.com/jackc/pgx/v5/pgproto3/ya.make
new file mode 100644
index 0000000000..24dc8df40d
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgproto3/ya.make
@@ -0,0 +1,83 @@
+GO_LIBRARY()
+
+LICENSE(MIT)
+
+SRCS(
+ authentication_cleartext_password.go
+ authentication_gss.go
+ authentication_gss_continue.go
+ authentication_md5_password.go
+ authentication_ok.go
+ authentication_sasl.go
+ authentication_sasl_continue.go
+ authentication_sasl_final.go
+ backend.go
+ backend_key_data.go
+ big_endian.go
+ bind.go
+ bind_complete.go
+ cancel_request.go
+ chunkreader.go
+ close.go
+ close_complete.go
+ command_complete.go
+ copy_both_response.go
+ copy_data.go
+ copy_done.go
+ copy_fail.go
+ copy_in_response.go
+ copy_out_response.go
+ data_row.go
+ describe.go
+ doc.go
+ empty_query_response.go
+ error_response.go
+ execute.go
+ flush.go
+ frontend.go
+ function_call.go
+ function_call_response.go
+ gss_enc_request.go
+ gss_response.go
+ no_data.go
+ notice_response.go
+ notification_response.go
+ parameter_description.go
+ parameter_status.go
+ parse.go
+ parse_complete.go
+ password_message.go
+ pgproto3.go
+ portal_suspended.go
+ query.go
+ ready_for_query.go
+ row_description.go
+ sasl_initial_response.go
+ sasl_response.go
+ ssl_request.go
+ startup_message.go
+ sync.go
+ terminate.go
+ trace.go
+)
+
+GO_TEST_SRCS(
+ chunkreader_test.go
+ function_call_test.go
+ json_test.go
+)
+
+GO_XTEST_SRCS(
+ # backend_test.go # same test in pgproto3 and pgproto3_test
+ copy_both_response_test.go
+ # frontend_test.go # same test in pgproto3 and pgproto3_test
+ fuzz_test.go
+ # trace_test.go # st/YMAKE-102
+)
+
+END()
+
+RECURSE(
+ example
+ gotest
+)