diff --git a/pgtype/array_codec.go b/pgtype/array_codec.go index 1e506a43..4cc7e84c 100644 --- a/pgtype/array_codec.go +++ b/pgtype/array_codec.go @@ -204,7 +204,12 @@ func (c *ArrayCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target int 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 { @@ -244,7 +249,7 @@ func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, arr elemSrc = src[rp : rp+elemLen] rp += elemLen } - err = elementScanPlan.Scan(ci, c.ElementOID, BinaryFormatCode, elemSrc, elem) + err = elementScanPlan.Scan(elemSrc, elem) if err != nil { return err } @@ -286,7 +291,7 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array elemSrc = []byte(s) } - err = elementScanPlan.Scan(ci, c.ElementOID, TextFormatCode, elemSrc, elem) + err = elementScanPlan.Scan(elemSrc, elem) if err != nil { return err } @@ -295,15 +300,23 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array 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 { - c := (*ArrayCodec)(spac) +func (spac *scanPlanArrayCodec) Scan(src []byte, dst interface{}) error { + c := spac.arrayCodec + ci := spac.ci + oid := spac.oid + formatCode := spac.formatCode array, err := makeArraySetter(dst) if err != nil { newPlan := ci.PlanScan(oid, formatCode, dst) - return newPlan.Scan(ci, oid, formatCode, src, dst) + return newPlan.Scan(src, dst) } if src == nil { diff --git a/pgtype/bits.go b/pgtype/bits.go index 9b499c35..541a3a6b 100644 --- a/pgtype/bits.go +++ b/pgtype/bits.go @@ -41,7 +41,7 @@ func (dst *Bits) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToBitsScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToBitsScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -182,7 +182,7 @@ func (scanPlanBinaryBitsToBitsScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/bool.go b/pgtype/bool.go index 71ce09b6..5aa06870 100644 --- a/pgtype/bool.go +++ b/pgtype/bool.go @@ -238,7 +238,7 @@ func (c BoolCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt 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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged @@ -299,7 +299,7 @@ func (scanPlanBinaryBoolToBoolScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if !ok { return ErrScanTargetTypeChanged diff --git a/pgtype/box.go b/pgtype/box.go index 80e1bd19..6c637308 100644 --- a/pgtype/box.go +++ b/pgtype/box.go @@ -42,7 +42,7 @@ func (dst *Box) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToBoxScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToBoxScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -173,7 +173,7 @@ func (scanPlanBinaryBoxToBoxScanner) Scan(ci *ConnInfo, oid uint32, formatCode i 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) if src == nil { diff --git a/pgtype/builtin_wrappers.go b/pgtype/builtin_wrappers.go index 9df28f55..fe58eee0 100644 --- a/pgtype/builtin_wrappers.go +++ b/pgtype/builtin_wrappers.go @@ -494,6 +494,8 @@ func (w netIPNetWrapper) InetValue() (Inet, error) { type netIPWrapper net.IP +func (w netIPWrapper) SkipUnderlyingTypePlan() {} + func (w *netIPWrapper) ScanInet(v Inet) error { if !v.Valid { *w = nil @@ -578,6 +580,26 @@ func (w byte16Wrapper) UUIDValue() (UUID, error) { 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 { if !v.Valid { *w = nil diff --git a/pgtype/bytea.go b/pgtype/bytea.go index 2eb50610..501e0c59 100644 --- a/pgtype/bytea.go +++ b/pgtype/bytea.go @@ -49,7 +49,7 @@ type UndecodedBytes []byte 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) if src == nil { *dstBuf = nil @@ -170,7 +170,7 @@ func (ByteaCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interf 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) if src == nil { *dstBuf = nil @@ -184,14 +184,14 @@ func (scanPlanBinaryBytesToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int1 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) return scanner.ScanBytes(src) } 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) if src == nil { *dstBuf = nil @@ -209,7 +209,7 @@ func (scanPlanTextByteaToBytes) Scan(ci *ConnInfo, oid uint32, formatCode int16, 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) buf, err := decodeHexBytea(src) if err != nil { diff --git a/pgtype/circle.go b/pgtype/circle.go index ae8aa352..8e06de88 100644 --- a/pgtype/circle.go +++ b/pgtype/circle.go @@ -43,7 +43,7 @@ func (dst *Circle) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToCircleScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToCircleScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -185,7 +185,7 @@ func (scanPlanBinaryCircleToCircleScanner) Scan(ci *ConnInfo, oid uint32, format 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) if src == nil { diff --git a/pgtype/date.go b/pgtype/date.go index fde66745..adfa0999 100644 --- a/pgtype/date.go +++ b/pgtype/date.go @@ -47,7 +47,7 @@ func (dst *Date) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToDateScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToDateScanner{}.Scan([]byte(src), dst) case time.Time: *dst = Date{Time: src, Valid: true} return nil @@ -216,7 +216,7 @@ func (DateCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa 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) if src == nil { @@ -242,7 +242,7 @@ func (scanPlanBinaryDateToDateScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/enum_codec.go b/pgtype/enum_codec.go index d405245f..3bf29f4a 100644 --- a/pgtype/enum_codec.go +++ b/pgtype/enum_codec.go @@ -86,7 +86,7 @@ type scanPlanTextAnyToEnumString struct { 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 { return fmt.Errorf("cannot scan null into %T", dst) } @@ -101,7 +101,7 @@ type scanPlanTextAnyToEnumTextScanner struct { 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) if src == nil { diff --git a/pgtype/float4.go b/pgtype/float4.go index 7699f656..db9b2215 100644 --- a/pgtype/float4.go +++ b/pgtype/float4.go @@ -164,7 +164,7 @@ func (Float4Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter 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 { 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{} -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) if src == nil { @@ -199,7 +199,7 @@ func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, forma 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) if src == nil { @@ -222,7 +222,7 @@ func (scanPlanBinaryFloat4ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatC 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 { return fmt.Errorf("cannot scan null into %T", dst) } diff --git a/pgtype/float8.go b/pgtype/float8.go index 86638ab1..96dcb0f3 100644 --- a/pgtype/float8.go +++ b/pgtype/float8.go @@ -202,7 +202,7 @@ func (Float8Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter 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 { 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{} -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) if src == nil { @@ -237,7 +237,7 @@ func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, forma 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) if src == nil { @@ -260,7 +260,7 @@ func (scanPlanBinaryFloat8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatC 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 { 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{} -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) if src == nil { diff --git a/pgtype/hstore.go b/pgtype/hstore.go index 6ff8164c..dc5caa84 100644 --- a/pgtype/hstore.go +++ b/pgtype/hstore.go @@ -43,7 +43,7 @@ func (h *Hstore) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToHstoreScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), h) + return scanPlanTextAnyToHstoreScanner{}.Scan([]byte(src), h) } 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{} -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) if src == nil { @@ -213,7 +213,7 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(ci *ConnInfo, oid uint32, format } var value Text - err := scanPlanTextAnyToTextScanner{}.Scan(ci, TextOID, TextFormatCode, valueBuf, &value) + err := scanPlanTextAnyToTextScanner{}.Scan(valueBuf, &value) if err != nil { return err } @@ -230,7 +230,7 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(ci *ConnInfo, oid uint32, format 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) if src == nil { diff --git a/pgtype/inet.go b/pgtype/inet.go index f88d1712..9530d1a2 100644 --- a/pgtype/inet.go +++ b/pgtype/inet.go @@ -46,7 +46,7 @@ func (dst *Inet) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToInetScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToInetScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -211,7 +211,7 @@ func (scanPlanBinaryInetToInetScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/int.go b/pgtype/int.go index 553d4dd0..a5b1c0a5 100644 --- a/pgtype/int.go +++ b/pgtype/int.go @@ -292,7 +292,7 @@ func (c Int2Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt 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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged @@ -829,7 +829,7 @@ func (c Int4Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt 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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged @@ -1377,7 +1377,7 @@ func (c Int8Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt 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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged @@ -1677,7 +1677,7 @@ func (scanPlanBinaryInt8ToInt64Scanner) Scan(ci *ConnInfo, oid uint32, formatCod 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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged diff --git a/pgtype/int.go.erb b/pgtype/int.go.erb index 6aecb761..8524136f 100644 --- a/pgtype/int.go.erb +++ b/pgtype/int.go.erb @@ -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| %> 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 { 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{} -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 { 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 %> 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 { 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{} -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 { 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 %> 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) if !ok { return ErrScanTargetTypeChanged @@ -455,7 +455,7 @@ func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(ci *ConnInfo, oid ].each do |type_suffix, bit_size| %> 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 { 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{} -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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged diff --git a/pgtype/interval.go b/pgtype/interval.go index 41216f37..a20266eb 100644 --- a/pgtype/interval.go +++ b/pgtype/interval.go @@ -51,7 +51,7 @@ func (interval *Interval) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToIntervalScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), interval) + return scanPlanTextAnyToIntervalScanner{}.Scan([]byte(src), interval) } 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{} -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) if src == nil { @@ -191,7 +191,7 @@ func (scanPlanBinaryIntervalToIntervalScanner) Scan(ci *ConnInfo, oid uint32, fo 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) if src == nil { diff --git a/pgtype/json.go b/pgtype/json.go index 510b638e..cd8b8ec9 100644 --- a/pgtype/json.go +++ b/pgtype/json.go @@ -65,7 +65,7 @@ func (JSONCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa 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 = string(src) return nil @@ -73,7 +73,7 @@ func (scanPlanAnyToString) Scan(ci *ConnInfo, oid uint32, formatCode int16, src 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) if src == nil { *dstBuf = nil @@ -87,14 +87,14 @@ func (scanPlanJSONToByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16, 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) return scanner.ScanBytes(src) } 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 { dstValue := reflect.ValueOf(dst) if dstValue.Kind() == reflect.Ptr { diff --git a/pgtype/jsonb.go b/pgtype/jsonb.go index 6e329150..07ea58bc 100644 --- a/pgtype/jsonb.go +++ b/pgtype/jsonb.go @@ -57,9 +57,9 @@ type scanPlanJSONBCodecBinaryUnwrapper struct { 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 { - return plan.textPlan.Scan(ci, oid, formatCode, src, dst) + return plan.textPlan.Scan(src, dst) } 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 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) { diff --git a/pgtype/line.go b/pgtype/line.go index db584862..acae903b 100644 --- a/pgtype/line.go +++ b/pgtype/line.go @@ -46,7 +46,7 @@ func (line *Line) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToLineScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), line) + return scanPlanTextAnyToLineScanner{}.Scan([]byte(src), line) } 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{} -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) if src == nil { @@ -173,7 +173,7 @@ func (scanPlanBinaryLineToLineScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/lseg.go b/pgtype/lseg.go index 26730e85..471b36b2 100644 --- a/pgtype/lseg.go +++ b/pgtype/lseg.go @@ -42,7 +42,7 @@ func (lseg *Lseg) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToLsegScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), lseg) + return scanPlanTextAnyToLsegScanner{}.Scan([]byte(src), lseg) } 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{} -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) if src == nil { @@ -173,7 +173,7 @@ func (scanPlanBinaryLsegToLsegScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/macaddr.go b/pgtype/macaddr.go index 0ac003ae..5b42811a 100644 --- a/pgtype/macaddr.go +++ b/pgtype/macaddr.go @@ -101,7 +101,7 @@ func (MacaddrCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inte 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) if src == nil { *dstBuf = nil @@ -115,7 +115,7 @@ func (scanPlanBinaryMacaddrToHardwareAddr) Scan(ci *ConnInfo, oid uint32, format 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) if src == nil { return scanner.ScanText(Text{}) @@ -126,7 +126,7 @@ func (scanPlanBinaryMacaddrToTextScanner) Scan(ci *ConnInfo, oid uint32, formatC 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) if src == nil { diff --git a/pgtype/numeric.go b/pgtype/numeric.go index 435c9618..5bdbd4d5 100644 --- a/pgtype/numeric.go +++ b/pgtype/numeric.go @@ -175,7 +175,7 @@ func (n *Numeric) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToNumericScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), n) + return scanPlanTextAnyToNumericScanner{}.Scan([]byte(src), n) } 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{} -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) if src == nil { @@ -628,7 +628,7 @@ func (scanPlanBinaryNumericToNumericScanner) Scan(ci *ConnInfo, oid uint32, form 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) if src == nil { @@ -637,7 +637,7 @@ func (scanPlanBinaryNumericToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, form var n Numeric - err := scanPlanBinaryNumericToNumericScanner{}.Scan(ci, oid, formatCode, src, &n) + err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n) if err != nil { return err } @@ -652,7 +652,7 @@ func (scanPlanBinaryNumericToFloat64Scanner) Scan(ci *ConnInfo, oid uint32, form 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) if src == nil { @@ -661,7 +661,7 @@ func (scanPlanBinaryNumericToInt64Scanner) Scan(ci *ConnInfo, oid uint32, format var n Numeric - err := scanPlanBinaryNumericToNumericScanner{}.Scan(ci, oid, formatCode, src, &n) + err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n) if err != nil { return err } @@ -680,7 +680,7 @@ func (scanPlanBinaryNumericToInt64Scanner) Scan(ci *ConnInfo, oid uint32, format 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) if src == nil { diff --git a/pgtype/numeric_test.go b/pgtype/numeric_test.go index 0d89dc2d..c74fb9a3 100644 --- a/pgtype/numeric_test.go +++ b/pgtype/numeric_test.go @@ -64,7 +64,7 @@ func mustParseNumeric(t *testing.T, src string) pgtype.Numeric { var n pgtype.Numeric plan := pgtype.NumericCodec{}.PlanScan(nil, pgtype.NumericOID, pgtype.TextFormatCode, &n, false) 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) return n } diff --git a/pgtype/path.go b/pgtype/path.go index be7daaa0..62a23219 100644 --- a/pgtype/path.go +++ b/pgtype/path.go @@ -43,7 +43,7 @@ func (path *Path) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToPathScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), path) + return scanPlanTextAnyToPathScanner{}.Scan([]byte(src), path) } 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{} -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) if src == nil { @@ -211,7 +211,7 @@ func (scanPlanBinaryPathToPathScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 73bd249c..150f1a23 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -3,10 +3,8 @@ package pgtype import ( "database/sql" "database/sql/driver" - "encoding/binary" "errors" "fmt" - "math" "net" "reflect" "time" @@ -198,14 +196,14 @@ func NewConnInfo() *ConnInfo { TryWrapEncodePlanFuncs: []TryWrapEncodePlanFunc{ TryWrapDerefPointerEncodePlan, - TryWrapFindUnderlyingTypeEncodePlan, TryWrapBuiltinTypeEncodePlan, + TryWrapFindUnderlyingTypeEncodePlan, }, TryWrapScanPlanFuncs: []TryWrapScanPlanFunc{ TryPointerPointerScanPlan, - TryFindUnderlyingTypeScanPlan, TryWrapBuiltinTypeScanPlan, + TryFindUnderlyingTypeScanPlan, }, } @@ -409,22 +407,19 @@ type EncodePlan interface { // ScanPlan is a precompiled plan to scan into a type of destination. type ScanPlan interface { - // Scan scans src into dst. If the dst type has changed in an incompatible way a ScanPlan should automatically - // replan and scan. - Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error + // Scan scans src into target. + Scan(src []byte, target interface{}) error } -type scanPlanDstResultDecoder struct{} - -func (scanPlanDstResultDecoder) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - newPlan := ci.PlanScan(oid, formatCode, dst) - return newPlan.Scan(ci, oid, formatCode, src, dst) +type scanPlanCodecSQLScanner struct { + c Codec + ci *ConnInfo + oid uint32 + formatCode int16 } -type scanPlanCodecSQLScanner struct{ c Codec } - -func (plan *scanPlanCodecSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - value, err := plan.c.DecodeDatabaseSQLValue(ci, oid, formatCode, src) +func (plan *scanPlanCodecSQLScanner) Scan(src []byte, dst interface{}) error { + value, err := plan.c.DecodeDatabaseSQLValue(plan.ci, plan.oid, plan.formatCode, src) if err != nil { return err } @@ -433,135 +428,56 @@ func (plan *scanPlanCodecSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode i 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) if src == nil { // 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. return scanner.Scan(nil) - } else if formatCode == BinaryFormatCode { + } else if plan.formatCode == BinaryFormatCode { return scanner.Scan(src) } else { 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{} -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 { return fmt.Errorf("cannot scan null into %T", dst) } - if p, ok := (dst).(*string); ok { - *p = string(src) + p := (dst).(*string) + *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 } - newPlan := ci.PlanScan(oid, formatCode, dst) - return newPlan.Scan(ci, oid, formatCode, src, dst) + *dstBuf = make([]byte, len(src)) + 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 @@ -577,12 +493,7 @@ type pointerPointerScanPlan struct { func (plan *pointerPointerScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *pointerPointerScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, 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) - } - +func (plan *pointerPointerScanPlan) Scan(src []byte, dst interface{}) error { el := reflect.ValueOf(dst).Elem() if src == nil { 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())) - 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 @@ -636,13 +547,8 @@ type underlyingTypeScanPlan struct { func (plan *underlyingTypeScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *underlyingTypeScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, 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) - } - - return plan.next.Scan(ci, oid, formatCode, src, reflect.ValueOf(dst).Convert(plan.nextDstType).Interface()) +func (plan *underlyingTypeScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(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 @@ -657,9 +563,17 @@ func TryFindUnderlyingTypeScanPlan(dst interface{}) (plan WrappedScanPlanNextSet if dstValue.Kind() == reflect.Ptr { elemValue := dstValue.Elem() nextDstType := elemKindToPointerTypes[elemValue.Kind()] + if nextDstType == nil && elemValue.Kind() == reflect.Slice { + if elemValue.Type().Elem().Kind() == reflect.Uint8 { + var v *[]byte + nextDstType = reflect.TypeOf(v) + } + } + if nextDstType != nil && dstValue.Type() != nextDstType { return &underlyingTypeScanPlan{dstType: dstValue.Type(), nextDstType: nextDstType}, dstValue.Convert(nextDstType).Interface(), true } + } return nil, nil, false @@ -728,8 +642,8 @@ type wrapInt8ScanPlan struct { func (plan *wrapInt8ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapInt8ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*int8Wrapper)(dst.(*int8))) +func (plan *wrapInt8ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*int8Wrapper)(dst.(*int8))) } type wrapInt16ScanPlan struct { @@ -738,8 +652,8 @@ type wrapInt16ScanPlan struct { func (plan *wrapInt16ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapInt16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*int16Wrapper)(dst.(*int16))) +func (plan *wrapInt16ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*int16Wrapper)(dst.(*int16))) } type wrapInt32ScanPlan struct { @@ -748,8 +662,8 @@ type wrapInt32ScanPlan struct { func (plan *wrapInt32ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapInt32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*int32Wrapper)(dst.(*int32))) +func (plan *wrapInt32ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*int32Wrapper)(dst.(*int32))) } type wrapInt64ScanPlan struct { @@ -758,8 +672,8 @@ type wrapInt64ScanPlan struct { func (plan *wrapInt64ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapInt64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*int64Wrapper)(dst.(*int64))) +func (plan *wrapInt64ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*int64Wrapper)(dst.(*int64))) } type wrapIntScanPlan struct { @@ -768,8 +682,8 @@ type wrapIntScanPlan struct { func (plan *wrapIntScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapIntScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*intWrapper)(dst.(*int))) +func (plan *wrapIntScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*intWrapper)(dst.(*int))) } type wrapUint8ScanPlan struct { @@ -778,8 +692,8 @@ type wrapUint8ScanPlan struct { func (plan *wrapUint8ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapUint8ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*uint8Wrapper)(dst.(*uint8))) +func (plan *wrapUint8ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*uint8Wrapper)(dst.(*uint8))) } type wrapUint16ScanPlan struct { @@ -788,8 +702,8 @@ type wrapUint16ScanPlan struct { func (plan *wrapUint16ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapUint16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*uint16Wrapper)(dst.(*uint16))) +func (plan *wrapUint16ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*uint16Wrapper)(dst.(*uint16))) } type wrapUint32ScanPlan struct { @@ -798,8 +712,8 @@ type wrapUint32ScanPlan struct { func (plan *wrapUint32ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapUint32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*uint32Wrapper)(dst.(*uint32))) +func (plan *wrapUint32ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*uint32Wrapper)(dst.(*uint32))) } type wrapUint64ScanPlan struct { @@ -808,8 +722,8 @@ type wrapUint64ScanPlan struct { func (plan *wrapUint64ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapUint64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*uint64Wrapper)(dst.(*uint64))) +func (plan *wrapUint64ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*uint64Wrapper)(dst.(*uint64))) } type wrapUintScanPlan struct { @@ -818,8 +732,8 @@ type wrapUintScanPlan struct { func (plan *wrapUintScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapUintScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*uintWrapper)(dst.(*uint))) +func (plan *wrapUintScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*uintWrapper)(dst.(*uint))) } type wrapFloat32ScanPlan struct { @@ -828,8 +742,8 @@ type wrapFloat32ScanPlan struct { func (plan *wrapFloat32ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapFloat32ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*float32Wrapper)(dst.(*float32))) +func (plan *wrapFloat32ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*float32Wrapper)(dst.(*float32))) } type wrapFloat64ScanPlan struct { @@ -838,8 +752,8 @@ type wrapFloat64ScanPlan struct { func (plan *wrapFloat64ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapFloat64ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*float64Wrapper)(dst.(*float64))) +func (plan *wrapFloat64ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*float64Wrapper)(dst.(*float64))) } type wrapStringScanPlan struct { @@ -848,8 +762,8 @@ type wrapStringScanPlan struct { func (plan *wrapStringScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*stringWrapper)(dst.(*string))) +func (plan *wrapStringScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*stringWrapper)(dst.(*string))) } type wrapTimeScanPlan struct { @@ -858,8 +772,8 @@ type wrapTimeScanPlan struct { func (plan *wrapTimeScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapTimeScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*timeWrapper)(dst.(*time.Time))) +func (plan *wrapTimeScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*timeWrapper)(dst.(*time.Time))) } type wrapDurationScanPlan struct { @@ -868,8 +782,8 @@ type wrapDurationScanPlan struct { func (plan *wrapDurationScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapDurationScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*durationWrapper)(dst.(*time.Duration))) +func (plan *wrapDurationScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*durationWrapper)(dst.(*time.Duration))) } type wrapNetIPNetScanPlan struct { @@ -878,8 +792,8 @@ type wrapNetIPNetScanPlan struct { func (plan *wrapNetIPNetScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapNetIPNetScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*netIPNetWrapper)(dst.(*net.IPNet))) +func (plan *wrapNetIPNetScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*netIPNetWrapper)(dst.(*net.IPNet))) } type wrapNetIPScanPlan struct { @@ -888,8 +802,8 @@ type wrapNetIPScanPlan struct { func (plan *wrapNetIPScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapNetIPScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*netIPWrapper)(dst.(*net.IP))) +func (plan *wrapNetIPScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*netIPWrapper)(dst.(*net.IP))) } type wrapMapStringToPointerStringScanPlan struct { @@ -898,8 +812,8 @@ type wrapMapStringToPointerStringScanPlan struct { func (plan *wrapMapStringToPointerStringScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapMapStringToPointerStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*mapStringToPointerStringWrapper)(dst.(*map[string]*string))) +func (plan *wrapMapStringToPointerStringScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*mapStringToPointerStringWrapper)(dst.(*map[string]*string))) } type wrapMapStringToStringScanPlan struct { @@ -908,8 +822,8 @@ type wrapMapStringToStringScanPlan struct { func (plan *wrapMapStringToStringScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapMapStringToStringScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*mapStringToStringWrapper)(dst.(*map[string]string))) +func (plan *wrapMapStringToStringScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*mapStringToStringWrapper)(dst.(*map[string]string))) } type wrapByte16ScanPlan struct { @@ -918,8 +832,8 @@ type wrapByte16ScanPlan struct { func (plan *wrapByte16ScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapByte16ScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*byte16Wrapper)(dst.(*[16]byte))) +func (plan *wrapByte16ScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*byte16Wrapper)(dst.(*[16]byte))) } type wrapByteSliceScanPlan struct { @@ -928,16 +842,19 @@ type wrapByteSliceScanPlan struct { func (plan *wrapByteSliceScanPlan) SetNext(next ScanPlan) { plan.next = next } -func (plan *wrapByteSliceScanPlan) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { - return plan.next.Scan(ci, oid, formatCode, src, (*byteSliceWrapper)(dst.(*[]byte))) +func (plan *wrapByteSliceScanPlan) Scan(src []byte, dst interface{}) error { + return plan.next.Scan(src, (*byteSliceWrapper)(dst.(*[]byte))) } 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 { - value, err := plan.codec.DecodeValue(ci, oid, formatCode, src) +func (plan *pointerEmptyInterfaceScanPlan) Scan(src []byte, dst interface{}) error { + value, err := plan.codec.DecodeValue(plan.ci, plan.oid, plan.formatCode, src) if err != nil { return err } @@ -948,45 +865,28 @@ func (plan *pointerEmptyInterfaceScanPlan) Scan(ci *ConnInfo, oid uint32, format return nil } -// PlanScan prepares a plan to scan a value into dst. -func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) ScanPlan { - if _, ok := dst.(*UndecodedBytes); ok { +// PlanScan prepares a plan to scan a value into target. +func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) ScanPlan { + if _, ok := target.(*UndecodedBytes); ok { return scanPlanAnyToUndecodedBytes{} } switch formatCode { case BinaryFormatCode: - switch dst.(type) { + switch target.(type) { case *string: switch oid { case TextOID, VarcharOID: 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: - switch dst.(type) { + switch target.(type) { case *string: return scanPlanString{} case *[]byte: if oid != ByteaOID { - return scanPlanBinaryBytes{} + return scanPlanAnyTextToBytes{} } case TextScanner: return scanPlanTextAnyToTextScanner{} @@ -995,47 +895,43 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, dst interface{}) Scan var dt *DataType - if oid == 0 { - if dataType, ok := ci.DataTypeForValue(dst); ok { - 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 dataType, ok := ci.DataTypeForOID(oid); ok { + dt = dataType + } else if dataType, ok := ci.DataTypeForValue(target); ok { + dt = dataType + oid = dt.OID // Preserve assumed OID in case we are recursively called below. } 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 } - for _, f := range ci.TryWrapScanPlanFuncs { - if wrapperPlan, nextDst, ok := f(dst); ok { - 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) - return wrapperPlan - } + if _, ok := target.(*interface{}); ok { + return &pointerEmptyInterfaceScanPlan{codec: dt.Codec, ci: ci, oid: oid, formatCode: formatCode} + } + + if _, ok := target.(sql.Scanner); ok { + 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 { - return scanPlanSQLScanner{} + if _, ok := target.(sql.Scanner); ok { + 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 { @@ -1044,7 +940,7 @@ func (ci *ConnInfo) Scan(oid uint32, formatCode int16, src []byte, dst interface } 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 { @@ -1073,7 +969,7 @@ func codecScan(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte, if scanPlan == nil { 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) { diff --git a/pgtype/pgtype_test.go b/pgtype/pgtype_test.go index 9bd665c5..2917c31c 100644 --- a/pgtype/pgtype_test.go +++ b/pgtype/pgtype_test.go @@ -118,18 +118,10 @@ func TestConnInfoScanUnknownOIDToStringsAndBytes(t *testing.T) { assert.NoError(t, err) 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 err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rb) assert.NoError(t, err) 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 { @@ -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) { ci := pgtype.NewConnInfo() src := []byte{0, 0, 0, 42} @@ -260,7 +237,7 @@ func BenchmarkScanPlanScanInt4IntoBinaryDecoder(b *testing.B) { for i := 0; i < b.N; i++ { v = pgtype.Int4{} - err := plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) + err := plan.Scan(src, &v) if err != nil { b.Fatal(err) } @@ -279,7 +256,7 @@ func BenchmarkScanPlanScanInt4IntoGoInt32(b *testing.B) { for i := 0; i < b.N; i++ { v = 0 - err := plan.Scan(ci, pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) + err := plan.Scan(src, &v) if err != nil { b.Fatal(err) } diff --git a/pgtype/point.go b/pgtype/point.go index a9be4fdc..0a300fe2 100644 --- a/pgtype/point.go +++ b/pgtype/point.go @@ -77,7 +77,7 @@ func (dst *Point) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToPointScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToPointScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -236,7 +236,7 @@ func (scanPlanBinaryPointToPointScanner) Scan(ci *ConnInfo, oid uint32, formatCo 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) if src == nil { diff --git a/pgtype/polygon.go b/pgtype/polygon.go index 47dbfed9..e4a1b2af 100644 --- a/pgtype/polygon.go +++ b/pgtype/polygon.go @@ -42,7 +42,7 @@ func (p *Polygon) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToPolygonScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), p) + return scanPlanTextAnyToPolygonScanner{}.Scan([]byte(src), p) } 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{} -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) if src == nil { @@ -193,7 +193,7 @@ func (scanPlanBinaryPolygonToPolygonScanner) Scan(ci *ConnInfo, oid uint32, form 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) if src == nil { diff --git a/pgtype/qchar.go b/pgtype/qchar.go index 28c91110..5c712369 100644 --- a/pgtype/qchar.go +++ b/pgtype/qchar.go @@ -72,7 +72,7 @@ func (QCharCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interf 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 { 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{} -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 { return fmt.Errorf("cannot scan null into %T", dst) } diff --git a/pgtype/text.go b/pgtype/text.go index 3c73cc15..7e4f8b99 100644 --- a/pgtype/text.go +++ b/pgtype/text.go @@ -189,7 +189,7 @@ func (c TextCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt 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 { 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{} -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) if src == nil { *p = nil @@ -216,7 +216,7 @@ func (scanPlanAnyToNewByteSlice) Scan(ci *ConnInfo, oid uint32, formatCode int16 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 { 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{} -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) if src == nil { diff --git a/pgtype/tid.go b/pgtype/tid.go index 450cfbc9..cc38f404 100644 --- a/pgtype/tid.go +++ b/pgtype/tid.go @@ -53,7 +53,7 @@ func (dst *TID) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToTIDScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), dst) + return scanPlanTextAnyToTIDScanner{}.Scan([]byte(src), dst) } 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{} -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) if src == nil { @@ -172,7 +172,7 @@ func (scanPlanBinaryTIDToTIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode i 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) if src == nil { @@ -194,7 +194,7 @@ func (scanPlanBinaryTIDToTextScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/time.go b/pgtype/time.go index 47dabe99..734687cb 100644 --- a/pgtype/time.go +++ b/pgtype/time.go @@ -45,7 +45,7 @@ func (t *Time) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextAnyToTimeScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), t) + return scanPlanTextAnyToTimeScanner{}.Scan([]byte(src), t) } 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{} -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) if src == nil { @@ -167,7 +167,7 @@ func (scanPlanBinaryTimeToTimeScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/pgtype/timestamp.go b/pgtype/timestamp.go index 374aafe4..24ee76b0 100644 --- a/pgtype/timestamp.go +++ b/pgtype/timestamp.go @@ -44,7 +44,7 @@ func (ts *Timestamp) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextTimestampToTimestampScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), ts) + return scanPlanTextTimestampToTimestampScanner{}.Scan([]byte(src), ts) case time.Time: *ts = Timestamp{Time: src, Valid: true} return nil @@ -172,7 +172,7 @@ func (TimestampCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target in 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) if src == nil { @@ -204,7 +204,7 @@ func (scanPlanBinaryTimestampToTimestampScanner) Scan(ci *ConnInfo, oid uint32, 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) if src == nil { diff --git a/pgtype/timestamp_test.go b/pgtype/timestamp_test.go index 1bbceaf5..562bb192 100644 --- a/pgtype/timestamp_test.go +++ b/pgtype/timestamp_test.go @@ -52,6 +52,6 @@ func TestTimestampCodecDecodeTextInvalid(t *testing.T) { c := &pgtype.TimestampCodec{} var ts pgtype.Timestamp 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) } diff --git a/pgtype/timestamptz.go b/pgtype/timestamptz.go index eec1dca5..ea2ebfbe 100644 --- a/pgtype/timestamptz.go +++ b/pgtype/timestamptz.go @@ -53,7 +53,7 @@ func (tstz *Timestamptz) Scan(src interface{}) error { switch src := src.(type) { case string: - return scanPlanTextTimestamptzToTimestamptzScanner{}.Scan(nil, 0, TextFormatCode, []byte(src), tstz) + return scanPlanTextTimestamptzToTimestamptzScanner{}.Scan([]byte(src), tstz) case time.Time: *tstz = Timestamptz{Time: src, Valid: true} return nil @@ -220,7 +220,7 @@ func (TimestamptzCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target 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) if src == nil { @@ -252,7 +252,7 @@ func (scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(ci *ConnInfo, oid uint 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) if src == nil { diff --git a/pgtype/timestamptz_test.go b/pgtype/timestamptz_test.go index 42439b7b..ec408f47 100644 --- a/pgtype/timestamptz_test.go +++ b/pgtype/timestamptz_test.go @@ -52,7 +52,7 @@ func TestTimestamptzDecodeTextInvalid(t *testing.T) { c := &pgtype.TimestamptzCodec{} var tstz pgtype.Timestamptz 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) } diff --git a/pgtype/uint32.go b/pgtype/uint32.go index ccf39471..7d481a27 100644 --- a/pgtype/uint32.go +++ b/pgtype/uint32.go @@ -246,7 +246,7 @@ func (c Uint32Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []b 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 { 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{} -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) if !ok { return ErrScanTargetTypeChanged @@ -284,7 +284,7 @@ func (scanPlanBinaryUint32ToUint32Scanner) Scan(ci *ConnInfo, oid uint32, format 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) if !ok { return ErrScanTargetTypeChanged diff --git a/pgtype/uuid.go b/pgtype/uuid.go index 288fc454..2655a124 100644 --- a/pgtype/uuid.go +++ b/pgtype/uuid.go @@ -186,7 +186,7 @@ func (UUIDCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa 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) if src == nil { @@ -205,7 +205,7 @@ func (scanPlanBinaryUUIDToUUIDScanner) Scan(ci *ConnInfo, oid uint32, formatCode 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) if src == nil { diff --git a/rows.go b/rows.go index 5a4bc9a9..06e0a933 100644 --- a/rows.go +++ b/rows.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "reflect" "time" "github.com/jackc/pgproto3/v2" @@ -111,6 +112,7 @@ type connRows struct { multiResultReader *pgconn.MultiResultReader scanPlans []pgtype.ScanPlan + scanTypes []reflect.Type } func (rows *connRows) FieldDescriptions() []pgproto3.FieldDescription { @@ -208,8 +210,10 @@ func (rows *connRows) Scan(dest ...interface{}) error { if rows.scanPlans == nil { rows.scanPlans = make([]pgtype.ScanPlan, len(values)) + rows.scanTypes = make([]reflect.Type, len(values)) for i := range dest { 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 } - 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 { err = ScanArgError{ColumnIndex: i, Err: err} rows.fatal(err) diff --git a/stdlib/sql.go b/stdlib/sql.go index 40693ded..5e2c3a03 100644 --- a/stdlib/sql.go +++ b/stdlib/sql.go @@ -605,21 +605,21 @@ func (r *Rows) Next(dest []driver.Value) error { var d bool scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.ByteaOID: var d []byte scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.CIDOID, pgtype.OIDOID, pgtype.XIDOID: var d pgtype.Uint32 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 { return nil, err } @@ -629,7 +629,7 @@ func (r *Rows) Next(dest []driver.Value) error { var d pgtype.Date scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 { return nil, err } @@ -639,42 +639,42 @@ func (r *Rows) Next(dest []driver.Value) error { var d float32 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.Float8OID: var d float64 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.Int2OID: var d int16 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.Int4OID: var d int32 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.Int8OID: var d int64 scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } case pgtype.JSONOID, pgtype.JSONBOID: var d []byte scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 { return nil, err } @@ -684,7 +684,7 @@ func (r *Rows) Next(dest []driver.Value) error { var d pgtype.Timestamp scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 { return nil, err } @@ -694,7 +694,7 @@ func (r *Rows) Next(dest []driver.Value) error { var d pgtype.Timestamptz scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 { return nil, err } @@ -704,7 +704,7 @@ func (r *Rows) Next(dest []driver.Value) error { var d string scanPlan := ci.PlanScan(dataTypeOID, format, &d) 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 } }