mirror of
https://github.com/jackc/pgx.git
synced 2025-05-30 19:22:19 +00:00
CopyFrom requires that all values are encoded in the binary format. It already tried to parse strings to values that can then be encoded into the binary format. But it didn't handle types that can be encoded as text and then parsed and converted to binary. It now does.
73 lines
1.5 KiB
Go
73 lines
1.5 KiB
Go
package pgx
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5/internal/anynil"
|
|
"github.com/jackc/pgx/v5/internal/pgio"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
// PostgreSQL format codes
|
|
const (
|
|
TextFormatCode = 0
|
|
BinaryFormatCode = 1
|
|
)
|
|
|
|
func convertSimpleArgument(m *pgtype.Map, arg any) (any, error) {
|
|
if anynil.Is(arg) {
|
|
return nil, nil
|
|
}
|
|
|
|
buf, err := m.Encode(0, TextFormatCode, arg, []byte{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if buf == nil {
|
|
return nil, nil
|
|
}
|
|
return string(buf), nil
|
|
}
|
|
|
|
func encodeCopyValue(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) {
|
|
if anynil.Is(arg) {
|
|
return pgio.AppendInt32(buf, -1), nil
|
|
}
|
|
|
|
sp := len(buf)
|
|
buf = pgio.AppendInt32(buf, -1)
|
|
argBuf, err := m.Encode(oid, BinaryFormatCode, arg, buf)
|
|
if err != nil {
|
|
if argBuf2, err2 := tryScanStringCopyValueThenEncode(m, buf, oid, arg); err2 == nil {
|
|
argBuf = argBuf2
|
|
} else {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if argBuf != nil {
|
|
buf = argBuf
|
|
pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
|
|
}
|
|
return buf, nil
|
|
}
|
|
|
|
func tryScanStringCopyValueThenEncode(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) {
|
|
s, ok := arg.(string)
|
|
if !ok {
|
|
textBuf, err := m.Encode(oid, TextFormatCode, arg, nil)
|
|
if err != nil {
|
|
return nil, errors.New("not a string and cannot be encoded as text")
|
|
}
|
|
s = string(textBuf)
|
|
}
|
|
|
|
var v any
|
|
err := m.Scan(oid, TextFormatCode, []byte(s), &v)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return m.Encode(oid, BinaryFormatCode, v, buf)
|
|
}
|