Skip to content

Commit

Permalink
Use time zone when casting date to timestamp.
Browse files Browse the repository at this point in the history
Fix current_date.
  • Loading branch information
vivekmenezes committed Oct 9, 2015
1 parent 80649e1 commit 8208796
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 22 deletions.
2 changes: 1 addition & 1 deletion sql/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (p parameters) Arg(name string) (parser.Datum, bool) {
case *driver.Datum_StringVal:
return parser.DString(t.StringVal), true
case *driver.Datum_DateVal:
return parser.MakeDDate(t.DateVal.GoTime()), true
return parser.DDate{Time: t.DateVal.GoTime()}, true
case *driver.Datum_TimeVal:
return parser.DTimestamp{Time: t.TimeVal.GoTime()}, true
case *driver.Datum_IntervalVal:
Expand Down
2 changes: 1 addition & 1 deletion sql/parser/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ var builtins = map[string][]builtin{
types: typeList{},
returnType: DummyDate,
fn: func(e EvalContext, args DTuple) (Datum, error) {
return MakeDDate(e.StmtTimestamp.Time), nil
return e.makeDDate(e.StmtTimestamp.Time)
},
},
},
Expand Down
9 changes: 1 addition & 8 deletions sql/parser/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,6 @@ type DDate struct {
time.Time // Must always be UTC!
}

// MakeDDate constructs a DDate from a time.Time.
func MakeDDate(t time.Time) DDate {
year, month, day := t.Date()
return DDate{Time: time.Date(year, month, day, 0, 0, 0, 0, time.UTC)}
}

// Type implements the Datum interface.
func (d DDate) Type() string {
return "date"
Expand Down Expand Up @@ -435,9 +429,8 @@ func (d DTimestamp) IsMin() bool {
return d.Before(d.Add(-1))
}

// TODO:(vivek) implement SET TIME ZONE to improve presentation.
func (d DTimestamp) String() string {
return d.Format(TimestampWithOffsetZoneFormat)
return d.UTC().Format(TimestampWithOffsetZoneFormat)
}

// DInterval is the interval Datum.
Expand Down
29 changes: 19 additions & 10 deletions sql/parser/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,16 @@ var defaultContext = EvalContext{
},
}

// makeDDate constructs a DDate from a time.Time in the session time zone.
func (ctx EvalContext) makeDDate(t time.Time) (Datum, error) {
loc, err := ctx.GetLocation()
if err != nil {
return DNull, err
}
year, month, day := t.In(loc).Date()
return DDate{Time: time.Date(year, month, day, 0, 0, 0, 0, time.UTC)}, nil
}

// EvalExpr evaluates an SQL expression. Expression evaluation is a mostly
// straightforward walk over the parse tree. The only significant complexity is
// the handling of types and implicit conversions. See binOps and cmpOps for
Expand Down Expand Up @@ -1133,19 +1143,20 @@ func (ctx EvalContext) evalCastExpr(expr *CastExpr) (Datum, error) {
case DString:
return ParseDate(d)
case DTimestamp:
loc, err := ctx.GetLocation()
if err != nil {
return DNull, err
}
return MakeDDate(d.Time.In(loc)), nil
return ctx.makeDDate(d.Time)
}

case *TimestampType:
switch d := d.(type) {
case DString:
return ctx.ParseTimestamp(d)
case DDate:
return DTimestamp{Time: d.Time}, nil
loc, err := ctx.GetLocation()
if err != nil {
return DNull, err
}
year, month, day := d.Date()
return DTimestamp{Time: time.Date(year, month, day, 0, 0, 0, 0, loc)}, nil
}

case *IntervalType:
Expand Down Expand Up @@ -1246,8 +1257,7 @@ func ParseDate(s DString) (DDate, error) {
if err != nil {
return DummyDate, err
}

return MakeDDate(t), nil
return DDate{Time: t}, nil
}

// ParseTimestamp parses the timestamp.
Expand All @@ -1271,8 +1281,7 @@ func (ctx EvalContext) ParseTimestamp(s DString) (DTimestamp, error) {
} {
var t time.Time
if t, err = time.ParseInLocation(format, str, loc); err == nil {
// Always return the time in the session time zone.
return DTimestamp{Time: t.In(loc)}, nil
return DTimestamp{Time: t}, nil
}
}

Expand Down
4 changes: 2 additions & 2 deletions sql/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ func decodeTableKey(valType parser.Datum, key []byte) (parser.Datum, []byte, err
return parser.DBytes(r), rkey, err
case parser.DDate:
rkey, t, err := encoding.DecodeTime(key)
return parser.MakeDDate(t), rkey, err
return parser.DDate{Time: t}, rkey, err
case parser.DTimestamp:
rkey, t, err := encoding.DecodeTime(key)
return parser.DTimestamp{Time: t}, rkey, err
Expand Down Expand Up @@ -516,7 +516,7 @@ func unmarshalColumnValue(kind ColumnType_Kind, value *roachpb.Value) (parser.Da
if err != nil {
return nil, err
}
return parser.MakeDDate(v), nil
return parser.DDate{Time: v}, nil
case ColumnType_TIMESTAMP:
v, err := value.GetTime()
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions sql/testdata/datetime
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,18 @@ SELECT '2015-08-24 21:45:45.53453'::timestamp
----
2015-08-25 04:45:45.53453 +0000 UTC

# Check that casting from a timestamp to a date and vice versa
# uses the time zone.
query TTT
SELECT b::date FROM u WHERE a = 123
----
2015-08-29

query TTT
SELECT c::timestamp FROM u WHERE a = 123
----
2015-08-30 07:00:00 +0000 UTC

statement ok
SET TIME ZONE -7

Expand Down

0 comments on commit 8208796

Please sign in to comment.