summaryrefslogtreecommitdiff
path: root/vendor/github.com/jackc/pgx/v5/pgtype
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jackc/pgx/v5/pgtype')
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/doc.go3
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/interval.go32
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/json.go9
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go44
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go3
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/time.go8
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/uint32.go22
-rw-r--r--vendor/github.com/jackc/pgx/v5/pgtype/xml.go198
8 files changed, 285 insertions, 34 deletions
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/doc.go b/vendor/github.com/jackc/pgx/v5/pgtype/doc.go
index d56c1dc70..7687ea8fe 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/doc.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/doc.go
@@ -53,6 +53,9 @@ similar fashion to database/sql. The second is to use a pointer to a pointer.
return err
}
+When using nullable pgtype types as parameters for queries, one has to remember
+to explicitly set their Valid field to true, otherwise the parameter's value will be NULL.
+
JSON Support
pgtype automatically marshals and unmarshals data from json and jsonb PostgreSQL types.
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/interval.go b/vendor/github.com/jackc/pgx/v5/pgtype/interval.go
index 06703d4dc..4b5116295 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/interval.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/interval.go
@@ -132,29 +132,25 @@ func (encodePlanIntervalCodecText) Encode(value any, buf []byte) (newBuf []byte,
if interval.Days != 0 {
buf = append(buf, strconv.FormatInt(int64(interval.Days), 10)...)
- buf = append(buf, " day"...)
+ buf = append(buf, " day "...)
}
- if interval.Microseconds != 0 {
- buf = append(buf, " "...)
-
- absMicroseconds := interval.Microseconds
- if absMicroseconds < 0 {
- absMicroseconds = -absMicroseconds
- buf = append(buf, '-')
- }
+ absMicroseconds := interval.Microseconds
+ if absMicroseconds < 0 {
+ absMicroseconds = -absMicroseconds
+ buf = append(buf, '-')
+ }
- hours := absMicroseconds / microsecondsPerHour
- minutes := (absMicroseconds % microsecondsPerHour) / microsecondsPerMinute
- seconds := (absMicroseconds % microsecondsPerMinute) / microsecondsPerSecond
+ hours := absMicroseconds / microsecondsPerHour
+ minutes := (absMicroseconds % microsecondsPerHour) / microsecondsPerMinute
+ seconds := (absMicroseconds % microsecondsPerMinute) / microsecondsPerSecond
- timeStr := fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
- buf = append(buf, timeStr...)
+ timeStr := fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
+ buf = append(buf, timeStr...)
- microseconds := absMicroseconds % microsecondsPerSecond
- if microseconds != 0 {
- buf = append(buf, fmt.Sprintf(".%06d", microseconds)...)
- }
+ microseconds := absMicroseconds % microsecondsPerSecond
+ if microseconds != 0 {
+ buf = append(buf, fmt.Sprintf(".%06d", microseconds)...)
}
return buf, nil
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/json.go b/vendor/github.com/jackc/pgx/v5/pgtype/json.go
index e71dcb9bf..c2aa0d3bf 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/json.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/json.go
@@ -37,7 +37,7 @@ func (c *JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value any) Enco
//
// https://github.com/jackc/pgx/issues/1430
//
- // Check for driver.Valuer must come before json.Marshaler so that it is guaranteed to beused
+ // Check for driver.Valuer must come before json.Marshaler so that it is guaranteed to be used
// when both are implemented https://github.com/jackc/pgx/issues/1805
case driver.Valuer:
return &encodePlanDriverValuer{m: m, oid: oid, formatCode: format}
@@ -177,13 +177,6 @@ func (scanPlanJSONToByteSlice) Scan(src []byte, dst any) error {
return nil
}
-type scanPlanJSONToBytesScanner struct{}
-
-func (scanPlanJSONToBytesScanner) Scan(src []byte, dst any) error {
- scanner := (dst).(BytesScanner)
- return scanner.ScanBytes(src)
-}
-
type scanPlanJSONToJSONUnmarshal struct {
unmarshal func(data []byte, v any) error
}
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go
index 408295683..bdd9f05ca 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go
@@ -26,6 +26,8 @@ const (
XIDOID = 28
CIDOID = 29
JSONOID = 114
+ XMLOID = 142
+ XMLArrayOID = 143
JSONArrayOID = 199
PointOID = 600
LsegOID = 601
@@ -214,6 +216,15 @@ type Map struct {
TryWrapScanPlanFuncs []TryWrapScanPlanFunc
}
+// Copy returns a new Map containing the same registered types.
+func (m *Map) Copy() *Map {
+ newMap := NewMap()
+ for _, type_ := range m.oidToType {
+ newMap.RegisterType(type_)
+ }
+ return newMap
+}
+
func NewMap() *Map {
defaultMapInitOnce.Do(initDefaultMap)
@@ -248,6 +259,13 @@ func NewMap() *Map {
}
}
+// RegisterTypes registers multiple data types in the sequence they are provided.
+func (m *Map) RegisterTypes(types []*Type) {
+ for _, t := range types {
+ m.RegisterType(t)
+ }
+}
+
// RegisterType registers a data type with the Map. t must not be mutated after it is registered.
func (m *Map) RegisterType(t *Type) {
m.oidToType[t.OID] = t
@@ -555,17 +573,24 @@ func TryFindUnderlyingTypeScanPlan(dst any) (plan WrappedScanPlanNextSetter, nex
elemValue = dstValue.Elem()
}
nextDstType := elemKindToPointerTypes[elemValue.Kind()]
- if nextDstType == nil && elemValue.Kind() == reflect.Slice {
- if elemValue.Type().Elem().Kind() == reflect.Uint8 {
- var v *[]byte
- nextDstType = reflect.TypeOf(v)
+ if nextDstType == nil {
+ if elemValue.Kind() == reflect.Slice {
+ if elemValue.Type().Elem().Kind() == reflect.Uint8 {
+ var v *[]byte
+ nextDstType = reflect.TypeOf(v)
+ }
+ }
+
+ // Get underlying type of any array.
+ // https://github.com/jackc/pgx/issues/2107
+ if elemValue.Kind() == reflect.Array {
+ nextDstType = reflect.PointerTo(reflect.ArrayOf(elemValue.Len(), elemValue.Type().Elem()))
}
}
if nextDstType != nil && dstValue.Type() != nextDstType && dstValue.CanConvert(nextDstType) {
return &underlyingTypeScanPlan{dstType: dstValue.Type(), nextDstType: nextDstType}, dstValue.Convert(nextDstType).Interface(), true
}
-
}
return nil, nil, false
@@ -1405,6 +1430,15 @@ func TryWrapFindUnderlyingTypeEncodePlan(value any) (plan WrappedEncodePlanNextS
return &underlyingTypeEncodePlan{nextValueType: byteSliceType}, refValue.Convert(byteSliceType).Interface(), true
}
+ // Get underlying type of any array.
+ // https://github.com/jackc/pgx/issues/2107
+ if refValue.Kind() == reflect.Array {
+ underlyingArrayType := reflect.ArrayOf(refValue.Len(), refValue.Type().Elem())
+ if refValue.Type() != underlyingArrayType {
+ return &underlyingTypeEncodePlan{nextValueType: underlyingArrayType}, refValue.Convert(underlyingArrayType).Interface(), true
+ }
+ }
+
return nil, nil, false
}
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go
index 9525f37c9..c81257311 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go
@@ -2,6 +2,7 @@ package pgtype
import (
"encoding/json"
+ "encoding/xml"
"net"
"net/netip"
"reflect"
@@ -89,6 +90,7 @@ func initDefaultMap() {
defaultMap.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}})
defaultMap.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}})
defaultMap.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}})
+ defaultMap.RegisterType(&Type{Name: "xml", OID: XMLOID, Codec: &XMLCodec{Marshal: xml.Marshal, Unmarshal: xml.Unmarshal}})
// Range types
defaultMap.RegisterType(&Type{Name: "daterange", OID: DaterangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[DateOID]}})
@@ -153,6 +155,7 @@ func initDefaultMap() {
defaultMap.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarbitOID]}})
defaultMap.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarcharOID]}})
defaultMap.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XIDOID]}})
+ defaultMap.RegisterType(&Type{Name: "_xml", OID: XMLArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XMLOID]}})
// Integer types that directly map to a PostgreSQL type
registerDefaultPgTypeVariants[int16](defaultMap, "int2")
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/time.go b/vendor/github.com/jackc/pgx/v5/pgtype/time.go
index 61a3abdfd..f8fd94891 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/time.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/time.go
@@ -19,9 +19,11 @@ type TimeValuer interface {
// Time represents the PostgreSQL time type. The PostgreSQL time is a time of day without time zone.
//
-// Time is represented as the number of microseconds since midnight in the same way that PostgreSQL does. Other time
-// and date types in pgtype can use time.Time as the underlying representation. However, pgtype.Time type cannot due
-// to needing to handle 24:00:00. time.Time converts that to 00:00:00 on the following day.
+// Time is represented as the number of microseconds since midnight in the same way that PostgreSQL does. Other time and
+// date types in pgtype can use time.Time as the underlying representation. However, pgtype.Time type cannot due to
+// needing to handle 24:00:00. time.Time converts that to 00:00:00 on the following day.
+//
+// The time with time zone type is not supported. Use of time with time zone is discouraged by the PostgreSQL documentation.
type Time struct {
Microseconds int64 // Number of microseconds since midnight
Valid bool
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go b/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go
index 098c516c1..f2b2fa6d4 100644
--- a/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go
@@ -205,6 +205,8 @@ func (Uint32Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPl
return scanPlanBinaryUint32ToUint32{}
case Uint32Scanner:
return scanPlanBinaryUint32ToUint32Scanner{}
+ case TextScanner:
+ return scanPlanBinaryUint32ToTextScanner{}
}
case TextFormatCode:
switch target.(type) {
@@ -282,6 +284,26 @@ func (scanPlanBinaryUint32ToUint32Scanner) Scan(src []byte, dst any) error {
return s.ScanUint32(Uint32{Uint32: n, Valid: true})
}
+type scanPlanBinaryUint32ToTextScanner struct{}
+
+func (scanPlanBinaryUint32ToTextScanner) Scan(src []byte, dst any) error {
+ s, ok := (dst).(TextScanner)
+ if !ok {
+ return ErrScanTargetTypeChanged
+ }
+
+ if src == nil {
+ return s.ScanText(Text{})
+ }
+
+ if len(src) != 4 {
+ return fmt.Errorf("invalid length for uint32: %v", len(src))
+ }
+
+ n := uint64(binary.BigEndian.Uint32(src))
+ return s.ScanText(Text{String: strconv.FormatUint(n, 10), Valid: true})
+}
+
type scanPlanTextAnyToUint32Scanner struct{}
func (scanPlanTextAnyToUint32Scanner) Scan(src []byte, dst any) error {
diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/xml.go b/vendor/github.com/jackc/pgx/v5/pgtype/xml.go
new file mode 100644
index 000000000..fb4c49ad9
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/v5/pgtype/xml.go
@@ -0,0 +1,198 @@
+package pgtype
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "encoding/xml"
+ "fmt"
+ "reflect"
+)
+
+type XMLCodec struct {
+ Marshal func(v any) ([]byte, error)
+ Unmarshal func(data []byte, v any) error
+}
+
+func (*XMLCodec) FormatSupported(format int16) bool {
+ return format == TextFormatCode || format == BinaryFormatCode
+}
+
+func (*XMLCodec) PreferredFormat() int16 {
+ return TextFormatCode
+}
+
+func (c *XMLCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
+ switch value.(type) {
+ case string:
+ return encodePlanXMLCodecEitherFormatString{}
+ case []byte:
+ return encodePlanXMLCodecEitherFormatByteSlice{}
+
+ // Cannot rely on driver.Valuer being handled later because anything can be marshalled.
+ //
+ // https://github.com/jackc/pgx/issues/1430
+ //
+ // Check for driver.Valuer must come before xml.Marshaler so that it is guaranteed to be used
+ // when both are implemented https://github.com/jackc/pgx/issues/1805
+ case driver.Valuer:
+ return &encodePlanDriverValuer{m: m, oid: oid, formatCode: format}
+
+ // Must come before trying wrap encode plans because a pointer to a struct may be unwrapped to a struct that can be
+ // marshalled.
+ //
+ // https://github.com/jackc/pgx/issues/1681
+ case xml.Marshaler:
+ return &encodePlanXMLCodecEitherFormatMarshal{
+ marshal: c.Marshal,
+ }
+ }
+
+ // Because anything can be marshalled the normal wrapping in Map.PlanScan doesn't get a chance to run. So try the
+ // appropriate wrappers here.
+ for _, f := range []TryWrapEncodePlanFunc{
+ TryWrapDerefPointerEncodePlan,
+ TryWrapFindUnderlyingTypeEncodePlan,
+ } {
+ if wrapperPlan, nextValue, ok := f(value); ok {
+ if nextPlan := c.PlanEncode(m, oid, format, nextValue); nextPlan != nil {
+ wrapperPlan.SetNext(nextPlan)
+ return wrapperPlan
+ }
+ }
+ }
+
+ return &encodePlanXMLCodecEitherFormatMarshal{
+ marshal: c.Marshal,
+ }
+}
+
+type encodePlanXMLCodecEitherFormatString struct{}
+
+func (encodePlanXMLCodecEitherFormatString) Encode(value any, buf []byte) (newBuf []byte, err error) {
+ xmlString := value.(string)
+ buf = append(buf, xmlString...)
+ return buf, nil
+}
+
+type encodePlanXMLCodecEitherFormatByteSlice struct{}
+
+func (encodePlanXMLCodecEitherFormatByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) {
+ xmlBytes := value.([]byte)
+ if xmlBytes == nil {
+ return nil, nil
+ }
+
+ buf = append(buf, xmlBytes...)
+ return buf, nil
+}
+
+type encodePlanXMLCodecEitherFormatMarshal struct {
+ marshal func(v any) ([]byte, error)
+}
+
+func (e *encodePlanXMLCodecEitherFormatMarshal) Encode(value any, buf []byte) (newBuf []byte, err error) {
+ xmlBytes, err := e.marshal(value)
+ if err != nil {
+ return nil, err
+ }
+
+ buf = append(buf, xmlBytes...)
+ return buf, nil
+}
+
+func (c *XMLCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
+ switch target.(type) {
+ case *string:
+ return scanPlanAnyToString{}
+
+ case **string:
+ // This is to fix **string scanning. It seems wrong to special case **string, but it's not clear what a better
+ // solution would be.
+ //
+ // https://github.com/jackc/pgx/issues/1470 -- **string
+ // https://github.com/jackc/pgx/issues/1691 -- ** anything else
+
+ if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
+ if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
+ if _, failed := nextPlan.(*scanPlanFail); !failed {
+ wrapperPlan.SetNext(nextPlan)
+ return wrapperPlan
+ }
+ }
+ }
+
+ case *[]byte:
+ return scanPlanXMLToByteSlice{}
+ case BytesScanner:
+ return scanPlanBinaryBytesToBytesScanner{}
+
+ // Cannot rely on sql.Scanner being handled later because scanPlanXMLToXMLUnmarshal will take precedence.
+ //
+ // https://github.com/jackc/pgx/issues/1418
+ case sql.Scanner:
+ return &scanPlanSQLScanner{formatCode: format}
+ }
+
+ return &scanPlanXMLToXMLUnmarshal{
+ unmarshal: c.Unmarshal,
+ }
+}
+
+type scanPlanXMLToByteSlice struct{}
+
+func (scanPlanXMLToByteSlice) Scan(src []byte, dst any) error {
+ dstBuf := dst.(*[]byte)
+ if src == nil {
+ *dstBuf = nil
+ return nil
+ }
+
+ *dstBuf = make([]byte, len(src))
+ copy(*dstBuf, src)
+ return nil
+}
+
+type scanPlanXMLToXMLUnmarshal struct {
+ unmarshal func(data []byte, v any) error
+}
+
+func (s *scanPlanXMLToXMLUnmarshal) Scan(src []byte, dst any) error {
+ if src == nil {
+ dstValue := reflect.ValueOf(dst)
+ if dstValue.Kind() == reflect.Ptr {
+ el := dstValue.Elem()
+ switch el.Kind() {
+ case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface, reflect.Struct:
+ el.Set(reflect.Zero(el.Type()))
+ return nil
+ }
+ }
+
+ return fmt.Errorf("cannot scan NULL into %T", dst)
+ }
+
+ elem := reflect.ValueOf(dst).Elem()
+ elem.Set(reflect.Zero(elem.Type()))
+
+ return s.unmarshal(src, dst)
+}
+
+func (c *XMLCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
+ if src == nil {
+ return nil, nil
+ }
+
+ dstBuf := make([]byte, len(src))
+ copy(dstBuf, src)
+ return dstBuf, nil
+}
+
+func (c *XMLCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
+ if src == nil {
+ return nil, nil
+ }
+
+ var dst any
+ err := c.Unmarshal(src, &dst)
+ return dst, err
+}