From bebfb18fb281d66cbb39af3bd2c76c9ba2b4f2bf Mon Sep 17 00:00:00 2001 From: Oliver Tan Date: Wed, 20 Nov 2019 09:52:07 -0800 Subject: [PATCH] sql: add cast support to TimeTZ Added the various casts supported by postgres for `timetz`: ``` otan=# select castcontext, f.typname as "from", t.typname as to from pg_cast join pg_type as f ON (f.typelem = castsource) join pg_type as t on (t.typelem=casttarget) where castsource = 'timetz'::regtype or casttarget = 'timetz'::regtype; castcontext | from | to -------------+--------------+--------- i | _time | _timetz a | _timestamptz | _timetz i | _timetz | _timetz a | _timetz | _time (4 rows) ``` No release not required as this will be combined with a fully fleshed note for TimeTZ. Release note: None --- pkg/sql/logictest/testdata/logic_test/timetz | 26 ++++++++++++++++++++ pkg/sql/sem/tree/eval.go | 9 ++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pkg/sql/logictest/testdata/logic_test/timetz b/pkg/sql/logictest/testdata/logic_test/timetz index 0b8387f56a37..6cf68de74e5d 100644 --- a/pkg/sql/logictest/testdata/logic_test/timetz +++ b/pkg/sql/logictest/testdata/logic_test/timetz @@ -46,3 +46,29 @@ query TTI SELECT a::string, b::string, c FROM timetz_test WHERE a = b ORDER BY c ---- 15:00:00+03:00:00 15:00:00+03:00:00 5 + +# Test various casts involving different timezones. +subtest cast_tests + +statement ok +SET TIME ZONE -5 + +query T +SELECT '11:00+03:00'::timetz::time +---- +0000-01-01 11:00:00 +0000 UTC + +# This should take the timezone in the background. +query T +SELECT '11:00'::time::timetz +---- +0000-01-01 11:00:00 -0500 -0500 + +# This should observe the time and zone from the timestamp. +query T +SELECT '2001-01-01 11:00+04:00'::timestamptz::timetz +---- +0000-01-01 11:00:00 +0400 +0400 + +statement ok +SET TIME ZONE UTC diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index 9b8095233839..f9dbe537ca24 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -3442,6 +3442,8 @@ func PerformCast(ctx *EvalContext, d Datum, t *types.T) (Datum, error) { return ParseDTime(ctx, d.Contents) case *DTime: return d, nil + case *DTimeTZ: + return MakeDTime(d.TimeOfDay), nil case *DTimestamp: return MakeDTime(timeofday.FromTime(d.Time)), nil case *DTimestampTZ: @@ -3457,7 +3459,12 @@ func PerformCast(ctx *EvalContext, d Datum, t *types.T) (Datum, error) { return ParseDTimeTZ(ctx, string(*d)) case *DCollatedString: return ParseDTimeTZ(ctx, d.Contents) - // TODO(otan#26097): expand for other valid types. + case *DTime: + return NewDTimeTZFromLocation(timeofday.TimeOfDay(*d), ctx.GetLocation()), nil + case *DTimeTZ: + return d, nil + case *DTimestampTZ: + return NewDTimeTZFromTime(d.Time), nil } case types.TimestampFamily: