diff --git a/pkg/sql/logictest/testdata/logic_test/datetime b/pkg/sql/logictest/testdata/logic_test/datetime index f97442cd5d78..a7b99caf8d58 100644 --- a/pkg/sql/logictest/testdata/logic_test/datetime +++ b/pkg/sql/logictest/testdata/logic_test/datetime @@ -159,13 +159,18 @@ SELECT '5874897-12-31'::date - '4714-11-24 BC'::date query T SELECT age('2001-04-10 22:06:45', '1957-06-13') ---- -384190:06:45 +44 years 5 mons 17 days 22:06:45 query B SELECT age('1957-06-13') - age(now(), '1957-06-13') = interval '0s' ---- true +query T +select age('2017-12-10'::timestamptz, '2017-12-01'::timestamptz) +---- +9 days + query B SELECT now() - timestamp '2015-06-13' > interval '100h' ---- diff --git a/pkg/sql/logictest/testdata/logic_test/timestamp b/pkg/sql/logictest/testdata/logic_test/timestamp index 12d747996230..ed5dfffa5503 100644 --- a/pkg/sql/logictest/testdata/logic_test/timestamp +++ b/pkg/sql/logictest/testdata/logic_test/timestamp @@ -402,8 +402,8 @@ SELECT FROM example ORDER BY a ---- -2010-11-07 22:59:00 -0600 CST 2010-11-07 23:59:00 -0600 CST 2010-12-06 23:59:00 -0600 CST 2010-11-05 23:59:00 -0500 CDT 2010-11-05 23:59:00 -0500 CDT 2010-10-06 23:59:00 -0500 CDT 00:00:00 -25:00:00 2010-11-06 23:59:00-05:00 -2010-11-08 23:59:00 -0600 CST 2010-11-08 23:59:00 -0600 CST 2010-12-07 23:59:00 -0600 CST 2010-11-07 00:59:00 -0500 CDT 2010-11-06 23:59:00 -0500 CDT 2010-10-07 23:59:00 -0500 CDT 25:00:00 00:00:00 2010-11-07 23:59:00-06:00 +2010-11-07 22:59:00 -0600 CST 2010-11-07 23:59:00 -0600 CST 2010-12-06 23:59:00 -0600 CST 2010-11-05 23:59:00 -0500 CDT 2010-11-05 23:59:00 -0500 CDT 2010-10-06 23:59:00 -0500 CDT 00:00:00 -1 days -01:00:00 2010-11-06 23:59:00-05:00 +2010-11-08 23:59:00 -0600 CST 2010-11-08 23:59:00 -0600 CST 2010-12-07 23:59:00 -0600 CST 2010-11-07 00:59:00 -0500 CDT 2010-11-06 23:59:00 -0500 CDT 2010-10-07 23:59:00 -0500 CDT 1 day 01:00:00 00:00:00 2010-11-07 23:59:00-06:00 statement ok DROP TABLE example diff --git a/pkg/sql/opt/norm/testdata/rules/fold_constants b/pkg/sql/opt/norm/testdata/rules/fold_constants index 469db12f2a2a..5df6d74f713d 100644 --- a/pkg/sql/opt/norm/testdata/rules/fold_constants +++ b/pkg/sql/opt/norm/testdata/rules/fold_constants @@ -366,7 +366,7 @@ values ├── cardinality: [1 - 1] ├── key: () ├── fd: ()-->(1) - └── ('-24:00:00',) + └── ('-1 days',) # Fold constant. norm expect=FoldBinary diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index bf30848dae24..ce207b815bf2 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -878,7 +878,7 @@ var BinOps = map[BinaryOperator]binOpOverload{ ReturnType: types.Interval, Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) { nanos := left.(*DTimestamp).Sub(right.(*DTimestamp).Time).Nanoseconds() - return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil + return &DInterval{Duration: duration.MakeNormalizedDuration(nanos, 0, 0)}, nil }, }, &BinOp{ @@ -887,7 +887,7 @@ var BinOps = map[BinaryOperator]binOpOverload{ ReturnType: types.Interval, Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) { nanos := left.(*DTimestampTZ).Sub(right.(*DTimestampTZ).Time).Nanoseconds() - return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil + return &DInterval{Duration: duration.MakeNormalizedDuration(nanos, 0, 0)}, nil }, }, &BinOp{ @@ -898,7 +898,7 @@ var BinOps = map[BinaryOperator]binOpOverload{ // These two quantities aren't directly comparable. Convert the // TimestampTZ to a timestamp first. nanos := left.(*DTimestamp).Sub(right.(*DTimestampTZ).stripTimeZone(ctx).Time).Nanoseconds() - return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil + return &DInterval{Duration: duration.MakeNormalizedDuration(nanos, 0, 0)}, nil }, }, &BinOp{ @@ -909,7 +909,7 @@ var BinOps = map[BinaryOperator]binOpOverload{ // These two quantities aren't directly comparable. Convert the // TimestampTZ to a timestamp first. nanos := left.(*DTimestampTZ).stripTimeZone(ctx).Sub(right.(*DTimestamp).Time).Nanoseconds() - return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil + return &DInterval{Duration: duration.MakeNormalizedDuration(nanos, 0, 0)}, nil }, }, &BinOp{ diff --git a/pkg/util/duration/duration.go b/pkg/util/duration/duration.go index 2f09d08abd50..362ea9cfcd52 100644 --- a/pkg/util/duration/duration.go +++ b/pkg/util/duration/duration.go @@ -102,6 +102,15 @@ func MakeDuration(nanos, days, months int64) Duration { } } +// MakeNormalizedDuration returns a normalized Duration. +func MakeNormalizedDuration(nanos, days, months int64) Duration { + return Duration{ + Months: months, + Days: days, + nanos: rounded(nanos), + }.normalize() +} + // DecodeDuration returns a Duration without rounding nanos. func DecodeDuration(months, days, nanos int64) Duration { return Duration{