From 9f4a264f89a3157a35097556542dbd34124d7f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez-Aradros=20Herce?= Date: Thu, 30 May 2024 09:48:53 +0200 Subject: [PATCH] Fix interval encoding to allow 0s and avoid extra spaces Fix a bugs introduced by 01d649b, also add some tests --- pgtype/interval.go | 32 ++++++++++++++------------------ pgtype/interval_test.go | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/pgtype/interval.go b/pgtype/interval.go index 06703d4d..4b511629 100644 --- a/pgtype/interval.go +++ b/pgtype/interval.go @@ -132,29 +132,25 @@ func (encodePlanIntervalCodecText) Encode(value any, buf []byte) (newBuf []byte, if interval.Days != 0 { buf = append(buf, strconv.FormatInt(int64(interval.Days), 10)...) - buf = append(buf, " day"...) + buf = append(buf, " day "...) } - if interval.Microseconds != 0 { - buf = append(buf, " "...) + absMicroseconds := interval.Microseconds + if absMicroseconds < 0 { + absMicroseconds = -absMicroseconds + buf = append(buf, '-') + } - absMicroseconds := interval.Microseconds - if absMicroseconds < 0 { - absMicroseconds = -absMicroseconds - buf = append(buf, '-') - } + hours := absMicroseconds / microsecondsPerHour + minutes := (absMicroseconds % microsecondsPerHour) / microsecondsPerMinute + seconds := (absMicroseconds % microsecondsPerMinute) / microsecondsPerSecond - hours := absMicroseconds / microsecondsPerHour - minutes := (absMicroseconds % microsecondsPerHour) / microsecondsPerMinute - seconds := (absMicroseconds % microsecondsPerMinute) / microsecondsPerSecond + timeStr := fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) + buf = append(buf, timeStr...) - timeStr := fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - buf = append(buf, timeStr...) - - microseconds := absMicroseconds % microsecondsPerSecond - if microseconds != 0 { - buf = append(buf, fmt.Sprintf(".%06d", microseconds)...) - } + microseconds := absMicroseconds % microsecondsPerSecond + if microseconds != 0 { + buf = append(buf, fmt.Sprintf(".%06d", microseconds)...) } return buf, nil diff --git a/pgtype/interval_test.go b/pgtype/interval_test.go index 754c44e3..c06c3b2d 100644 --- a/pgtype/interval_test.go +++ b/pgtype/interval_test.go @@ -7,6 +7,7 @@ import ( "github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgxtest" + "github.com/stretchr/testify/assert" ) func TestIntervalCodec(t *testing.T) { @@ -136,3 +137,22 @@ func TestIntervalCodec(t *testing.T) { {nil, new(pgtype.Interval), isExpectedEq(pgtype.Interval{})}, }) } + +func TestIntervalTextEncode(t *testing.T) { + m := pgtype.NewMap() + + successfulTests := []struct { + source pgtype.Interval + result string + }{ + {source: pgtype.Interval{Months: 2, Days: 1, Microseconds: 0, Valid: true}, result: "2 mon 1 day 00:00:00"}, + {source: pgtype.Interval{Months: 0, Days: 0, Microseconds: 0, Valid: true}, result: "00:00:00"}, + {source: pgtype.Interval{Months: 0, Days: 0, Microseconds: 6 * 60 * 1000000, Valid: true}, result: "00:06:00"}, + {source: pgtype.Interval{Months: 0, Days: 1, Microseconds: 6*60*1000000 + 30, Valid: true}, result: "1 day 00:06:00.000030"}, + } + for i, tt := range successfulTests { + buf, err := m.Encode(pgtype.DateOID, pgtype.TextFormatCode, tt.source, nil) + assert.NoErrorf(t, err, "%d", i) + assert.Equalf(t, tt.result, string(buf), "%d", i) + } +}