diff --git a/pkg/sql/logictest/testdata/logic_test/datetime b/pkg/sql/logictest/testdata/logic_test/datetime index a6caeac1b865..1ca15f7b9cc0 100644 --- a/pkg/sql/logictest/testdata/logic_test/datetime +++ b/pkg/sql/logictest/testdata/logic_test/datetime @@ -1523,7 +1523,7 @@ ORDER BY 01:00:00 00:30:00 02:00:00 00:30:00 02:00:00 04:14:01.320914 00:14:10.32 1 day 12:00:00 2 days 12:00:00 2 days 4 days 05:36:31.701948 05:40:07.68 1 mon 15 days 2 mons 15 days 2 mons 4 mons 7 days 00:15:51.058425 7 days 02:03:50.4 -1 mon 2 days 04:00:00 16 days 02:00:00 2 mons 4 days 08:00:00 16 days 02:00:00 2 mons 4 days 08:00:00 4 mons 15 days 28:24:59.745978 7 days 14:20:47.04 +1 mon 2 days 04:00:00 16 days 02:00:00 2 mons 4 days 08:00:00 16 days 02:00:00 2 mons 4 days 08:00:00 4 mons 15 days 28:24:59.745977 7 days 14:20:47.04 subtest tz_utc_normalization diff --git a/pkg/sql/logictest/testdata/logic_test/interval b/pkg/sql/logictest/testdata/logic_test/interval index d8fb3d0a891f..883b54f9fa40 100644 --- a/pkg/sql/logictest/testdata/logic_test/interval +++ b/pkg/sql/logictest/testdata/logic_test/interval @@ -367,3 +367,12 @@ subtest regression_62369 query error "10000000000000000000000000000000000": value out of range SELECT INTERVAL '10000000000000000000000000000000000 year' + +query T +SELECT i / 2 FROM ( VALUES + ('0 days 0.253000 seconds'::interval), + (INTERVAL '0.000001'::interval) +) regression_66118(i) +---- +00:00:00.1265 +00:00:00 diff --git a/pkg/util/duration/duration.go b/pkg/util/duration/duration.go index 70e8311463e4..94f4f844ea4a 100644 --- a/pkg/util/duration/duration.go +++ b/pkg/util/duration/duration.go @@ -619,9 +619,12 @@ func (d Duration) MulFloat(x float64) Duration { func (d Duration) DivFloat(x float64) Duration { monthInt, monthFrac := math.Modf(float64(d.Months) / x) dayInt, dayFrac := math.Modf((float64(d.Days) / x) + (monthFrac * DaysPerMonth)) + // We ensure we round down nanoseconds when doing division to + // match PostgreSQL. + retNanos := time.Duration(float64(d.nanos) / x).Truncate(time.Microsecond) return MakeDuration( - int64((float64(d.nanos)/x)+(dayFrac*float64(nanosInDay))), + int64(float64(retNanos.Nanoseconds())+(dayFrac*float64(nanosInDay))), int64(dayInt), int64(monthInt), ) diff --git a/pkg/util/duration/duration_test.go b/pkg/util/duration/duration_test.go index 78d25b166b49..da10335f1ffd 100644 --- a/pkg/util/duration/duration_test.go +++ b/pkg/util/duration/duration_test.go @@ -498,6 +498,18 @@ func TestFloatMath(t *testing.T) { Duration{Months: 2, Days: 34, nanos: nanosInHour * 4}, Duration{Days: 23, nanos: nanosInHour * 13}, }, + { + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0.253000}, + 3.2, + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0.8096}, + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0.079062}, + }, + { + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0.000001}, + 2.0, + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0.000002}, + Duration{Months: 0, Days: 0, nanos: nanosInSecond * 0}, + }, } for i, test := range tests {