diff --git a/pkg/sql/logictest/testdata/logic_test/timestamp b/pkg/sql/logictest/testdata/logic_test/timestamp index eaed574fafc5..1aac5dabc572 100644 --- a/pkg/sql/logictest/testdata/logic_test/timestamp +++ b/pkg/sql/logictest/testdata/logic_test/timestamp @@ -14,10 +14,8 @@ SELECT '2000-05-05 10:00:00+03':::TIMESTAMP FROM a ---- 2000-05-05 10:00:00 +0000 +0000 -query T +query error syntax error: unimplemented select '1-1-18 1:00:00.001':::TIMESTAMP(0) ----- -2001-01-18 01:00:00 +0000 +0000 query T select '1-1-18 1:00:00.001':::TIMESTAMP(6) @@ -29,10 +27,8 @@ select '1-1-18 1:00:00.001':::TIMESTAMP ---- 2001-01-18 01:00:00.001 +0000 +0000 -query T +query error syntax error: unimplemented select '1-1-18 1:00:00.001-8':::TIMESTAMPTZ(0) ----- -2001-01-18 09:00:00 +0000 UTC query T select '1-1-18 1:00:00.001-8':::TIMESTAMPTZ(6) diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 5f83d16a93e2..ee3fcf536531 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -7228,8 +7228,8 @@ const_datetime: | TIMESTAMP '(' iconst32 ')' opt_timezone { prec := $3.int32() - if !(prec == 6 || prec == 0) { - return unimplementedWithIssue(sqllex, 32098) + if prec != 6 { + return unimplementedWithIssue(sqllex, 32098) } if $5.bool() { $$.val = types.MakeTimestampTZ(prec) @@ -7244,7 +7244,7 @@ const_datetime: | TIMESTAMPTZ '(' iconst32 ')' { prec := $3.int32() - if !(prec == 6 || prec == 0) { + if prec != 6 { return unimplementedWithIssue(sqllex, 32098) } $$.val = types.MakeTimestampTZ(prec) diff --git a/pkg/sql/sem/tree/col_types_test.go b/pkg/sql/sem/tree/col_types_test.go index e03e06982d97..ef2c6e8a5bc0 100644 --- a/pkg/sql/sem/tree/col_types_test.go +++ b/pkg/sql/sem/tree/col_types_test.go @@ -46,11 +46,7 @@ func TestParseColumnType(t *testing.T) { {"JSONB", types.Jsonb}, {"TIME", types.Time}, {"TIMESTAMP", types.Timestamp}, - {"TIMESTAMP(0)", types.MakeTimestamp(0)}, - {"TIMESTAMP(6)", types.MakeTimestamp(6)}, {"TIMESTAMPTZ", types.TimestampTZ}, - {"TIMESTAMPTZ(0)", types.MakeTimestampTZ(0)}, - {"TIMESTAMPTZ(6)", types.MakeTimestampTZ(6)}, {"INTERVAL", types.Interval}, {"STRING", types.String}, {"CHAR", types.MakeChar(1)}, diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index 869404a14d2d..6a6dc86caafc 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -3440,18 +3440,14 @@ func PerformCast(ctx *EvalContext, d Datum, t *types.T) (Datum, error) { case types.TimestampFamily: // TODO(knz): Timestamp from float, decimal. - prec := time.Microsecond - if t.Precision() == 0 { - prec = time.Second - } switch d := d.(type) { case *DString: - return ParseDTimestamp(ctx, string(*d), prec) + return ParseDTimestamp(ctx, string(*d), time.Microsecond) case *DCollatedString: - return ParseDTimestamp(ctx, d.Contents, prec) + return ParseDTimestamp(ctx, d.Contents, time.Microsecond) case *DDate: t, err := d.ToTime() - return MakeDTimestamp(t, prec), err + return MakeDTimestamp(t, time.Microsecond), err case *DInt: return MakeDTimestamp(timeutil.Unix(int64(*d), 0), time.Second), nil case *DTimestamp: @@ -3463,24 +3459,20 @@ func PerformCast(ctx *EvalContext, d Datum, t *types.T) (Datum, error) { case types.TimestampTZFamily: // TODO(knz): TimestampTZ from float, decimal. - prec := time.Microsecond - if t.Precision() == 0 { - prec = time.Second - } switch d := d.(type) { case *DString: - return ParseDTimestampTZ(ctx, string(*d), prec) + return ParseDTimestampTZ(ctx, string(*d), time.Microsecond) case *DCollatedString: - return ParseDTimestampTZ(ctx, d.Contents, prec) + return ParseDTimestampTZ(ctx, d.Contents, time.Microsecond) case *DDate: t, err := d.ToTime() _, before := t.Zone() _, after := t.In(ctx.GetLocation()).Zone() - return MakeDTimestampTZ(t.Add(time.Duration(before-after)*time.Second), prec), err + return MakeDTimestampTZ(t.Add(time.Duration(before-after)*time.Second), time.Microsecond), err case *DTimestamp: _, before := d.Time.Zone() _, after := d.Time.In(ctx.GetLocation()).Zone() - return MakeDTimestampTZ(d.Time.Add(time.Duration(before-after)*time.Second), prec), nil + return MakeDTimestampTZ(d.Time.Add(time.Duration(before-after)*time.Second), time.Microsecond), nil case *DInt: return MakeDTimestampTZ(timeutil.Unix(int64(*d), 0), time.Second), nil case *DTimestampTZ: diff --git a/pkg/sql/sem/tree/parse_string.go b/pkg/sql/sem/tree/parse_string.go index 7d78d2f66445..91e178981159 100644 --- a/pkg/sql/sem/tree/parse_string.go +++ b/pkg/sql/sem/tree/parse_string.go @@ -83,14 +83,8 @@ func parseStringAs(t *types.T, s string, ctx ParseTimeContext) (Datum, error) { case types.TimeFamily: return ParseDTime(ctx, s) case types.TimestampFamily: - if t.Precision() == 0 { - return ParseDTimestamp(ctx, s, time.Second) - } return ParseDTimestamp(ctx, s, time.Microsecond) case types.TimestampTZFamily: - if t.Precision() == 0 { - return ParseDTimestampTZ(ctx, s, time.Second) - } return ParseDTimestampTZ(ctx, s, time.Microsecond) case types.UuidFamily: return ParseDUuidFromString(s) diff --git a/pkg/sql/types/types.go b/pkg/sql/types/types.go index 2d33d5fed48d..3e47ee230f14 100644 --- a/pkg/sql/types/types.go +++ b/pkg/sql/types/types.go @@ -252,8 +252,9 @@ var ( // precision. For example: // // YYYY-MM-DD HH:MM:SS.ssssss + // Timestamp = &T{InternalType: InternalType{ - Family: TimestampFamily, Precision: -1, Oid: oid.T_timestamp, Locale: &emptyLocale}} + Family: TimestampFamily, Oid: oid.T_timestamp, Locale: &emptyLocale}} // TimestampTZ is the type of a value specifying year, month, day, hour, // minute, and second, as well as an associated timezone. By default, it has @@ -262,7 +263,7 @@ var ( // YYYY-MM-DD HH:MM:SS.ssssss+-ZZ:ZZ // TimestampTZ = &T{InternalType: InternalType{ - Family: TimestampTZFamily, Precision: -1, Oid: oid.T_timestamptz, Locale: &emptyLocale}} + Family: TimestampTZFamily, Oid: oid.T_timestamptz, Locale: &emptyLocale}} // Interval is the type of a value describing a duration of time. By default, // it has microsecond precision. @@ -643,21 +644,27 @@ func MakeTime(precision int32) *T { // MakeTimestamp constructs a new instance of a TIMESTAMP type that has at most // the given number of fractional second digits. func MakeTimestamp(precision int32) *T { - if precision == 0 || precision == 6 { - return &T{InternalType: InternalType{ - Family: TimestampFamily, Oid: oid.T_timestamp, Precision: precision, Locale: &emptyLocale}} + if precision == 0 { + return Timestamp + } + if precision != 6 { + panic(errors.AssertionFailedf("precision %d is not currently supported", precision)) } - panic(errors.AssertionFailedf("precision %d is not currently supported", precision)) + return &T{InternalType: InternalType{ + Family: TimestampFamily, Oid: oid.T_timestamp, Precision: precision, Locale: &emptyLocale}} } // MakeTimestampTZ constructs a new instance of a TIMESTAMPTZ type that has at // most the given number of fractional second digits. func MakeTimestampTZ(precision int32) *T { - if precision == 0 || precision == 6 { - return &T{InternalType: InternalType{ - Family: TimestampTZFamily, Oid: oid.T_timestamptz, Precision: precision, Locale: &emptyLocale}} + if precision == 0 { + return TimestampTZ + } + if precision != 6 { + panic(errors.AssertionFailedf("precision %d is not currently supported", precision)) } - panic(errors.AssertionFailedf("precision %d is not currently supported", precision)) + return &T{InternalType: InternalType{ + Family: TimestampTZFamily, Oid: oid.T_timestamptz, Precision: precision, Locale: &emptyLocale}} } // MakeArray constructs a new instance of an ArrayFamily type with the given @@ -768,7 +775,6 @@ func (t *T) Width() int32 { // TIMESTAMP : max # fractional second digits // TIMESTAMPTZ: max # fractional second digits // -// For TIMESTAMP and TIMESTAMP TZ, the precision field is -1 for a default precision value of 6. // Precision is always 0 for other types. func (t *T) Precision() int32 { return t.InternalType.Precision @@ -1154,13 +1160,7 @@ func (t *T) SQLString() string { case JsonFamily: // Only binary JSON is currently supported. return "JSONB" - case TimestampFamily, TimestampTZFamily: - if t.Precision() != -1 { - return fmt.Sprintf("%s(%d)", strings.ToUpper(t.Name()), t.Precision()) - } - // This is the timestamp with the default precision value - return strings.ToUpper(t.Name()) - case TimeFamily: + case TimeFamily, TimestampFamily, TimestampTZFamily: if t.Precision() > 0 { return fmt.Sprintf("%s(%d)", strings.ToUpper(t.Name()), t.Precision()) } diff --git a/pkg/sql/types/types_test.go b/pkg/sql/types/types_test.go index 65ff9c36a622..6fb695cca153 100644 --- a/pkg/sql/types/types_test.go +++ b/pkg/sql/types/types_test.go @@ -222,15 +222,17 @@ func TestTypes(t *testing.T) { {MakeTime(6), MakeScalar(TimeFamily, oid.T_time, 6, 0, emptyLocale)}, // TIMESTAMP + {MakeTimestamp(0), Timestamp}, {MakeTimestamp(0), &T{InternalType: InternalType{ - Family: TimestampFamily, Precision: 0, Oid: oid.T_timestamp, Locale: &emptyLocale}}}, + Family: TimestampFamily, Oid: oid.T_timestamp, Locale: &emptyLocale}}}, {MakeTimestamp(6), &T{InternalType: InternalType{ Family: TimestampFamily, Oid: oid.T_timestamp, Precision: 6, Locale: &emptyLocale}}}, {MakeTimestamp(6), MakeScalar(TimestampFamily, oid.T_timestamp, 6, 0, emptyLocale)}, // TIMESTAMPTZ + {MakeTimestampTZ(0), TimestampTZ}, {MakeTimestampTZ(0), &T{InternalType: InternalType{ - Family: TimestampTZFamily, Precision: 0, Oid: oid.T_timestamptz, Locale: &emptyLocale}}}, + Family: TimestampTZFamily, Oid: oid.T_timestamptz, Locale: &emptyLocale}}}, {MakeTimestampTZ(6), &T{InternalType: InternalType{ Family: TimestampTZFamily, Oid: oid.T_timestamptz, Precision: 6, Locale: &emptyLocale}}}, {MakeTimestampTZ(6), MakeScalar(TimestampTZFamily, oid.T_timestamptz, 6, 0, emptyLocale)},