From f8fe85a7da96dc2951beb3c6258892cea693db54 Mon Sep 17 00:00:00 2001 From: Matt Brittan Date: Sat, 17 Feb 2024 14:36:10 +1300 Subject: [PATCH] Add support for scanning float4 into *float64. This is required to support scanning float4 using a `sql.Scanner` (previously this resulted in "did not find a plan" error) closes #1911 --- pgtype/float4.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pgtype/float4.go b/pgtype/float4.go index 91ca01473..33bf669e7 100644 --- a/pgtype/float4.go +++ b/pgtype/float4.go @@ -176,6 +176,8 @@ func (Float4Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPl switch target.(type) { case *float32: return scanPlanBinaryFloat4ToFloat32{} + case *float64: + return scanPlanBinaryFloat4ToFloat64{} case Float64Scanner: return scanPlanBinaryFloat4ToFloat64Scanner{} case Int64Scanner: @@ -187,6 +189,8 @@ func (Float4Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPl switch target.(type) { case *float32: return scanPlanTextAnyToFloat32{} + case *float64: + return scanPlanTextAnyToFloat64{} case Float64Scanner: return scanPlanTextAnyToFloat64Scanner{} case Int64Scanner: @@ -215,6 +219,24 @@ func (scanPlanBinaryFloat4ToFloat32) Scan(src []byte, dst any) error { return nil } +type scanPlanBinaryFloat4ToFloat64 struct{} + +func (scanPlanBinaryFloat4ToFloat64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for float4: %v", len(src)) + } + + n := int32(binary.BigEndian.Uint32(src)) + f := (dst).(*float64) + *f = float64(math.Float32frombits(uint32(n))) + + return nil +} + type scanPlanBinaryFloat4ToFloat64Scanner struct{} func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(src []byte, dst any) error {