diff --git a/pgtype/box.go b/pgtype/box.go index b5c30ed3..5e841ae5 100644 --- a/pgtype/box.go +++ b/pgtype/box.go @@ -50,6 +50,10 @@ func (dst *Box) Scan(src interface{}) error { // Value implements the database/sql/driver Valuer interface. func (src Box) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + buf, err := BoxCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) if err != nil { return nil, err @@ -90,6 +94,10 @@ func (p *encodePlanBoxCodecBinary) Encode(value interface{}, buf []byte) (newBuf return nil, err } + if !box.Valid { + return nil, nil + } + buf = pgio.AppendUint64(buf, math.Float64bits(box.P[0].X)) buf = pgio.AppendUint64(buf, math.Float64bits(box.P[0].Y)) buf = pgio.AppendUint64(buf, math.Float64bits(box.P[1].X)) @@ -105,6 +113,10 @@ func (p *encodePlanBoxCodecText) Encode(value interface{}, buf []byte) (newBuf [ return nil, err } + if !box.Valid { + return nil, nil + } + buf = append(buf, fmt.Sprintf(`(%s,%s),(%s,%s)`, strconv.FormatFloat(box.P[0].X, 'f', -1, 64), strconv.FormatFloat(box.P[0].Y, 'f', -1, 64), diff --git a/pgtype/box_test.go b/pgtype/box_test.go index f4e26370..8056e819 100644 --- a/pgtype/box_test.go +++ b/pgtype/box_test.go @@ -31,6 +31,7 @@ func TestBoxCodec(t *testing.T) { Valid: true, }), }, + {pgtype.Box{}, new(pgtype.Box), isExpectedEq(pgtype.Box{})}, {nil, new(pgtype.Box), isExpectedEq(pgtype.Box{})}, }) } diff --git a/pgtype/circle.go b/pgtype/circle.go index f214a070..5d9055e5 100644 --- a/pgtype/circle.go +++ b/pgtype/circle.go @@ -51,6 +51,10 @@ func (dst *Circle) Scan(src interface{}) error { // Value implements the database/sql/driver Valuer interface. func (src Circle) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + buf, err := CircleCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) if err != nil { return nil, err @@ -91,6 +95,10 @@ func (p *encodePlanCircleCodecBinary) Encode(value interface{}, buf []byte) (new return nil, err } + if !circle.Valid { + return nil, nil + } + buf = pgio.AppendUint64(buf, math.Float64bits(circle.P.X)) buf = pgio.AppendUint64(buf, math.Float64bits(circle.P.Y)) buf = pgio.AppendUint64(buf, math.Float64bits(circle.R)) @@ -105,6 +113,10 @@ func (p *encodePlanCircleCodecText) Encode(value interface{}, buf []byte) (newBu return nil, err } + if !circle.Valid { + return nil, nil + } + buf = append(buf, fmt.Sprintf(`<(%s,%s),%s>`, strconv.FormatFloat(circle.P.X, 'f', -1, 64), strconv.FormatFloat(circle.P.Y, 'f', -1, 64), diff --git a/pgtype/circle_test.go b/pgtype/circle_test.go index 742ac688..6fbf4c31 100644 --- a/pgtype/circle_test.go +++ b/pgtype/circle_test.go @@ -18,6 +18,7 @@ func TestCircleTranscode(t *testing.T) { new(pgtype.Circle), isExpectedEq(pgtype.Circle{P: pgtype.Vec2{1.234, 5.67890123}, R: 3.5, Valid: true}), }, + {pgtype.Circle{}, new(pgtype.Circle), isExpectedEq(pgtype.Circle{})}, {nil, new(pgtype.Circle), isExpectedEq(pgtype.Circle{})}, }) } diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 6c26db16..6ead989e 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -949,6 +949,10 @@ func codecScan(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte, } func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + if format == TextFormatCode { return string(src), nil } else { diff --git a/pgtype/point.go b/pgtype/point.go index b4236c8f..256bedc0 100644 --- a/pgtype/point.go +++ b/pgtype/point.go @@ -85,6 +85,10 @@ func (dst *Point) Scan(src interface{}) error { // Value implements the database/sql/driver Valuer interface. func (src Point) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + buf, err := PointCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) if err != nil { return nil, err @@ -146,6 +150,10 @@ func (p *encodePlanPointCodecBinary) Encode(value interface{}, buf []byte) (newB return nil, err } + if !point.Valid { + return nil, nil + } + buf = pgio.AppendUint64(buf, math.Float64bits(point.P.X)) buf = pgio.AppendUint64(buf, math.Float64bits(point.P.Y)) return buf, nil @@ -159,6 +167,10 @@ func (p *encodePlanPointCodecText) Encode(value interface{}, buf []byte) (newBuf return nil, err } + if !point.Valid { + return nil, nil + } + return append(buf, fmt.Sprintf(`(%s,%s)`, strconv.FormatFloat(point.P.X, 'f', -1, 64), strconv.FormatFloat(point.P.Y, 'f', -1, 64), diff --git a/pgtype/point_test.go b/pgtype/point_test.go index 718e203a..8046da92 100644 --- a/pgtype/point_test.go +++ b/pgtype/point_test.go @@ -20,6 +20,7 @@ func TestPointCodec(t *testing.T) { new(pgtype.Point), isExpectedEq(pgtype.Point{P: pgtype.Vec2{-1.234, -5.6789}, Valid: true}), }, + {pgtype.Point{}, new(pgtype.Point), isExpectedEq(pgtype.Point{})}, {nil, new(pgtype.Point), isExpectedEq(pgtype.Point{})}, }) }