Expose wrap functions on ConnInfo

- Remove rarely used ScanPlan.Scan arguments
- Plus other refactorings and fixes that fell out of this change.
- Plus rows Scan now handles checking for changed type.
query-exec-mode
Jack Christensen 2022-01-22 17:48:31 -06:00
parent 322bfedc60
commit 5ed95dcd1c
40 changed files with 352 additions and 435 deletions

View File

@ -204,7 +204,12 @@ func (c *ArrayCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target int
return nil return nil
} }
return (*scanPlanArrayCodec)(c) return &scanPlanArrayCodec{
arrayCodec: c,
ci: ci,
oid: oid,
formatCode: format,
}
} }
func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, array ArraySetter) error { func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, array ArraySetter) error {
@ -244,7 +249,7 @@ func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, arr
elemSrc = src[rp : rp+elemLen] elemSrc = src[rp : rp+elemLen]
rp += elemLen rp += elemLen
} }
err = elementScanPlan.Scan(ci, c.ElementOID, BinaryFormatCode, elemSrc, elem) err = elementScanPlan.Scan(elemSrc, elem)
if err != nil { if err != nil {
return err return err
} }
@ -286,7 +291,7 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array
elemSrc = []byte(s) elemSrc = []byte(s)
} }
err = elementScanPlan.Scan(ci, c.ElementOID, TextFormatCode, elemSrc, elem) err = elementScanPlan.Scan(elemSrc, elem)
if err != nil { if err != nil {
return err return err
} }
@ -295,15 +300,23 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array
return nil return nil
} }
type scanPlanArrayCodec ArrayCodec type scanPlanArrayCodec struct {
arrayCodec *ArrayCodec
ci *ConnInfo
oid uint32
formatCode int16
}
func (spac *scanPlanArrayCodec) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (spac *scanPlanArrayCodec) Scan(src []byte, dst interface{}) error {
c := (*ArrayCodec)(spac) c := spac.arrayCodec
ci := spac.ci
oid := spac.oid
formatCode := spac.formatCode
array, err := makeArraySetter(dst) array, err := makeArraySetter(dst)
if err != nil { if err != nil {
newPlan := ci.PlanScan(oid, formatCode, dst) newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst) return newPlan.Scan(src, dst)
} }
if src == nil { if src == nil {

View File

@ -41,7 +41,7 @@ func (dst *Bits) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToBitsScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToBitsScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -163,7 +163,7 @@ func (c BitsCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryBitsToBitsScanner struct{} type scanPlanBinaryBitsToBitsScanner struct{}
func (scanPlanBinaryBitsToBitsScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBitsToBitsScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BitsScanner) scanner := (dst).(BitsScanner)
if src == nil { if src == nil {
@ -182,7 +182,7 @@ func (scanPlanBinaryBitsToBitsScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToBitsScanner struct{} type scanPlanTextAnyToBitsScanner struct{}
func (scanPlanTextAnyToBitsScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToBitsScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BitsScanner) scanner := (dst).(BitsScanner)
if src == nil { if src == nil {

View File

@ -238,7 +238,7 @@ func (c BoolCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryBoolToBool struct{} type scanPlanBinaryBoolToBool struct{}
func (scanPlanBinaryBoolToBool) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBoolToBool) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -259,7 +259,7 @@ func (scanPlanBinaryBoolToBool) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextAnyToBool struct{} type scanPlanTextAnyToBool struct{}
func (scanPlanTextAnyToBool) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToBool) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -280,7 +280,7 @@ func (scanPlanTextAnyToBool) Scan(ci *ConnInfo, oid uint32, formatCode int16, sr
type scanPlanBinaryBoolToBoolScanner struct{} type scanPlanBinaryBoolToBoolScanner struct{}
func (scanPlanBinaryBoolToBoolScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBoolToBoolScanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(BoolScanner) s, ok := (dst).(BoolScanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -299,7 +299,7 @@ func (scanPlanBinaryBoolToBoolScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToBoolScanner struct{} type scanPlanTextAnyToBoolScanner struct{}
func (scanPlanTextAnyToBoolScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToBoolScanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(BoolScanner) s, ok := (dst).(BoolScanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged

View File

@ -42,7 +42,7 @@ func (dst *Box) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToBoxScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToBoxScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -146,7 +146,7 @@ func (BoxCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfac
type scanPlanBinaryBoxToBoxScanner struct{} type scanPlanBinaryBoxToBoxScanner struct{}
func (scanPlanBinaryBoxToBoxScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBoxToBoxScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BoxScanner) scanner := (dst).(BoxScanner)
if src == nil { if src == nil {
@ -173,7 +173,7 @@ func (scanPlanBinaryBoxToBoxScanner) Scan(ci *ConnInfo, oid uint32, formatCode i
type scanPlanTextAnyToBoxScanner struct{} type scanPlanTextAnyToBoxScanner struct{}
func (scanPlanTextAnyToBoxScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToBoxScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BoxScanner) scanner := (dst).(BoxScanner)
if src == nil { if src == nil {

View File

@ -494,6 +494,8 @@ func (w netIPNetWrapper) InetValue() (Inet, error) {
type netIPWrapper net.IP type netIPWrapper net.IP
func (w netIPWrapper) SkipUnderlyingTypePlan() {}
func (w *netIPWrapper) ScanInet(v Inet) error { func (w *netIPWrapper) ScanInet(v Inet) error {
if !v.Valid { if !v.Valid {
*w = nil *w = nil
@ -578,6 +580,26 @@ func (w byte16Wrapper) UUIDValue() (UUID, error) {
type byteSliceWrapper []byte type byteSliceWrapper []byte
func (w byteSliceWrapper) SkipUnderlyingTypePlan() {}
func (w *byteSliceWrapper) ScanText(v Text) error {
if !v.Valid {
*w = nil
return nil
}
*w = byteSliceWrapper(v.String)
return nil
}
func (w byteSliceWrapper) TextValue() (Text, error) {
if w == nil {
return Text{}, nil
}
return Text{String: string(w), Valid: true}, nil
}
func (w *byteSliceWrapper) ScanUUID(v UUID) error { func (w *byteSliceWrapper) ScanUUID(v UUID) error {
if !v.Valid { if !v.Valid {
*w = nil *w = nil

View File

@ -49,7 +49,7 @@ type UndecodedBytes []byte
type scanPlanAnyToUndecodedBytes struct{} type scanPlanAnyToUndecodedBytes struct{}
func (scanPlanAnyToUndecodedBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanAnyToUndecodedBytes) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*UndecodedBytes) dstBuf := dst.(*UndecodedBytes)
if src == nil { if src == nil {
*dstBuf = nil *dstBuf = nil
@ -170,7 +170,7 @@ func (ByteaCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interf
type scanPlanBinaryBytesToBytes struct{} type scanPlanBinaryBytesToBytes struct{}
func (scanPlanBinaryBytesToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBytesToBytes) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*[]byte) dstBuf := dst.(*[]byte)
if src == nil { if src == nil {
*dstBuf = nil *dstBuf = nil
@ -184,14 +184,14 @@ func (scanPlanBinaryBytesToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryBytesToBytesScanner struct{} type scanPlanBinaryBytesToBytesScanner struct{}
func (scanPlanBinaryBytesToBytesScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryBytesToBytesScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BytesScanner) scanner := (dst).(BytesScanner)
return scanner.ScanBytes(src) return scanner.ScanBytes(src)
} }
type scanPlanTextByteaToBytes struct{} type scanPlanTextByteaToBytes struct{}
func (scanPlanTextByteaToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextByteaToBytes) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*[]byte) dstBuf := dst.(*[]byte)
if src == nil { if src == nil {
*dstBuf = nil *dstBuf = nil
@ -209,7 +209,7 @@ func (scanPlanTextByteaToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextByteaToBytesScanner struct{} type scanPlanTextByteaToBytesScanner struct{}
func (scanPlanTextByteaToBytesScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextByteaToBytesScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BytesScanner) scanner := (dst).(BytesScanner)
buf, err := decodeHexBytea(src) buf, err := decodeHexBytea(src)
if err != nil { if err != nil {

View File

@ -43,7 +43,7 @@ func (dst *Circle) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToCircleScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToCircleScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -161,7 +161,7 @@ func (c CircleCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []b
type scanPlanBinaryCircleToCircleScanner struct{} type scanPlanBinaryCircleToCircleScanner struct{}
func (scanPlanBinaryCircleToCircleScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryCircleToCircleScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(CircleScanner) scanner := (dst).(CircleScanner)
if src == nil { if src == nil {
@ -185,7 +185,7 @@ func (scanPlanBinaryCircleToCircleScanner) Scan(ci *ConnInfo, oid uint32, format
type scanPlanTextAnyToCircleScanner struct{} type scanPlanTextAnyToCircleScanner struct{}
func (scanPlanTextAnyToCircleScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToCircleScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(CircleScanner) scanner := (dst).(CircleScanner)
if src == nil { if src == nil {

View File

@ -47,7 +47,7 @@ func (dst *Date) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToDateScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToDateScanner{}.Scan([]byte(src), dst)
case time.Time: case time.Time:
*dst = Date{Time: src, Valid: true} *dst = Date{Time: src, Valid: true}
return nil return nil
@ -216,7 +216,7 @@ func (DateCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryDateToDateScanner struct{} type scanPlanBinaryDateToDateScanner struct{}
func (scanPlanBinaryDateToDateScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryDateToDateScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(DateScanner) scanner := (dst).(DateScanner)
if src == nil { if src == nil {
@ -242,7 +242,7 @@ func (scanPlanBinaryDateToDateScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToDateScanner struct{} type scanPlanTextAnyToDateScanner struct{}
func (scanPlanTextAnyToDateScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToDateScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(DateScanner) scanner := (dst).(DateScanner)
if src == nil { if src == nil {

View File

@ -86,7 +86,7 @@ type scanPlanTextAnyToEnumString struct {
codec *EnumCodec codec *EnumCodec
} }
func (plan *scanPlanTextAnyToEnumString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *scanPlanTextAnyToEnumString) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -101,7 +101,7 @@ type scanPlanTextAnyToEnumTextScanner struct {
codec *EnumCodec codec *EnumCodec
} }
func (plan *scanPlanTextAnyToEnumTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *scanPlanTextAnyToEnumTextScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TextScanner) scanner := (dst).(TextScanner)
if src == nil { if src == nil {

View File

@ -164,7 +164,7 @@ func (Float4Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter
type scanPlanBinaryFloat4ToFloat32 struct{} type scanPlanBinaryFloat4ToFloat32 struct{}
func (scanPlanBinaryFloat4ToFloat32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat4ToFloat32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -182,7 +182,7 @@ func (scanPlanBinaryFloat4ToFloat32) Scan(ci *ConnInfo, oid uint32, formatCode i
type scanPlanBinaryFloat4ToFloat64Scanner struct{} type scanPlanBinaryFloat4ToFloat64Scanner struct{}
func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(src []byte, dst interface{}) error {
s := (dst).(Float64Scanner) s := (dst).(Float64Scanner)
if src == nil { if src == nil {
@ -199,7 +199,7 @@ func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, forma
type scanPlanBinaryFloat4ToInt64Scanner struct{} type scanPlanBinaryFloat4ToInt64Scanner struct{}
func (scanPlanBinaryFloat4ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat4ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s := (dst).(Int64Scanner) s := (dst).(Int64Scanner)
if src == nil { if src == nil {
@ -222,7 +222,7 @@ func (scanPlanBinaryFloat4ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatC
type scanPlanTextAnyToFloat32 struct{} type scanPlanTextAnyToFloat32 struct{}
func (scanPlanTextAnyToFloat32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToFloat32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }

View File

@ -202,7 +202,7 @@ func (Float8Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter
type scanPlanBinaryFloat8ToFloat64 struct{} type scanPlanBinaryFloat8ToFloat64 struct{}
func (scanPlanBinaryFloat8ToFloat64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat8ToFloat64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -220,7 +220,7 @@ func (scanPlanBinaryFloat8ToFloat64) Scan(ci *ConnInfo, oid uint32, formatCode i
type scanPlanBinaryFloat8ToFloat64Scanner struct{} type scanPlanBinaryFloat8ToFloat64Scanner struct{}
func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(src []byte, dst interface{}) error {
s := (dst).(Float64Scanner) s := (dst).(Float64Scanner)
if src == nil { if src == nil {
@ -237,7 +237,7 @@ func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, forma
type scanPlanBinaryFloat8ToInt64Scanner struct{} type scanPlanBinaryFloat8ToInt64Scanner struct{}
func (scanPlanBinaryFloat8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryFloat8ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s := (dst).(Int64Scanner) s := (dst).(Int64Scanner)
if src == nil { if src == nil {
@ -260,7 +260,7 @@ func (scanPlanBinaryFloat8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatC
type scanPlanTextAnyToFloat64 struct{} type scanPlanTextAnyToFloat64 struct{}
func (scanPlanTextAnyToFloat64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToFloat64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -278,7 +278,7 @@ func (scanPlanTextAnyToFloat64) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextAnyToFloat64Scanner struct{} type scanPlanTextAnyToFloat64Scanner struct{}
func (scanPlanTextAnyToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToFloat64Scanner) Scan(src []byte, dst interface{}) error {
s := (dst).(Float64Scanner) s := (dst).(Float64Scanner)
if src == nil { if src == nil {

View File

@ -43,7 +43,7 @@ func (h *Hstore) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToHstoreScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), h) return scanPlanTextAnyToHstoreScanner{}.Scan([]byte(src), h)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -170,7 +170,7 @@ func (HstoreCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter
type scanPlanBinaryHstoreToHstoreScanner struct{} type scanPlanBinaryHstoreToHstoreScanner struct{}
func (scanPlanBinaryHstoreToHstoreScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryHstoreToHstoreScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(HstoreScanner) scanner := (dst).(HstoreScanner)
if src == nil { if src == nil {
@ -213,7 +213,7 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(ci *ConnInfo, oid uint32, format
} }
var value Text var value Text
err := scanPlanTextAnyToTextScanner{}.Scan(ci, TextOID, TextFormatCode, valueBuf, &value) err := scanPlanTextAnyToTextScanner{}.Scan(valueBuf, &value)
if err != nil { if err != nil {
return err return err
} }
@ -230,7 +230,7 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(ci *ConnInfo, oid uint32, format
type scanPlanTextAnyToHstoreScanner struct{} type scanPlanTextAnyToHstoreScanner struct{}
func (scanPlanTextAnyToHstoreScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToHstoreScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(HstoreScanner) scanner := (dst).(HstoreScanner)
if src == nil { if src == nil {

View File

@ -46,7 +46,7 @@ func (dst *Inet) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToInetScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToInetScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -182,7 +182,7 @@ func (c InetCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryInetToInetScanner struct{} type scanPlanBinaryInetToInetScanner struct{}
func (scanPlanBinaryInetToInetScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInetToInetScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(InetScanner) scanner := (dst).(InetScanner)
if src == nil { if src == nil {
@ -211,7 +211,7 @@ func (scanPlanBinaryInetToInetScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToInetScanner struct{} type scanPlanTextAnyToInetScanner struct{}
func (scanPlanTextAnyToInetScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInetScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(InetScanner) scanner := (dst).(InetScanner)
if src == nil { if src == nil {

View File

@ -292,7 +292,7 @@ func (c Int2Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryInt2ToInt8 struct{} type scanPlanBinaryInt2ToInt8 struct{}
func (scanPlanBinaryInt2ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -320,7 +320,7 @@ func (scanPlanBinaryInt2ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt2ToUint8 struct{} type scanPlanBinaryInt2ToUint8 struct{}
func (scanPlanBinaryInt2ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToUint8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -350,7 +350,7 @@ func (scanPlanBinaryInt2ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt2ToInt16 struct{} type scanPlanBinaryInt2ToInt16 struct{}
func (scanPlanBinaryInt2ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -371,7 +371,7 @@ func (scanPlanBinaryInt2ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt2ToUint16 struct{} type scanPlanBinaryInt2ToUint16 struct{}
func (scanPlanBinaryInt2ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToUint16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -397,7 +397,7 @@ func (scanPlanBinaryInt2ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt2ToInt32 struct{} type scanPlanBinaryInt2ToInt32 struct{}
func (scanPlanBinaryInt2ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -418,7 +418,7 @@ func (scanPlanBinaryInt2ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt2ToUint32 struct{} type scanPlanBinaryInt2ToUint32 struct{}
func (scanPlanBinaryInt2ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToUint32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -444,7 +444,7 @@ func (scanPlanBinaryInt2ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt2ToInt64 struct{} type scanPlanBinaryInt2ToInt64 struct{}
func (scanPlanBinaryInt2ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -465,7 +465,7 @@ func (scanPlanBinaryInt2ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt2ToUint64 struct{} type scanPlanBinaryInt2ToUint64 struct{}
func (scanPlanBinaryInt2ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToUint64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -491,7 +491,7 @@ func (scanPlanBinaryInt2ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt2ToInt struct{} type scanPlanBinaryInt2ToInt struct{}
func (scanPlanBinaryInt2ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -512,7 +512,7 @@ func (scanPlanBinaryInt2ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt2ToUint struct{} type scanPlanBinaryInt2ToUint struct{}
func (scanPlanBinaryInt2ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToUint) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -538,7 +538,7 @@ func (scanPlanBinaryInt2ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt2ToInt64Scanner struct{} type scanPlanBinaryInt2ToInt64Scanner struct{}
func (scanPlanBinaryInt2ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt2ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -829,7 +829,7 @@ func (c Int4Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryInt4ToInt8 struct{} type scanPlanBinaryInt4ToInt8 struct{}
func (scanPlanBinaryInt4ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -857,7 +857,7 @@ func (scanPlanBinaryInt4ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt4ToUint8 struct{} type scanPlanBinaryInt4ToUint8 struct{}
func (scanPlanBinaryInt4ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToUint8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -887,7 +887,7 @@ func (scanPlanBinaryInt4ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt4ToInt16 struct{} type scanPlanBinaryInt4ToInt16 struct{}
func (scanPlanBinaryInt4ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -915,7 +915,7 @@ func (scanPlanBinaryInt4ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt4ToUint16 struct{} type scanPlanBinaryInt4ToUint16 struct{}
func (scanPlanBinaryInt4ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToUint16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -945,7 +945,7 @@ func (scanPlanBinaryInt4ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt4ToInt32 struct{} type scanPlanBinaryInt4ToInt32 struct{}
func (scanPlanBinaryInt4ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -966,7 +966,7 @@ func (scanPlanBinaryInt4ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt4ToUint32 struct{} type scanPlanBinaryInt4ToUint32 struct{}
func (scanPlanBinaryInt4ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToUint32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -992,7 +992,7 @@ func (scanPlanBinaryInt4ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt4ToInt64 struct{} type scanPlanBinaryInt4ToInt64 struct{}
func (scanPlanBinaryInt4ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1013,7 +1013,7 @@ func (scanPlanBinaryInt4ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt4ToUint64 struct{} type scanPlanBinaryInt4ToUint64 struct{}
func (scanPlanBinaryInt4ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToUint64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1039,7 +1039,7 @@ func (scanPlanBinaryInt4ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt4ToInt struct{} type scanPlanBinaryInt4ToInt struct{}
func (scanPlanBinaryInt4ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1060,7 +1060,7 @@ func (scanPlanBinaryInt4ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt4ToUint struct{} type scanPlanBinaryInt4ToUint struct{}
func (scanPlanBinaryInt4ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToUint) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1086,7 +1086,7 @@ func (scanPlanBinaryInt4ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt4ToInt64Scanner struct{} type scanPlanBinaryInt4ToInt64Scanner struct{}
func (scanPlanBinaryInt4ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt4ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -1377,7 +1377,7 @@ func (c Int8Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanBinaryInt8ToInt8 struct{} type scanPlanBinaryInt8ToInt8 struct{}
func (scanPlanBinaryInt8ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1405,7 +1405,7 @@ func (scanPlanBinaryInt8ToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt8ToUint8 struct{} type scanPlanBinaryInt8ToUint8 struct{}
func (scanPlanBinaryInt8ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToUint8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1435,7 +1435,7 @@ func (scanPlanBinaryInt8ToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt8ToInt16 struct{} type scanPlanBinaryInt8ToInt16 struct{}
func (scanPlanBinaryInt8ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1463,7 +1463,7 @@ func (scanPlanBinaryInt8ToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt8ToUint16 struct{} type scanPlanBinaryInt8ToUint16 struct{}
func (scanPlanBinaryInt8ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToUint16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1493,7 +1493,7 @@ func (scanPlanBinaryInt8ToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt8ToInt32 struct{} type scanPlanBinaryInt8ToInt32 struct{}
func (scanPlanBinaryInt8ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1521,7 +1521,7 @@ func (scanPlanBinaryInt8ToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt8ToUint32 struct{} type scanPlanBinaryInt8ToUint32 struct{}
func (scanPlanBinaryInt8ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToUint32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1551,7 +1551,7 @@ func (scanPlanBinaryInt8ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt8ToInt64 struct{} type scanPlanBinaryInt8ToInt64 struct{}
func (scanPlanBinaryInt8ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1572,7 +1572,7 @@ func (scanPlanBinaryInt8ToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanBinaryInt8ToUint64 struct{} type scanPlanBinaryInt8ToUint64 struct{}
func (scanPlanBinaryInt8ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToUint64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1598,7 +1598,7 @@ func (scanPlanBinaryInt8ToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int1
type scanPlanBinaryInt8ToInt struct{} type scanPlanBinaryInt8ToInt struct{}
func (scanPlanBinaryInt8ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1626,7 +1626,7 @@ func (scanPlanBinaryInt8ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt8ToUint struct{} type scanPlanBinaryInt8ToUint struct{}
func (scanPlanBinaryInt8ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToUint) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1656,7 +1656,7 @@ func (scanPlanBinaryInt8ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanBinaryInt8ToInt64Scanner struct{} type scanPlanBinaryInt8ToInt64Scanner struct{}
func (scanPlanBinaryInt8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt8ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -1677,7 +1677,7 @@ func (scanPlanBinaryInt8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCod
type scanPlanTextAnyToInt8 struct{} type scanPlanTextAnyToInt8 struct{}
func (scanPlanTextAnyToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1698,7 +1698,7 @@ func (scanPlanTextAnyToInt8) Scan(ci *ConnInfo, oid uint32, formatCode int16, sr
type scanPlanTextAnyToUint8 struct{} type scanPlanTextAnyToUint8 struct{}
func (scanPlanTextAnyToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint8) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1719,7 +1719,7 @@ func (scanPlanTextAnyToUint8) Scan(ci *ConnInfo, oid uint32, formatCode int16, s
type scanPlanTextAnyToInt16 struct{} type scanPlanTextAnyToInt16 struct{}
func (scanPlanTextAnyToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1740,7 +1740,7 @@ func (scanPlanTextAnyToInt16) Scan(ci *ConnInfo, oid uint32, formatCode int16, s
type scanPlanTextAnyToUint16 struct{} type scanPlanTextAnyToUint16 struct{}
func (scanPlanTextAnyToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint16) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1761,7 +1761,7 @@ func (scanPlanTextAnyToUint16) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextAnyToInt32 struct{} type scanPlanTextAnyToInt32 struct{}
func (scanPlanTextAnyToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1782,7 +1782,7 @@ func (scanPlanTextAnyToInt32) Scan(ci *ConnInfo, oid uint32, formatCode int16, s
type scanPlanTextAnyToUint32 struct{} type scanPlanTextAnyToUint32 struct{}
func (scanPlanTextAnyToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1803,7 +1803,7 @@ func (scanPlanTextAnyToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextAnyToInt64 struct{} type scanPlanTextAnyToInt64 struct{}
func (scanPlanTextAnyToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1824,7 +1824,7 @@ func (scanPlanTextAnyToInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, s
type scanPlanTextAnyToUint64 struct{} type scanPlanTextAnyToUint64 struct{}
func (scanPlanTextAnyToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint64) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1845,7 +1845,7 @@ func (scanPlanTextAnyToUint64) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanTextAnyToInt struct{} type scanPlanTextAnyToInt struct{}
func (scanPlanTextAnyToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1866,7 +1866,7 @@ func (scanPlanTextAnyToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src
type scanPlanTextAnyToUint struct{} type scanPlanTextAnyToUint struct{}
func (scanPlanTextAnyToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -1887,7 +1887,7 @@ func (scanPlanTextAnyToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, sr
type scanPlanTextAnyToInt64Scanner struct{} type scanPlanTextAnyToInt64Scanner struct{}
func (scanPlanTextAnyToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged

View File

@ -295,7 +295,7 @@ func (c Int<%= pg_byte_size %>Codec) DecodeValue(ci *ConnInfo, oid uint32, forma
<% [8, 16, 32, 64].each do |dst_bit_size| %> <% [8, 16, 32, 64].each do |dst_bit_size| %>
type scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %> struct{} type scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %> struct{}
func (scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %>) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -329,7 +329,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %>) Scan(ci *Con
type scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %> struct{} type scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %> struct{}
func (scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %>) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -361,7 +361,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %>) Scan(ci *Co
<%# PostgreSQL binary format integer to Go machine integers %> <%# PostgreSQL binary format integer to Go machine integers %>
type scanPlanBinaryInt<%= pg_byte_size %>ToInt struct{} type scanPlanBinaryInt<%= pg_byte_size %>ToInt struct{}
func (scanPlanBinaryInt<%= pg_byte_size %>ToInt) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt<%= pg_byte_size %>ToInt) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -393,7 +393,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToInt) Scan(ci *ConnInfo, oid uint32,
type scanPlanBinaryInt<%= pg_byte_size %>ToUint struct{} type scanPlanBinaryInt<%= pg_byte_size %>ToUint struct{}
func (scanPlanBinaryInt<%= pg_byte_size %>ToUint) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt<%= pg_byte_size %>ToUint) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -424,7 +424,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToUint) Scan(ci *ConnInfo, oid uint32,
<%# PostgreSQL binary format integer to Go Int64Scanner %> <%# PostgreSQL binary format integer to Go Int64Scanner %>
type scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner struct{} type scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner struct{}
func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -455,7 +455,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(ci *ConnInfo, oid
].each do |type_suffix, bit_size| %> ].each do |type_suffix, bit_size| %>
type scanPlanTextAnyToInt<%= type_suffix %> struct{} type scanPlanTextAnyToInt<%= type_suffix %> struct{}
func (scanPlanTextAnyToInt<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt<%= type_suffix %>) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -476,7 +476,7 @@ func (scanPlanTextAnyToInt<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, for
type scanPlanTextAnyToUint<%= type_suffix %> struct{} type scanPlanTextAnyToUint<%= type_suffix %> struct{}
func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -498,7 +498,7 @@ func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(ci *ConnInfo, oid uint32, fo
type scanPlanTextAnyToInt64Scanner struct{} type scanPlanTextAnyToInt64Scanner struct{}
func (scanPlanTextAnyToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToInt64Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Int64Scanner) s, ok := (dst).(Int64Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged

View File

@ -51,7 +51,7 @@ func (interval *Interval) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToIntervalScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), interval) return scanPlanTextAnyToIntervalScanner{}.Scan([]byte(src), interval)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -171,7 +171,7 @@ func (IntervalCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target int
type scanPlanBinaryIntervalToIntervalScanner struct{} type scanPlanBinaryIntervalToIntervalScanner struct{}
func (scanPlanBinaryIntervalToIntervalScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryIntervalToIntervalScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(IntervalScanner) scanner := (dst).(IntervalScanner)
if src == nil { if src == nil {
@ -191,7 +191,7 @@ func (scanPlanBinaryIntervalToIntervalScanner) Scan(ci *ConnInfo, oid uint32, fo
type scanPlanTextAnyToIntervalScanner struct{} type scanPlanTextAnyToIntervalScanner struct{}
func (scanPlanTextAnyToIntervalScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToIntervalScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(IntervalScanner) scanner := (dst).(IntervalScanner)
if src == nil { if src == nil {

View File

@ -65,7 +65,7 @@ func (JSONCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanAnyToString struct{} type scanPlanAnyToString struct{}
func (scanPlanAnyToString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanAnyToString) Scan(src []byte, dst interface{}) error {
p := dst.(*string) p := dst.(*string)
*p = string(src) *p = string(src)
return nil return nil
@ -73,7 +73,7 @@ func (scanPlanAnyToString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src
type scanPlanJSONToByteSlice struct{} type scanPlanJSONToByteSlice struct{}
func (scanPlanJSONToByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanJSONToByteSlice) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*[]byte) dstBuf := dst.(*[]byte)
if src == nil { if src == nil {
*dstBuf = nil *dstBuf = nil
@ -87,14 +87,14 @@ func (scanPlanJSONToByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanJSONToBytesScanner struct{} type scanPlanJSONToBytesScanner struct{}
func (scanPlanJSONToBytesScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanJSONToBytesScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(BytesScanner) scanner := (dst).(BytesScanner)
return scanner.ScanBytes(src) return scanner.ScanBytes(src)
} }
type scanPlanJSONToJSONUnmarshal struct{} type scanPlanJSONToJSONUnmarshal struct{}
func (scanPlanJSONToJSONUnmarshal) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanJSONToJSONUnmarshal) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
dstValue := reflect.ValueOf(dst) dstValue := reflect.ValueOf(dst)
if dstValue.Kind() == reflect.Ptr { if dstValue.Kind() == reflect.Ptr {

View File

@ -57,9 +57,9 @@ type scanPlanJSONBCodecBinaryUnwrapper struct {
textPlan ScanPlan textPlan ScanPlan
} }
func (plan *scanPlanJSONBCodecBinaryUnwrapper) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *scanPlanJSONBCodecBinaryUnwrapper) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return plan.textPlan.Scan(ci, oid, formatCode, src, dst) return plan.textPlan.Scan(src, dst)
} }
if len(src) == 0 { if len(src) == 0 {
@ -70,7 +70,7 @@ func (plan *scanPlanJSONBCodecBinaryUnwrapper) Scan(ci *ConnInfo, oid uint32, fo
return fmt.Errorf("unknown jsonb version number %d", src[0]) return fmt.Errorf("unknown jsonb version number %d", src[0])
} }
return plan.textPlan.Scan(ci, oid, formatCode, src[1:], dst) return plan.textPlan.Scan(src[1:], dst)
} }
func (c JSONBCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { func (c JSONBCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) {

View File

@ -46,7 +46,7 @@ func (line *Line) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToLineScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), line) return scanPlanTextAnyToLineScanner{}.Scan([]byte(src), line)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -148,7 +148,7 @@ func (LineCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryLineToLineScanner struct{} type scanPlanBinaryLineToLineScanner struct{}
func (scanPlanBinaryLineToLineScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryLineToLineScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(LineScanner) scanner := (dst).(LineScanner)
if src == nil { if src == nil {
@ -173,7 +173,7 @@ func (scanPlanBinaryLineToLineScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToLineScanner struct{} type scanPlanTextAnyToLineScanner struct{}
func (scanPlanTextAnyToLineScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToLineScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(LineScanner) scanner := (dst).(LineScanner)
if src == nil { if src == nil {

View File

@ -42,7 +42,7 @@ func (lseg *Lseg) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToLsegScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), lseg) return scanPlanTextAnyToLsegScanner{}.Scan([]byte(src), lseg)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -146,7 +146,7 @@ func (LsegCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryLsegToLsegScanner struct{} type scanPlanBinaryLsegToLsegScanner struct{}
func (scanPlanBinaryLsegToLsegScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryLsegToLsegScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(LsegScanner) scanner := (dst).(LsegScanner)
if src == nil { if src == nil {
@ -173,7 +173,7 @@ func (scanPlanBinaryLsegToLsegScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToLsegScanner struct{} type scanPlanTextAnyToLsegScanner struct{}
func (scanPlanTextAnyToLsegScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToLsegScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(LsegScanner) scanner := (dst).(LsegScanner)
if src == nil { if src == nil {

View File

@ -101,7 +101,7 @@ func (MacaddrCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inte
type scanPlanBinaryMacaddrToHardwareAddr struct{} type scanPlanBinaryMacaddrToHardwareAddr struct{}
func (scanPlanBinaryMacaddrToHardwareAddr) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryMacaddrToHardwareAddr) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*net.HardwareAddr) dstBuf := dst.(*net.HardwareAddr)
if src == nil { if src == nil {
*dstBuf = nil *dstBuf = nil
@ -115,7 +115,7 @@ func (scanPlanBinaryMacaddrToHardwareAddr) Scan(ci *ConnInfo, oid uint32, format
type scanPlanBinaryMacaddrToTextScanner struct{} type scanPlanBinaryMacaddrToTextScanner struct{}
func (scanPlanBinaryMacaddrToTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryMacaddrToTextScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TextScanner) scanner := (dst).(TextScanner)
if src == nil { if src == nil {
return scanner.ScanText(Text{}) return scanner.ScanText(Text{})
@ -126,7 +126,7 @@ func (scanPlanBinaryMacaddrToTextScanner) Scan(ci *ConnInfo, oid uint32, formatC
type scanPlanTextMacaddrToHardwareAddr struct{} type scanPlanTextMacaddrToHardwareAddr struct{}
func (scanPlanTextMacaddrToHardwareAddr) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextMacaddrToHardwareAddr) Scan(src []byte, dst interface{}) error {
p := dst.(*net.HardwareAddr) p := dst.(*net.HardwareAddr)
if src == nil { if src == nil {

View File

@ -175,7 +175,7 @@ func (n *Numeric) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToNumericScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), n) return scanPlanTextAnyToNumericScanner{}.Scan([]byte(src), n)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -522,7 +522,7 @@ func (NumericCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inte
type scanPlanBinaryNumericToNumericScanner struct{} type scanPlanBinaryNumericToNumericScanner struct{}
func (scanPlanBinaryNumericToNumericScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryNumericToNumericScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(NumericScanner) scanner := (dst).(NumericScanner)
if src == nil { if src == nil {
@ -628,7 +628,7 @@ func (scanPlanBinaryNumericToNumericScanner) Scan(ci *ConnInfo, oid uint32, form
type scanPlanBinaryNumericToFloat64Scanner struct{} type scanPlanBinaryNumericToFloat64Scanner struct{}
func (scanPlanBinaryNumericToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryNumericToFloat64Scanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(Float64Scanner) scanner := (dst).(Float64Scanner)
if src == nil { if src == nil {
@ -637,7 +637,7 @@ func (scanPlanBinaryNumericToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, form
var n Numeric var n Numeric
err := scanPlanBinaryNumericToNumericScanner{}.Scan(ci, oid, formatCode, src, &n) err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n)
if err != nil { if err != nil {
return err return err
} }
@ -652,7 +652,7 @@ func (scanPlanBinaryNumericToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, form
type scanPlanBinaryNumericToInt64Scanner struct{} type scanPlanBinaryNumericToInt64Scanner struct{}
func (scanPlanBinaryNumericToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryNumericToInt64Scanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(Int64Scanner) scanner := (dst).(Int64Scanner)
if src == nil { if src == nil {
@ -661,7 +661,7 @@ func (scanPlanBinaryNumericToInt64Scanner) Scan(ci *ConnInfo, oid uint32, format
var n Numeric var n Numeric
err := scanPlanBinaryNumericToNumericScanner{}.Scan(ci, oid, formatCode, src, &n) err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n)
if err != nil { if err != nil {
return err return err
} }
@ -680,7 +680,7 @@ func (scanPlanBinaryNumericToInt64Scanner) Scan(ci *ConnInfo, oid uint32, format
type scanPlanTextAnyToNumericScanner struct{} type scanPlanTextAnyToNumericScanner struct{}
func (scanPlanTextAnyToNumericScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToNumericScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(NumericScanner) scanner := (dst).(NumericScanner)
if src == nil { if src == nil {

View File

@ -64,7 +64,7 @@ func mustParseNumeric(t *testing.T, src string) pgtype.Numeric {
var n pgtype.Numeric var n pgtype.Numeric
plan := pgtype.NumericCodec{}.PlanScan(nil, pgtype.NumericOID, pgtype.TextFormatCode, &n, false) plan := pgtype.NumericCodec{}.PlanScan(nil, pgtype.NumericOID, pgtype.TextFormatCode, &n, false)
require.NotNil(t, plan) require.NotNil(t, plan)
err := plan.Scan(nil, pgtype.NumericOID, pgtype.TextFormatCode, []byte(src), &n) err := plan.Scan([]byte(src), &n)
require.NoError(t, err) require.NoError(t, err)
return n return n
} }

View File

@ -43,7 +43,7 @@ func (path *Path) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToPathScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), path) return scanPlanTextAnyToPathScanner{}.Scan([]byte(src), path)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -173,7 +173,7 @@ func (PathCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryPathToPathScanner struct{} type scanPlanBinaryPathToPathScanner struct{}
func (scanPlanBinaryPathToPathScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryPathToPathScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PathScanner) scanner := (dst).(PathScanner)
if src == nil { if src == nil {
@ -211,7 +211,7 @@ func (scanPlanBinaryPathToPathScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToPathScanner struct{} type scanPlanTextAnyToPathScanner struct{}
func (scanPlanTextAnyToPathScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToPathScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PathScanner) scanner := (dst).(PathScanner)
if src == nil { if src == nil {

View File

@ -3,10 +3,8 @@ package pgtype
import ( import (
"database/sql" "database/sql"
"database/sql/driver" "database/sql/driver"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math"
"net" "net"
"reflect" "reflect"
"time" "time"
@ -198,14 +196,14 @@ func NewConnInfo() *ConnInfo {
TryWrapEncodePlanFuncs: []TryWrapEncodePlanFunc{ TryWrapEncodePlanFuncs: []TryWrapEncodePlanFunc{
TryWrapDerefPointerEncodePlan, TryWrapDerefPointerEncodePlan,
TryWrapFindUnderlyingTypeEncodePlan,
TryWrapBuiltinTypeEncodePlan, TryWrapBuiltinTypeEncodePlan,
TryWrapFindUnderlyingTypeEncodePlan,
}, },
TryWrapScanPlanFuncs: []TryWrapScanPlanFunc{ TryWrapScanPlanFuncs: []TryWrapScanPlanFunc{
TryPointerPointerScanPlan, TryPointerPointerScanPlan,
TryFindUnderlyingTypeScanPlan,
TryWrapBuiltinTypeScanPlan, TryWrapBuiltinTypeScanPlan,
TryFindUnderlyingTypeScanPlan,
}, },
} }
@ -409,22 +407,19 @@ type EncodePlan interface {
// ScanPlan is a precompiled plan to scan into a type of destination. // ScanPlan is a precompiled plan to scan into a type of destination.
type ScanPlan interface { type ScanPlan interface {
// Scan scans src into dst. If the dst type has changed in an incompatible way a ScanPlan should automatically // Scan scans src into target.
// replan and scan. Scan(src []byte, target interface{}) error
Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error
} }
type scanPlanDstResultDecoder struct{} type scanPlanCodecSQLScanner struct {
c Codec
func (scanPlanDstResultDecoder) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { ci *ConnInfo
newPlan := ci.PlanScan(oid, formatCode, dst) oid uint32
return newPlan.Scan(ci, oid, formatCode, src, dst) formatCode int16
} }
type scanPlanCodecSQLScanner struct{ c Codec } func (plan *scanPlanCodecSQLScanner) Scan(src []byte, dst interface{}) error {
value, err := plan.c.DecodeDatabaseSQLValue(plan.ci, plan.oid, plan.formatCode, src)
func (plan *scanPlanCodecSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
value, err := plan.c.DecodeDatabaseSQLValue(ci, oid, formatCode, src)
if err != nil { if err != nil {
return err return err
} }
@ -433,135 +428,56 @@ func (plan *scanPlanCodecSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode i
return scanner.Scan(value) return scanner.Scan(value)
} }
type scanPlanSQLScanner struct{} type scanPlanSQLScanner struct {
formatCode int16
}
func (scanPlanSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *scanPlanSQLScanner) Scan(src []byte, dst interface{}) error {
scanner := dst.(sql.Scanner) scanner := dst.(sql.Scanner)
if src == nil { if src == nil {
// This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the // This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the
// text format path would be converted to empty string. // text format path would be converted to empty string.
return scanner.Scan(nil) return scanner.Scan(nil)
} else if formatCode == BinaryFormatCode { } else if plan.formatCode == BinaryFormatCode {
return scanner.Scan(src) return scanner.Scan(src)
} else { } else {
return scanner.Scan(string(src)) return scanner.Scan(string(src))
} }
} }
type scanPlanReflection struct{}
func (scanPlanReflection) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
// We might be given a pointer to something that implements the decoder interface(s),
// even though the pointer itself doesn't.
refVal := reflect.ValueOf(dst)
if refVal.Kind() == reflect.Ptr && refVal.Type().Elem().Kind() == reflect.Ptr {
// If the database returned NULL, then we set dest as nil to indicate that.
if src == nil {
nilPtr := reflect.Zero(refVal.Type().Elem())
refVal.Elem().Set(nilPtr)
return nil
}
// We need to allocate an element, and set the destination to it
// Then we can retry as that element.
elemPtr := reflect.New(refVal.Type().Elem().Elem())
refVal.Elem().Set(elemPtr)
plan := ci.PlanScan(oid, formatCode, elemPtr.Interface())
return plan.Scan(ci, oid, formatCode, src, elemPtr.Interface())
}
return scanUnknownType(oid, formatCode, src, dst)
}
type scanPlanBinaryInt64 struct{}
func (scanPlanBinaryInt64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
if src == nil {
return fmt.Errorf("cannot scan null into %T", dst)
}
if len(src) != 8 {
return fmt.Errorf("invalid length for int8: %v", len(src))
}
if p, ok := (dst).(*int64); ok {
*p = int64(binary.BigEndian.Uint64(src))
return nil
}
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
type scanPlanBinaryFloat32 struct{}
func (scanPlanBinaryFloat32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
if src == nil {
return fmt.Errorf("cannot scan null into %T", dst)
}
if len(src) != 4 {
return fmt.Errorf("invalid length for int4: %v", len(src))
}
if p, ok := (dst).(*float32); ok {
n := int32(binary.BigEndian.Uint32(src))
*p = float32(math.Float32frombits(uint32(n)))
return nil
}
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
type scanPlanBinaryFloat64 struct{}
func (scanPlanBinaryFloat64) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
if src == nil {
return fmt.Errorf("cannot scan null into %T", dst)
}
if len(src) != 8 {
return fmt.Errorf("invalid length for int8: %v", len(src))
}
if p, ok := (dst).(*float64); ok {
n := int64(binary.BigEndian.Uint64(src))
*p = float64(math.Float64frombits(uint64(n)))
return nil
}
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
type scanPlanBinaryBytes struct{}
func (scanPlanBinaryBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error {
if p, ok := (dst).(*[]byte); ok {
*p = src
return nil
}
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
type scanPlanString struct{} type scanPlanString struct{}
func (scanPlanString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanString) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
if p, ok := (dst).(*string); ok { p := (dst).(*string)
*p = string(src) *p = string(src)
return nil
}
type scanPlanAnyTextToBytes struct{}
func (scanPlanAnyTextToBytes) Scan(src []byte, dst interface{}) error {
dstBuf := dst.(*[]byte)
if src == nil {
*dstBuf = nil
return nil return nil
} }
newPlan := ci.PlanScan(oid, formatCode, dst) *dstBuf = make([]byte, len(src))
return newPlan.Scan(ci, oid, formatCode, src, dst) copy(*dstBuf, src)
return nil
}
type scanPlanFail struct {
oid uint32
formatCode int16
}
func (plan *scanPlanFail) Scan(src []byte, dst interface{}) error {
return fmt.Errorf("cannot scan OID %v in format %v into %T", plan.oid, plan.formatCode, dst)
} }
// TryWrapScanPlanFunc is a function that tries to create a wrapper plan for target. If successful it returns a plan // TryWrapScanPlanFunc is a function that tries to create a wrapper plan for target. If successful it returns a plan
@ -577,12 +493,7 @@ type pointerPointerScanPlan struct {
func (plan *pointerPointerScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *pointerPointerScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *pointerPointerScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *pointerPointerScanPlan) Scan(src []byte, dst interface{}) error {
if plan.dstType != reflect.TypeOf(dst) {
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
el := reflect.ValueOf(dst).Elem() el := reflect.ValueOf(dst).Elem()
if src == nil { if src == nil {
el.Set(reflect.Zero(el.Type())) el.Set(reflect.Zero(el.Type()))
@ -590,7 +501,7 @@ func (plan *pointerPointerScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode in
} }
el.Set(reflect.New(el.Type().Elem())) el.Set(reflect.New(el.Type().Elem()))
return plan.next.Scan(ci, oid, formatCode, src, el.Interface()) return plan.next.Scan(src, el.Interface())
} }
// TryPointerPointerScanPlan handles a pointer to a pointer by setting the target to nil for SQL NULL and allocating and // TryPointerPointerScanPlan handles a pointer to a pointer by setting the target to nil for SQL NULL and allocating and
@ -636,13 +547,8 @@ type underlyingTypeScanPlan struct {
func (plan *underlyingTypeScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *underlyingTypeScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *underlyingTypeScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *underlyingTypeScanPlan) Scan(src []byte, dst interface{}) error {
if plan.dstType != reflect.TypeOf(dst) { return plan.next.Scan(src, reflect.ValueOf(dst).Convert(plan.nextDstType).Interface())
newPlan := ci.PlanScan(oid, formatCode, dst)
return newPlan.Scan(ci, oid, formatCode, src, dst)
}
return plan.next.Scan(ci, oid, formatCode, src, reflect.ValueOf(dst).Convert(plan.nextDstType).Interface())
} }
// TryFindUnderlyingTypeScanPlan tries to convert to a Go builtin type. e.g. If value was of type MyString and // TryFindUnderlyingTypeScanPlan tries to convert to a Go builtin type. e.g. If value was of type MyString and
@ -657,9 +563,17 @@ func TryFindUnderlyingTypeScanPlan(dst interface{}) (plan WrappedScanPlanNextSet
if dstValue.Kind() == reflect.Ptr { if dstValue.Kind() == reflect.Ptr {
elemValue := dstValue.Elem() elemValue := dstValue.Elem()
nextDstType := elemKindToPointerTypes[elemValue.Kind()] 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 && dstValue.Type() != nextDstType { if nextDstType != nil && dstValue.Type() != nextDstType {
return &underlyingTypeScanPlan{dstType: dstValue.Type(), nextDstType: nextDstType}, dstValue.Convert(nextDstType).Interface(), true return &underlyingTypeScanPlan{dstType: dstValue.Type(), nextDstType: nextDstType}, dstValue.Convert(nextDstType).Interface(), true
} }
} }
return nil, nil, false return nil, nil, false
@ -728,8 +642,8 @@ type wrapInt8ScanPlan struct {
func (plan *wrapInt8ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapInt8ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapInt8ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapInt8ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*int8Wrapper)(dst.(*int8))) return plan.next.Scan(src, (*int8Wrapper)(dst.(*int8)))
} }
type wrapInt16ScanPlan struct { type wrapInt16ScanPlan struct {
@ -738,8 +652,8 @@ type wrapInt16ScanPlan struct {
func (plan *wrapInt16ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapInt16ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapInt16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapInt16ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*int16Wrapper)(dst.(*int16))) return plan.next.Scan(src, (*int16Wrapper)(dst.(*int16)))
} }
type wrapInt32ScanPlan struct { type wrapInt32ScanPlan struct {
@ -748,8 +662,8 @@ type wrapInt32ScanPlan struct {
func (plan *wrapInt32ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapInt32ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapInt32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapInt32ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*int32Wrapper)(dst.(*int32))) return plan.next.Scan(src, (*int32Wrapper)(dst.(*int32)))
} }
type wrapInt64ScanPlan struct { type wrapInt64ScanPlan struct {
@ -758,8 +672,8 @@ type wrapInt64ScanPlan struct {
func (plan *wrapInt64ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapInt64ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapInt64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapInt64ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*int64Wrapper)(dst.(*int64))) return plan.next.Scan(src, (*int64Wrapper)(dst.(*int64)))
} }
type wrapIntScanPlan struct { type wrapIntScanPlan struct {
@ -768,8 +682,8 @@ type wrapIntScanPlan struct {
func (plan *wrapIntScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapIntScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapIntScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapIntScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*intWrapper)(dst.(*int))) return plan.next.Scan(src, (*intWrapper)(dst.(*int)))
} }
type wrapUint8ScanPlan struct { type wrapUint8ScanPlan struct {
@ -778,8 +692,8 @@ type wrapUint8ScanPlan struct {
func (plan *wrapUint8ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapUint8ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapUint8ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapUint8ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*uint8Wrapper)(dst.(*uint8))) return plan.next.Scan(src, (*uint8Wrapper)(dst.(*uint8)))
} }
type wrapUint16ScanPlan struct { type wrapUint16ScanPlan struct {
@ -788,8 +702,8 @@ type wrapUint16ScanPlan struct {
func (plan *wrapUint16ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapUint16ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapUint16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapUint16ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*uint16Wrapper)(dst.(*uint16))) return plan.next.Scan(src, (*uint16Wrapper)(dst.(*uint16)))
} }
type wrapUint32ScanPlan struct { type wrapUint32ScanPlan struct {
@ -798,8 +712,8 @@ type wrapUint32ScanPlan struct {
func (plan *wrapUint32ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapUint32ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapUint32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapUint32ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*uint32Wrapper)(dst.(*uint32))) return plan.next.Scan(src, (*uint32Wrapper)(dst.(*uint32)))
} }
type wrapUint64ScanPlan struct { type wrapUint64ScanPlan struct {
@ -808,8 +722,8 @@ type wrapUint64ScanPlan struct {
func (plan *wrapUint64ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapUint64ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapUint64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapUint64ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*uint64Wrapper)(dst.(*uint64))) return plan.next.Scan(src, (*uint64Wrapper)(dst.(*uint64)))
} }
type wrapUintScanPlan struct { type wrapUintScanPlan struct {
@ -818,8 +732,8 @@ type wrapUintScanPlan struct {
func (plan *wrapUintScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapUintScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapUintScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapUintScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*uintWrapper)(dst.(*uint))) return plan.next.Scan(src, (*uintWrapper)(dst.(*uint)))
} }
type wrapFloat32ScanPlan struct { type wrapFloat32ScanPlan struct {
@ -828,8 +742,8 @@ type wrapFloat32ScanPlan struct {
func (plan *wrapFloat32ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapFloat32ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapFloat32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapFloat32ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*float32Wrapper)(dst.(*float32))) return plan.next.Scan(src, (*float32Wrapper)(dst.(*float32)))
} }
type wrapFloat64ScanPlan struct { type wrapFloat64ScanPlan struct {
@ -838,8 +752,8 @@ type wrapFloat64ScanPlan struct {
func (plan *wrapFloat64ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapFloat64ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapFloat64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapFloat64ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*float64Wrapper)(dst.(*float64))) return plan.next.Scan(src, (*float64Wrapper)(dst.(*float64)))
} }
type wrapStringScanPlan struct { type wrapStringScanPlan struct {
@ -848,8 +762,8 @@ type wrapStringScanPlan struct {
func (plan *wrapStringScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapStringScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapStringScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*stringWrapper)(dst.(*string))) return plan.next.Scan(src, (*stringWrapper)(dst.(*string)))
} }
type wrapTimeScanPlan struct { type wrapTimeScanPlan struct {
@ -858,8 +772,8 @@ type wrapTimeScanPlan struct {
func (plan *wrapTimeScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapTimeScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapTimeScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapTimeScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*timeWrapper)(dst.(*time.Time))) return plan.next.Scan(src, (*timeWrapper)(dst.(*time.Time)))
} }
type wrapDurationScanPlan struct { type wrapDurationScanPlan struct {
@ -868,8 +782,8 @@ type wrapDurationScanPlan struct {
func (plan *wrapDurationScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapDurationScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapDurationScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapDurationScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*durationWrapper)(dst.(*time.Duration))) return plan.next.Scan(src, (*durationWrapper)(dst.(*time.Duration)))
} }
type wrapNetIPNetScanPlan struct { type wrapNetIPNetScanPlan struct {
@ -878,8 +792,8 @@ type wrapNetIPNetScanPlan struct {
func (plan *wrapNetIPNetScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapNetIPNetScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapNetIPNetScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapNetIPNetScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*netIPNetWrapper)(dst.(*net.IPNet))) return plan.next.Scan(src, (*netIPNetWrapper)(dst.(*net.IPNet)))
} }
type wrapNetIPScanPlan struct { type wrapNetIPScanPlan struct {
@ -888,8 +802,8 @@ type wrapNetIPScanPlan struct {
func (plan *wrapNetIPScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapNetIPScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapNetIPScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapNetIPScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*netIPWrapper)(dst.(*net.IP))) return plan.next.Scan(src, (*netIPWrapper)(dst.(*net.IP)))
} }
type wrapMapStringToPointerStringScanPlan struct { type wrapMapStringToPointerStringScanPlan struct {
@ -898,8 +812,8 @@ type wrapMapStringToPointerStringScanPlan struct {
func (plan *wrapMapStringToPointerStringScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapMapStringToPointerStringScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapMapStringToPointerStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapMapStringToPointerStringScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*mapStringToPointerStringWrapper)(dst.(*map[string]*string))) return plan.next.Scan(src, (*mapStringToPointerStringWrapper)(dst.(*map[string]*string)))
} }
type wrapMapStringToStringScanPlan struct { type wrapMapStringToStringScanPlan struct {
@ -908,8 +822,8 @@ type wrapMapStringToStringScanPlan struct {
func (plan *wrapMapStringToStringScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapMapStringToStringScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapMapStringToStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapMapStringToStringScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*mapStringToStringWrapper)(dst.(*map[string]string))) return plan.next.Scan(src, (*mapStringToStringWrapper)(dst.(*map[string]string)))
} }
type wrapByte16ScanPlan struct { type wrapByte16ScanPlan struct {
@ -918,8 +832,8 @@ type wrapByte16ScanPlan struct {
func (plan *wrapByte16ScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapByte16ScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapByte16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapByte16ScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*byte16Wrapper)(dst.(*[16]byte))) return plan.next.Scan(src, (*byte16Wrapper)(dst.(*[16]byte)))
} }
type wrapByteSliceScanPlan struct { type wrapByteSliceScanPlan struct {
@ -928,16 +842,19 @@ type wrapByteSliceScanPlan struct {
func (plan *wrapByteSliceScanPlan) SetNext(next ScanPlan) { plan.next = next } func (plan *wrapByteSliceScanPlan) SetNext(next ScanPlan) { plan.next = next }
func (plan *wrapByteSliceScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *wrapByteSliceScanPlan) Scan(src []byte, dst interface{}) error {
return plan.next.Scan(ci, oid, formatCode, src, (*byteSliceWrapper)(dst.(*[]byte))) return plan.next.Scan(src, (*byteSliceWrapper)(dst.(*[]byte)))
} }
type pointerEmptyInterfaceScanPlan struct { type pointerEmptyInterfaceScanPlan struct {
codec Codec codec Codec
ci *ConnInfo
oid uint32
formatCode int16
} }
func (plan *pointerEmptyInterfaceScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (plan *pointerEmptyInterfaceScanPlan) Scan(src []byte, dst interface{}) error {
value, err := plan.codec.DecodeValue(ci, oid, formatCode, src) value, err := plan.codec.DecodeValue(plan.ci, plan.oid, plan.formatCode, src)
if err != nil { if err != nil {
return err return err
} }
@ -948,45 +865,28 @@ func (plan *pointerEmptyInterfaceScanPlan) Scan(ci *ConnInfo, oid uint32, format
return nil return nil
} }
// PlanScan prepares a plan to scan a value into dst. // PlanScan prepares a plan to scan a value into target.
func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) ScanPlan { func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) ScanPlan {
if _, ok := dst.(*UndecodedBytes); ok { if _, ok := target.(*UndecodedBytes); ok {
return scanPlanAnyToUndecodedBytes{} return scanPlanAnyToUndecodedBytes{}
} }
switch formatCode { switch formatCode {
case BinaryFormatCode: case BinaryFormatCode:
switch dst.(type) { switch target.(type) {
case *string: case *string:
switch oid { switch oid {
case TextOID, VarcharOID: case TextOID, VarcharOID:
return scanPlanString{} return scanPlanString{}
} }
case *int64:
if oid == Int8OID {
return scanPlanBinaryInt64{}
}
case *float32:
if oid == Float4OID {
return scanPlanBinaryFloat32{}
}
case *float64:
if oid == Float8OID {
return scanPlanBinaryFloat64{}
}
case *[]byte:
switch oid {
case ByteaOID, TextOID, VarcharOID, JSONOID:
return scanPlanBinaryBytes{}
}
} }
case TextFormatCode: case TextFormatCode:
switch dst.(type) { switch target.(type) {
case *string: case *string:
return scanPlanString{} return scanPlanString{}
case *[]byte: case *[]byte:
if oid != ByteaOID { if oid != ByteaOID {
return scanPlanBinaryBytes{} return scanPlanAnyTextToBytes{}
} }
case TextScanner: case TextScanner:
return scanPlanTextAnyToTextScanner{} return scanPlanTextAnyToTextScanner{}
@ -995,47 +895,43 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) Scan
var dt *DataType var dt *DataType
if oid == 0 { if dataType, ok := ci.DataTypeForOID(oid); ok {
if dataType, ok := ci.DataTypeForValue(dst); ok { dt = dataType
dt = dataType } else if dataType, ok := ci.DataTypeForValue(target); ok {
oid = dt.OID // Preserve assumed OID in case we are recursively called below. dt = dataType
} oid = dt.OID // Preserve assumed OID in case we are recursively called below.
} else {
if dataType, ok := ci.DataTypeForOID(oid); ok {
dt = dataType
}
} }
if dt != nil { if dt != nil {
if plan := dt.Codec.PlanScan(ci, oid, formatCode, dst, false); plan != nil { if plan := dt.Codec.PlanScan(ci, oid, formatCode, target, false); plan != nil {
return plan return plan
} }
for _, f := range ci.TryWrapScanPlanFuncs { if _, ok := target.(*interface{}); ok {
if wrapperPlan, nextDst, ok := f(dst); ok { return &pointerEmptyInterfaceScanPlan{codec: dt.Codec, ci: ci, oid: oid, formatCode: formatCode}
if nextPlan := ci.PlanScan(oid, formatCode, nextDst); nextPlan != nil { }
if _, ok := nextPlan.(scanPlanReflection); !ok { // avoid fallthrough -- this will go away when old system removed.
wrapperPlan.SetNext(nextPlan) if _, ok := target.(sql.Scanner); ok {
return wrapperPlan return &scanPlanCodecSQLScanner{c: dt.Codec, ci: ci, oid: oid, formatCode: formatCode}
} }
}
for _, f := range ci.TryWrapScanPlanFuncs {
if wrapperPlan, nextDst, ok := f(target); ok {
if nextPlan := ci.PlanScan(oid, formatCode, nextDst); nextPlan != nil {
if _, failed := nextPlan.(*scanPlanFail); !failed {
wrapperPlan.SetNext(nextPlan)
return wrapperPlan
} }
} }
} }
if _, ok := dst.(*interface{}); ok {
return &pointerEmptyInterfaceScanPlan{codec: dt.Codec}
}
if _, ok := dst.(sql.Scanner); ok {
return &scanPlanCodecSQLScanner{c: dt.Codec}
}
} }
if _, ok := dst.(sql.Scanner); ok { if _, ok := target.(sql.Scanner); ok {
return scanPlanSQLScanner{} return &scanPlanSQLScanner{formatCode: formatCode}
} }
return scanPlanReflection{} return &scanPlanFail{oid: oid, formatCode: formatCode}
} }
func (ci *ConnInfo) Scan(oid uint32, formatCode int16, src []byte, dst interface{}) error { func (ci *ConnInfo) Scan(oid uint32, formatCode int16, src []byte, dst interface{}) error {
@ -1044,7 +940,7 @@ func (ci *ConnInfo) Scan(oid uint32, formatCode int16, src []byte, dst interface
} }
plan := ci.PlanScan(oid, formatCode, dst) plan := ci.PlanScan(oid, formatCode, dst)
return plan.Scan(ci, oid, formatCode, src, dst) return plan.Scan(src, dst)
} }
func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest interface{}) error { func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest interface{}) error {
@ -1073,7 +969,7 @@ func codecScan(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte,
if scanPlan == nil { if scanPlan == nil {
return fmt.Errorf("PlanScan did not find a plan") return fmt.Errorf("PlanScan did not find a plan")
} }
return scanPlan.Scan(ci, oid, format, src, dst) return scanPlan.Scan(src, dst)
} }
func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) {

View File

@ -118,18 +118,10 @@ func TestConnInfoScanUnknownOIDToStringsAndBytes(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte("foo"), b) assert.Equal(t, []byte("foo"), b)
err = ci.Scan(unknownOID, pgx.BinaryFormatCode, srcBuf, &b)
assert.NoError(t, err)
assert.Equal(t, []byte("foo"), b)
var rb _byteSlice var rb _byteSlice
err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rb) err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rb)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte("foo"), []byte(rb)) assert.Equal(t, []byte("foo"), []byte(rb))
err = ci.Scan(unknownOID, pgx.BinaryFormatCode, srcBuf, &b)
assert.NoError(t, err)
assert.Equal(t, []byte("foo"), []byte(rb))
} }
type pgCustomType struct { type pgCustomType struct {
@ -219,21 +211,6 @@ func BenchmarkConnInfoScanInt4IntoBinaryDecoder(b *testing.B) {
} }
} }
func TestScanPlanBinaryInt32ScanChangedType(t *testing.T) {
ci := pgtype.NewConnInfo()
src := []byte{0, 0, 0, 42}
var v int32
plan := ci.PlanScan(pgtype.Int4OID, pgtype.BinaryFormatCode, &v)
err := plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v)
require.NoError(t, err)
require.EqualValues(t, 42, v)
var d pgtype.Int4
err = plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &d)
require.EqualError(t, err, pgtype.ErrScanTargetTypeChanged.Error())
}
func BenchmarkConnInfoScanInt4IntoGoInt32(b *testing.B) { func BenchmarkConnInfoScanInt4IntoGoInt32(b *testing.B) {
ci := pgtype.NewConnInfo() ci := pgtype.NewConnInfo()
src := []byte{0, 0, 0, 42} src := []byte{0, 0, 0, 42}
@ -260,7 +237,7 @@ func BenchmarkScanPlanScanInt4IntoBinaryDecoder(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
v = pgtype.Int4{} v = pgtype.Int4{}
err := plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) err := plan.Scan(src, &v)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
@ -279,7 +256,7 @@ func BenchmarkScanPlanScanInt4IntoGoInt32(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
v = 0 v = 0
err := plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) err := plan.Scan(src, &v)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }

View File

@ -77,7 +77,7 @@ func (dst *Point) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToPointScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToPointScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -214,7 +214,7 @@ func (c PointCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []by
type scanPlanBinaryPointToPointScanner struct{} type scanPlanBinaryPointToPointScanner struct{}
func (scanPlanBinaryPointToPointScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryPointToPointScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PointScanner) scanner := (dst).(PointScanner)
if src == nil { if src == nil {
@ -236,7 +236,7 @@ func (scanPlanBinaryPointToPointScanner) Scan(ci *ConnInfo, oid uint32, formatCo
type scanPlanTextAnyToPointScanner struct{} type scanPlanTextAnyToPointScanner struct{}
func (scanPlanTextAnyToPointScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToPointScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PointScanner) scanner := (dst).(PointScanner)
if src == nil { if src == nil {

View File

@ -42,7 +42,7 @@ func (p *Polygon) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToPolygonScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), p) return scanPlanTextAnyToPolygonScanner{}.Scan([]byte(src), p)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -158,7 +158,7 @@ func (PolygonCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inte
type scanPlanBinaryPolygonToPolygonScanner struct{} type scanPlanBinaryPolygonToPolygonScanner struct{}
func (scanPlanBinaryPolygonToPolygonScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryPolygonToPolygonScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PolygonScanner) scanner := (dst).(PolygonScanner)
if src == nil { if src == nil {
@ -193,7 +193,7 @@ func (scanPlanBinaryPolygonToPolygonScanner) Scan(ci *ConnInfo, oid uint32, form
type scanPlanTextAnyToPolygonScanner struct{} type scanPlanTextAnyToPolygonScanner struct{}
func (scanPlanTextAnyToPolygonScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToPolygonScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(PolygonScanner) scanner := (dst).(PolygonScanner)
if src == nil { if src == nil {

View File

@ -72,7 +72,7 @@ func (QCharCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interf
type scanPlanQcharCodecByte struct{} type scanPlanQcharCodecByte struct{}
func (scanPlanQcharCodecByte) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanQcharCodecByte) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -94,7 +94,7 @@ func (scanPlanQcharCodecByte) Scan(ci *ConnInfo, oid uint32, formatCode int16, s
type scanPlanQcharCodecRune struct{} type scanPlanQcharCodecRune struct{}
func (scanPlanQcharCodecRune) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanQcharCodecRune) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }

View File

@ -189,7 +189,7 @@ func (c TextCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt
type scanPlanTextAnyToString struct{} type scanPlanTextAnyToString struct{}
func (scanPlanTextAnyToString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToString) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -202,7 +202,7 @@ func (scanPlanTextAnyToString) Scan(ci *ConnInfo, oid uint32, formatCode int16,
type scanPlanAnyToNewByteSlice struct{} type scanPlanAnyToNewByteSlice struct{}
func (scanPlanAnyToNewByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanAnyToNewByteSlice) Scan(src []byte, dst interface{}) error {
p := (dst).(*[]byte) p := (dst).(*[]byte)
if src == nil { if src == nil {
*p = nil *p = nil
@ -216,7 +216,7 @@ func (scanPlanAnyToNewByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16
type scanPlanTextAnyToRune struct{} type scanPlanTextAnyToRune struct{}
func (scanPlanTextAnyToRune) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToRune) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -234,7 +234,7 @@ func (scanPlanTextAnyToRune) Scan(ci *ConnInfo, oid uint32, formatCode int16, sr
type scanPlanTextAnyToTextScanner struct{} type scanPlanTextAnyToTextScanner struct{}
func (scanPlanTextAnyToTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToTextScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TextScanner) scanner := (dst).(TextScanner)
if src == nil { if src == nil {

View File

@ -53,7 +53,7 @@ func (dst *TID) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToTIDScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) return scanPlanTextAnyToTIDScanner{}.Scan([]byte(src), dst)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -152,7 +152,7 @@ func (TIDCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfac
type scanPlanBinaryTIDToTIDScanner struct{} type scanPlanBinaryTIDToTIDScanner struct{}
func (scanPlanBinaryTIDToTIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryTIDToTIDScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TIDScanner) scanner := (dst).(TIDScanner)
if src == nil { if src == nil {
@ -172,7 +172,7 @@ func (scanPlanBinaryTIDToTIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode i
type scanPlanBinaryTIDToTextScanner struct{} type scanPlanBinaryTIDToTextScanner struct{}
func (scanPlanBinaryTIDToTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryTIDToTextScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TextScanner) scanner := (dst).(TextScanner)
if src == nil { if src == nil {
@ -194,7 +194,7 @@ func (scanPlanBinaryTIDToTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToTIDScanner struct{} type scanPlanTextAnyToTIDScanner struct{}
func (scanPlanTextAnyToTIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToTIDScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TIDScanner) scanner := (dst).(TIDScanner)
if src == nil { if src == nil {

View File

@ -45,7 +45,7 @@ func (t *Time) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextAnyToTimeScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), t) return scanPlanTextAnyToTimeScanner{}.Scan([]byte(src), t)
} }
return fmt.Errorf("cannot scan %T", src) return fmt.Errorf("cannot scan %T", src)
@ -149,7 +149,7 @@ func (TimeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryTimeToTimeScanner struct{} type scanPlanBinaryTimeToTimeScanner struct{}
func (scanPlanBinaryTimeToTimeScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryTimeToTimeScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimeScanner) scanner := (dst).(TimeScanner)
if src == nil { if src == nil {
@ -167,7 +167,7 @@ func (scanPlanBinaryTimeToTimeScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToTimeScanner struct{} type scanPlanTextAnyToTimeScanner struct{}
func (scanPlanTextAnyToTimeScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToTimeScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimeScanner) scanner := (dst).(TimeScanner)
if src == nil { if src == nil {

View File

@ -44,7 +44,7 @@ func (ts *Timestamp) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextTimestampToTimestampScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), ts) return scanPlanTextTimestampToTimestampScanner{}.Scan([]byte(src), ts)
case time.Time: case time.Time:
*ts = Timestamp{Time: src, Valid: true} *ts = Timestamp{Time: src, Valid: true}
return nil return nil
@ -172,7 +172,7 @@ func (TimestampCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target in
type scanPlanBinaryTimestampToTimestampScanner struct{} type scanPlanBinaryTimestampToTimestampScanner struct{}
func (scanPlanBinaryTimestampToTimestampScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryTimestampToTimestampScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimestampScanner) scanner := (dst).(TimestampScanner)
if src == nil { if src == nil {
@ -204,7 +204,7 @@ func (scanPlanBinaryTimestampToTimestampScanner) Scan(ci *ConnInfo, oid uint32,
type scanPlanTextTimestampToTimestampScanner struct{} type scanPlanTextTimestampToTimestampScanner struct{}
func (scanPlanTextTimestampToTimestampScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextTimestampToTimestampScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimestampScanner) scanner := (dst).(TimestampScanner)
if src == nil { if src == nil {

View File

@ -52,6 +52,6 @@ func TestTimestampCodecDecodeTextInvalid(t *testing.T) {
c := &pgtype.TimestampCodec{} c := &pgtype.TimestampCodec{}
var ts pgtype.Timestamp var ts pgtype.Timestamp
plan := c.PlanScan(nil, pgtype.TimestampOID, pgtype.TextFormatCode, &ts, false) plan := c.PlanScan(nil, pgtype.TimestampOID, pgtype.TextFormatCode, &ts, false)
err := plan.Scan(nil, pgtype.TimestampOID, pgtype.TextFormatCode, []byte(`eeeee`), &ts) err := plan.Scan([]byte(`eeeee`), &ts)
require.Error(t, err) require.Error(t, err)
} }

View File

@ -53,7 +53,7 @@ func (tstz *Timestamptz) Scan(src interface{}) error {
switch src := src.(type) { switch src := src.(type) {
case string: case string:
return scanPlanTextTimestamptzToTimestamptzScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), tstz) return scanPlanTextTimestamptzToTimestamptzScanner{}.Scan([]byte(src), tstz)
case time.Time: case time.Time:
*tstz = Timestamptz{Time: src, Valid: true} *tstz = Timestamptz{Time: src, Valid: true}
return nil return nil
@ -220,7 +220,7 @@ func (TimestamptzCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target
type scanPlanBinaryTimestamptzToTimestamptzScanner struct{} type scanPlanBinaryTimestamptzToTimestamptzScanner struct{}
func (scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimestamptzScanner) scanner := (dst).(TimestamptzScanner)
if src == nil { if src == nil {
@ -252,7 +252,7 @@ func (scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(ci *ConnInfo, oid uint
type scanPlanTextTimestamptzToTimestamptzScanner struct{} type scanPlanTextTimestamptzToTimestamptzScanner struct{}
func (scanPlanTextTimestamptzToTimestamptzScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(TimestamptzScanner) scanner := (dst).(TimestamptzScanner)
if src == nil { if src == nil {

View File

@ -52,7 +52,7 @@ func TestTimestamptzDecodeTextInvalid(t *testing.T) {
c := &pgtype.TimestamptzCodec{} c := &pgtype.TimestamptzCodec{}
var tstz pgtype.Timestamptz var tstz pgtype.Timestamptz
plan := c.PlanScan(nil, pgtype.TimestamptzOID, pgtype.TextFormatCode, &tstz, false) plan := c.PlanScan(nil, pgtype.TimestamptzOID, pgtype.TextFormatCode, &tstz, false)
err := plan.Scan(nil, pgtype.TimestamptzOID, pgtype.TextFormatCode, []byte(`eeeee`), &tstz) err := plan.Scan([]byte(`eeeee`), &tstz)
require.Error(t, err) require.Error(t, err)
} }

View File

@ -246,7 +246,7 @@ func (c Uint32Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []b
type scanPlanBinaryUint32ToUint32 struct{} type scanPlanBinaryUint32ToUint32 struct{}
func (scanPlanBinaryUint32ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryUint32ToUint32) Scan(src []byte, dst interface{}) error {
if src == nil { if src == nil {
return fmt.Errorf("cannot scan null into %T", dst) return fmt.Errorf("cannot scan null into %T", dst)
} }
@ -263,7 +263,7 @@ func (scanPlanBinaryUint32ToUint32) Scan(ci *ConnInfo, oid uint32, formatCode in
type scanPlanBinaryUint32ToUint32Scanner struct{} type scanPlanBinaryUint32ToUint32Scanner struct{}
func (scanPlanBinaryUint32ToUint32Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryUint32ToUint32Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Uint32Scanner) s, ok := (dst).(Uint32Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged
@ -284,7 +284,7 @@ func (scanPlanBinaryUint32ToUint32Scanner) Scan(ci *ConnInfo, oid uint32, format
type scanPlanTextAnyToUint32Scanner struct{} type scanPlanTextAnyToUint32Scanner struct{}
func (scanPlanTextAnyToUint32Scanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUint32Scanner) Scan(src []byte, dst interface{}) error {
s, ok := (dst).(Uint32Scanner) s, ok := (dst).(Uint32Scanner)
if !ok { if !ok {
return ErrScanTargetTypeChanged return ErrScanTargetTypeChanged

View File

@ -186,7 +186,7 @@ func (UUIDCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa
type scanPlanBinaryUUIDToUUIDScanner struct{} type scanPlanBinaryUUIDToUUIDScanner struct{}
func (scanPlanBinaryUUIDToUUIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanBinaryUUIDToUUIDScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(UUIDScanner) scanner := (dst).(UUIDScanner)
if src == nil { if src == nil {
@ -205,7 +205,7 @@ func (scanPlanBinaryUUIDToUUIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode
type scanPlanTextAnyToUUIDScanner struct{} type scanPlanTextAnyToUUIDScanner struct{}
func (scanPlanTextAnyToUUIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { func (scanPlanTextAnyToUUIDScanner) Scan(src []byte, dst interface{}) error {
scanner := (dst).(UUIDScanner) scanner := (dst).(UUIDScanner)
if src == nil { if src == nil {

11
rows.go
View File

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"reflect"
"time" "time"
"github.com/jackc/pgproto3/v2" "github.com/jackc/pgproto3/v2"
@ -111,6 +112,7 @@ type connRows struct {
multiResultReader *pgconn.MultiResultReader multiResultReader *pgconn.MultiResultReader
scanPlans []pgtype.ScanPlan scanPlans []pgtype.ScanPlan
scanTypes []reflect.Type
} }
func (rows *connRows) FieldDescriptions() []pgproto3.FieldDescription { func (rows *connRows) FieldDescriptions() []pgproto3.FieldDescription {
@ -208,8 +210,10 @@ func (rows *connRows) Scan(dest ...interface{}) error {
if rows.scanPlans == nil { if rows.scanPlans == nil {
rows.scanPlans = make([]pgtype.ScanPlan, len(values)) rows.scanPlans = make([]pgtype.ScanPlan, len(values))
rows.scanTypes = make([]reflect.Type, len(values))
for i := range dest { for i := range dest {
rows.scanPlans[i] = ci.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) rows.scanPlans[i] = ci.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i])
rows.scanTypes[i] = reflect.TypeOf(dest[i])
} }
} }
@ -218,7 +222,12 @@ func (rows *connRows) Scan(dest ...interface{}) error {
continue continue
} }
err := rows.scanPlans[i].Scan(ci, fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, values[i], dst) if rows.scanTypes[i] != reflect.TypeOf(dst) {
rows.scanPlans[i] = ci.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i])
rows.scanTypes[i] = reflect.TypeOf(dest[i])
}
err := rows.scanPlans[i].Scan(values[i], dst)
if err != nil { if err != nil {
err = ScanArgError{ColumnIndex: i, Err: err} err = ScanArgError{ColumnIndex: i, Err: err}
rows.fatal(err) rows.fatal(err)

View File

@ -605,21 +605,21 @@ func (r *Rows) Next(dest []driver.Value) error {
var d bool var d bool
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return d, err return d, err
} }
case pgtype.ByteaOID: case pgtype.ByteaOID:
var d []byte var d []byte
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return d, err return d, err
} }
case pgtype.CIDOID, pgtype.OIDOID, pgtype.XIDOID: case pgtype.CIDOID, pgtype.OIDOID, pgtype.XIDOID:
var d pgtype.Uint32 var d pgtype.Uint32
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -629,7 +629,7 @@ func (r *Rows) Next(dest []driver.Value) error {
var d pgtype.Date var d pgtype.Date
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -639,42 +639,42 @@ func (r *Rows) Next(dest []driver.Value) error {
var d float32 var d float32
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return float64(d), err return float64(d), err
} }
case pgtype.Float8OID: case pgtype.Float8OID:
var d float64 var d float64
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return d, err return d, err
} }
case pgtype.Int2OID: case pgtype.Int2OID:
var d int16 var d int16
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return int64(d), err return int64(d), err
} }
case pgtype.Int4OID: case pgtype.Int4OID:
var d int32 var d int32
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return int64(d), err return int64(d), err
} }
case pgtype.Int8OID: case pgtype.Int8OID:
var d int64 var d int64
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return d, err return d, err
} }
case pgtype.JSONOID, pgtype.JSONBOID: case pgtype.JSONOID, pgtype.JSONBOID:
var d []byte var d []byte
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -684,7 +684,7 @@ func (r *Rows) Next(dest []driver.Value) error {
var d pgtype.Timestamp var d pgtype.Timestamp
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -694,7 +694,7 @@ func (r *Rows) Next(dest []driver.Value) error {
var d pgtype.Timestamptz var d pgtype.Timestamptz
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -704,7 +704,7 @@ func (r *Rows) Next(dest []driver.Value) error {
var d string var d string
scanPlan := ci.PlanScan(dataTypeOID, format, &d) scanPlan := ci.PlanScan(dataTypeOID, format, &d)
r.valueFuncs[i] = func(src []byte) (driver.Value, error) { r.valueFuncs[i] = func(src []byte) (driver.Value, error) {
err := scanPlan.Scan(ci, dataTypeOID, format, src, &d) err := scanPlan.Scan(src, &d)
return d, err return d, err
} }
} }