1 package pgx
2
3 import (
4 "errors"
5
6 "github.com/jackc/pgx/v5/internal/anynil"
7 "github.com/jackc/pgx/v5/internal/pgio"
8 "github.com/jackc/pgx/v5/pgtype"
9 )
10
11
12 const (
13 TextFormatCode = 0
14 BinaryFormatCode = 1
15 )
16
17 func convertSimpleArgument(m *pgtype.Map, arg any) (any, error) {
18 if anynil.Is(arg) {
19 return nil, nil
20 }
21
22 buf, err := m.Encode(0, TextFormatCode, arg, []byte{})
23 if err != nil {
24 return nil, err
25 }
26 if buf == nil {
27 return nil, nil
28 }
29 return string(buf), nil
30 }
31
32 func encodeCopyValue(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) {
33 if anynil.Is(arg) {
34 return pgio.AppendInt32(buf, -1), nil
35 }
36
37 sp := len(buf)
38 buf = pgio.AppendInt32(buf, -1)
39 argBuf, err := m.Encode(oid, BinaryFormatCode, arg, buf)
40 if err != nil {
41 if argBuf2, err2 := tryScanStringCopyValueThenEncode(m, buf, oid, arg); err2 == nil {
42 argBuf = argBuf2
43 } else {
44 return nil, err
45 }
46 }
47
48 if argBuf != nil {
49 buf = argBuf
50 pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4))
51 }
52 return buf, nil
53 }
54
55 func tryScanStringCopyValueThenEncode(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) {
56 s, ok := arg.(string)
57 if !ok {
58 textBuf, err := m.Encode(oid, TextFormatCode, arg, nil)
59 if err != nil {
60 return nil, errors.New("not a string and cannot be encoded as text")
61 }
62 s = string(textBuf)
63 }
64
65 var v any
66 err := m.Scan(oid, TextFormatCode, []byte(s), &v)
67 if err != nil {
68 return nil, err
69 }
70
71 return m.Encode(oid, BinaryFormatCode, v, buf)
72 }
73
View as plain text