From 0355d2ffeae3bc0d5cb14ae63fbd407b790a9358 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sat, 5 Feb 2022 08:54:38 -0600 Subject: [PATCH] Add Float8range PostgreSQL doesn't define float8range out of the box though it can easily be created by the user. However, it is still convenient to treat a numrange as a float8range. --- pgtype/range_codec_test.go | 27 +++++++++++++++++++++++++++ pgtype/range_types.go | 36 ++++++++++++++++++++++++++++++++++++ pgtype/range_types.go.erb | 3 ++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/pgtype/range_codec_test.go b/pgtype/range_codec_test.go index b4cc9e8e..30095065 100644 --- a/pgtype/range_codec_test.go +++ b/pgtype/range_codec_test.go @@ -36,6 +36,33 @@ func TestRangeCodecTranscode(t *testing.T) { }) } +func TestRangeCodecTranscodeCompatibleRangeElementTypes(t *testing.T) { + testutil.RunTranscodeTests(t, "numrange", []testutil.TranscodeTestCase{ + { + pgtype.Float8range{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true}, + new(pgtype.Float8range), + isExpectedEq(pgtype.Float8range{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true}), + }, + { + pgtype.Float8range{ + LowerType: pgtype.Inclusive, + Lower: pgtype.Float8{Float: 1, Valid: true}, + Upper: pgtype.Float8{Float: 5, Valid: true}, + UpperType: pgtype.Exclusive, Valid: true, + }, + new(pgtype.Float8range), + isExpectedEq(pgtype.Float8range{ + LowerType: pgtype.Inclusive, + Lower: pgtype.Float8{Float: 1, Valid: true}, + Upper: pgtype.Float8{Float: 5, Valid: true}, + UpperType: pgtype.Exclusive, Valid: true, + }), + }, + {pgtype.Float8range{}, new(pgtype.Float8range), isExpectedEq(pgtype.Float8range{})}, + {nil, new(pgtype.Float8range), isExpectedEq(pgtype.Float8range{})}, + }) +} + func TestRangeCodecDecodeValue(t *testing.T) { conn := testutil.MustConnectPgx(t) defer testutil.MustCloseContext(t, conn) diff --git a/pgtype/range_types.go b/pgtype/range_types.go index 3f1e7d8a..aa979d56 100644 --- a/pgtype/range_types.go +++ b/pgtype/range_types.go @@ -216,3 +216,39 @@ func (r *Daterange) SetBoundTypes(lower, upper BoundType) error { r.Valid = true return nil } + +type Float8range struct { + Lower Float8 + Upper Float8 + LowerType BoundType + UpperType BoundType + Valid bool +} + +func (r Float8range) IsNull() bool { + return !r.Valid +} + +func (r Float8range) BoundTypes() (lower, upper BoundType) { + return r.LowerType, r.UpperType +} + +func (r Float8range) Bounds() (lower, upper interface{}) { + return &r.Lower, &r.Upper +} + +func (r *Float8range) ScanNull() error { + *r = Float8range{} + return nil +} + +func (r *Float8range) ScanBounds() (lowerTarget, upperTarget interface{}) { + return &r.Lower, &r.Upper +} + +func (r *Float8range) SetBoundTypes(lower, upper BoundType) error { + r.LowerType = lower + r.UpperType = upper + r.Valid = true + return nil +} diff --git a/pgtype/range_types.go.erb b/pgtype/range_types.go.erb index 11b12822..dc796a1d 100644 --- a/pgtype/range_types.go.erb +++ b/pgtype/range_types.go.erb @@ -7,7 +7,8 @@ package pgtype ["Numrange", "Numeric"], ["Tsrange", "Timestamp"], ["Tstzrange", "Timestamptz"], - ["Daterange", "Date"] + ["Daterange", "Date"], + ["Float8range", "Float8"] ].each do |range_type, element_type| %> type <%= range_type %> struct {