From 0f765e7149cc7663369a487f88a71e3e4d8ef987 Mon Sep 17 00:00:00 2001 From: Timothy Messier Date: Wed, 21 Feb 2024 16:13:05 +0000 Subject: [PATCH] feat(timestamp): Support -/+infinity for Valuer When converting a timestamp.Timestamp for use in SQL, this now correctly converts the NegativeInfinity and PositiveInfinity constants into the corresponding `-infinity` and `infinity` SQL constants. --- internal/db/timestamp/scanners.go | 10 ++++++++-- internal/db/timestamp/scanners_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/internal/db/timestamp/scanners.go b/internal/db/timestamp/scanners.go index cd347212e4..8fbe2cefbf 100644 --- a/internal/db/timestamp/scanners.go +++ b/internal/db/timestamp/scanners.go @@ -37,10 +37,16 @@ func (ts *Timestamp) Scan(value any) error { // Scan implements driver.Valuer for protobuf Timestamp. func (ts *Timestamp) Value() (driver.Value, error) { - if ts == nil { + switch { + case ts == nil: return nil, nil + case ts.AsTime().Equal(NegativeInfinityTS): + return "-infinity", nil + case ts.AsTime().Equal(PositiveInfinityTS): + return "infinity", nil + default: + return ts.Timestamp.AsTime(), nil } - return ts.Timestamp.AsTime(), nil } // GormDataType gorm common data type (required) diff --git a/internal/db/timestamp/scanners_test.go b/internal/db/timestamp/scanners_test.go index c231c13872..c6725f087b 100644 --- a/internal/db/timestamp/scanners_test.go +++ b/internal/db/timestamp/scanners_test.go @@ -33,6 +33,18 @@ func Test_TimestampValue(t *testing.T) { require.NoError(t, err) assert.Equal(t, v, utcDate(10000, 1, 1)) }) + t.Run("negativeInfinity", func(t *testing.T) { + ts := New(NegativeInfinityTS) + v, err := ts.Value() + require.NoError(t, err) + assert.Equal(t, v, "-infinity") + }) + t.Run("positiveInfinity", func(t *testing.T) { + ts := New(PositiveInfinityTS) + v, err := ts.Value() + require.NoError(t, err) + assert.Equal(t, v, "infinity") + }) } func Test_TimestampScan(t *testing.T) { @@ -65,6 +77,20 @@ func Test_TimestampScan(t *testing.T) { err := ts.Scan(v) require.Nil(err) }) + t.Run("negativeInfinity", func(t *testing.T) { + v := "-infinity" + ts := Timestamp{} + err := ts.Scan(v) + require.NoError(err) + assert.Equal(ts.AsTime(), NegativeInfinityTS) + }) + t.Run("positiveInfinity", func(t *testing.T) { + v := "infinity" + ts := Timestamp{} + err := ts.Scan(v) + require.NoError(err) + assert.Equal(ts.AsTime(), PositiveInfinityTS) + }) } const maxValidSeconds = 253402300800