Skip to content

Commit

Permalink
util/types: refact Time introduce a TimeInternal interface (#2098)
Browse files Browse the repository at this point in the history
Go time representation is not compatible with mysql, this
commit is a prepare before the code refact.

timeInternal is a interface for time representation, and it
would make the refact more smooth.
  • Loading branch information
tiancaiamao authored Nov 29, 2016
1 parent b09f97d commit 296f4a6
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 89 deletions.
2 changes: 1 addition & 1 deletion evaluator/builtin_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (s *testEvaluatorSuite) TestLength(c *C) {
{"abc", 3},
{1, 1},
{3.14, 4},
{types.Time{Time: time.Now(), Fsp: 6, Type: mysql.TypeDatetime}, 26},
{types.Time{Time: types.FromGoTime(time.Now()), Fsp: 6, Type: mysql.TypeDatetime}, 26},
{types.Bit{Value: 1, Width: 8}, 1},
{types.Hex{Value: 1}, 1},
{types.Set{Value: 1, Name: "abc"}, 3},
Expand Down
35 changes: 18 additions & 17 deletions evaluator/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ func builtinMonth(args []types.Datum, ctx context.Context) (types.Datum, error)
d.SetInt64(i)
return d, nil
}
i = int64(t.Month())
i = int64(t.Time.Month())
d.SetInt64(i)
return d, nil
}
Expand Down Expand Up @@ -426,7 +426,7 @@ func builtinNow(args []types.Datum, _ context.Context) (d types.Datum, err error
}

t := types.Time{
Time: time.Now(),
Time: types.FromGoTime(time.Now()),
Type: mysql.TypeDatetime,
// set unspecified for later round
Fsp: types.UnspecifiedFsp,
Expand Down Expand Up @@ -471,7 +471,7 @@ func builtinDayOfMonth(args []types.Datum, ctx context.Context) (d types.Datum,
return d, nil
}

d.SetInt64(int64(t.Day()))
d.SetInt64(int64(t.Time.Day()))
return d, nil
}

Expand All @@ -491,7 +491,7 @@ func builtinDayOfWeek(args []types.Datum, ctx context.Context) (d types.Datum, e
}

// 1 is Sunday, 2 is Monday, .... 7 is Saturday
d.SetInt64(int64(t.Weekday()) + 1)
d.SetInt64(int64(t.Time.Weekday() + 1))
return d, nil
}

Expand All @@ -509,7 +509,7 @@ func builtinDayOfYear(args []types.Datum, ctx context.Context) (types.Datum, err
return d, nil
}

yd := int64(t.YearDay())
yd := int64(t.Time.YearDay())
d.SetInt64(yd)
return d, nil
}
Expand All @@ -530,7 +530,7 @@ func builtinWeek(args []types.Datum, ctx context.Context) (types.Datum, error) {
}

// TODO: support multi mode for week
_, week := t.ISOWeek()
_, week := t.Time.ISOWeek()
wi := int64(week)
d.SetInt64(wi)
return d, nil
Expand All @@ -554,7 +554,7 @@ func builtinWeekDay(args []types.Datum, ctx context.Context) (types.Datum, error
// Monday is 0, ... Sunday = 6 in MySQL
// but in go, Sunday is 0, ... Saturday is 6
// w will do a conversion.
w := (int64(t.Weekday()) + 6) % 7
w := (int64(t.Time.Weekday()) + 6) % 7
d.SetInt64(w)
return d, nil
}
Expand All @@ -581,7 +581,7 @@ func builtinYear(args []types.Datum, ctx context.Context) (types.Datum, error) {
return d, nil
}

d.SetInt64(int64(t.Year()))
d.SetInt64(int64(t.Time.Year()))
return d, nil
}

Expand All @@ -601,7 +601,7 @@ func builtinYearWeek(args []types.Datum, ctx context.Context) (types.Datum, erro
}

// TODO: support multi mode for week
year, week := t.ISOWeek()
year, week := t.Time.ISOWeek()
d.SetInt64(int64(year*100 + week))
if d.GetInt64() < 0 {
d.SetInt64(math.MaxUint32)
Expand Down Expand Up @@ -653,7 +653,7 @@ func builtinFromUnixTime(args []types.Datum, ctx context.Context) (d types.Datum
return d, errors.Trace(err)
}
t := types.Time{
Time: time.Unix(integralPart, fractionalPart),
Time: types.FromGoTime(time.Unix(integralPart, fractionalPart)),
Type: mysql.TypeDatetime,
Fsp: types.UnspecifiedFsp,
}
Expand Down Expand Up @@ -983,14 +983,13 @@ func builtinStrToDate(args []types.Datum, _ context.Context) (types.Datum, error
d types.Datum
goTime time.Time
)
goTime = types.ZeroTime
if !strToDate(&goTime, date, format) {
d.SetNull()
return d, nil
}

t := types.Time{
Time: goTime,
Time: types.FromGoTime(goTime),
Type: mysql.TypeDatetime,
Fsp: types.UnspecifiedFsp,
}
Expand All @@ -1009,7 +1008,7 @@ func builtinSysDate(args []types.Datum, ctx context.Context) (types.Datum, error
func builtinCurrentDate(args []types.Datum, _ context.Context) (d types.Datum, err error) {
year, month, day := time.Now().Date()
t := types.Time{
Time: time.Date(year, month, day, 0, 0, 0, 0, time.Local),
Time: types.FromDate(year, int(month), day, 0, 0, 0, 0),
Type: mysql.TypeDate, Fsp: 0}
d.SetMysqlTime(t)
return d, nil
Expand Down Expand Up @@ -1055,7 +1054,7 @@ func builtinTime(args []types.Datum, ctx context.Context) (d types.Datum, err er
func builtinUTCDate(args []types.Datum, _ context.Context) (d types.Datum, err error) {
year, month, day := time.Now().UTC().Date()
t := types.Time{
Time: time.Date(year, month, day, 0, 0, 0, 0, time.UTC),
Time: types.FromGoTime(time.Date(year, month, day, 0, 0, 0, 0, time.UTC)),
Type: mysql.TypeDate, Fsp: types.UnspecifiedFsp}
d.SetMysqlTime(t)
return d, nil
Expand Down Expand Up @@ -1190,11 +1189,13 @@ func builtinDateArith(args []types.Datum, ctx context.Context) (d types.Datum, e
if op == ast.DateSub {
year, month, day, duration = -year, -month, -day, -duration
}
result.Time = result.Time.Add(duration)
result.Time = result.Time.AddDate(int(year), int(month), int(day))
if result.Time.Nanosecond() == 0 {
t := result.Time.GoTime()
t = t.Add(duration)
t = t.AddDate(int(year), int(month), int(day))
if t.Nanosecond() == 0 {
result.Fsp = 0
}
result.Time = types.FromGoTime(t)
d.SetMysqlTime(result)
return d, nil
}
Expand Down
8 changes: 4 additions & 4 deletions evaluator/builtin_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,9 @@ func (s *testEvaluatorSuite) TestStrToDate(c *C) {
Success bool
Expect time.Time
}{
{"20161122165022", "%Y%m%d%H%i%s", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.Local)},
{"2016 11 22 16 50 22", "%Y%m%d%H%i%s", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.Local)},
{"16-50-22 2016 11 22", "%H-%i-%s%Y%m%d", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.Local)},
{"20161122165022", "%Y%m%d%H%i%s", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.UTC)},
{"2016 11 22 16 50 22", "%Y%m%d%H%i%s", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.UTC)},
{"16-50-22 2016 11 22", "%H-%i-%s%Y%m%d", true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.UTC)},
{"16-50 2016 11 22", "%H-%i-%s%Y%m%d", false, time.Time{}},
}

Expand All @@ -609,6 +609,6 @@ func (s *testEvaluatorSuite) TestStrToDate(c *C) {
}
c.Assert(result.Kind(), Equals, types.KindMysqlTime)
value := result.GetMysqlTime()
c.Assert(value.Time, Equals, test.Expect)
c.Assert(value.Time.GoTime(), Equals, test.Expect)
}
}
16 changes: 11 additions & 5 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ func (s *testEvaluatorSuite) TestBinopNumeric(c *C) {
{uint64(1), opcode.Mul, uint64(1), 1},
{types.Time{}, opcode.Mul, 0, 0},
{types.ZeroDuration, opcode.Mul, 0, 0},
{types.Time{Time: time.Now(), Fsp: 0, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
{types.Time{Time: time.Now(), Fsp: 6, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
{types.Time{Time: types.FromGoTime(time.Now()), Fsp: 0, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
{types.Time{Time: types.FromGoTime(time.Now()), Fsp: 6, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
{types.Duration{Duration: 100000000, Fsp: 6}, opcode.Mul, 0, 0},

// div
Expand Down Expand Up @@ -877,11 +877,17 @@ func (s *testEvaluatorSuite) TestUnaryOp(c *C) {
{types.NewDecFromInt(1), opcode.Plus, types.NewDecFromInt(1)},
{types.Duration{Duration: time.Duration(838*3600 + 59*60 + 59), Fsp: types.DefaultFsp}, opcode.Plus,
types.Duration{Duration: time.Duration(838*3600 + 59*60 + 59), Fsp: types.DefaultFsp}},
{types.Time{Time: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), Type: mysql.TypeDatetime, Fsp: 0}, opcode.Plus, types.Time{Time: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), Type: mysql.TypeDatetime, Fsp: 0}},

{types.Time{
Time: types.FromGoTime(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)),
Type: mysql.TypeDatetime,
Fsp: 0},
opcode.Plus,
types.Time{
Time: types.FromGoTime(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)),
Type: mysql.TypeDatetime, Fsp: 0}},
{types.NewDecFromInt(1), opcode.Minus, types.NewDecFromInt(-1)},
{types.ZeroDuration, opcode.Minus, new(types.MyDecimal)},
{types.Time{Time: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), Type: mysql.TypeDatetime, Fsp: 0}, opcode.Minus, types.NewDecFromInt(-20091110230000)},
{types.Time{Time: types.FromGoTime(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)), Type: mysql.TypeDatetime, Fsp: 0}, opcode.Minus, types.NewDecFromInt(-20091110230000)},
}

for _, t := range tbl {
Expand Down
2 changes: 1 addition & 1 deletion evaluator/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func getTimeValue(ctx context.Context, v interface{}, tp byte, fsp int) (d types
case string:
upperX := strings.ToUpper(x)
if upperX == CurrentTimestamp {
value.Time = defaultTime
value.Time = types.FromGoTime(defaultTime)
} else if upperX == ZeroTimestamp {
value, _ = types.ParseTimeFromNum(0, tp, fsp)
} else {
Expand Down
10 changes: 5 additions & 5 deletions server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,19 @@ func dumpBinaryTime(dur time.Duration) (data []byte) {

func dumpBinaryDateTime(t types.Time, loc *time.Location) (data []byte) {
if t.Type == mysql.TypeTimestamp && loc != nil {
t.Time = t.In(loc)
t.Time = types.FromGoTime(t.Time.GoTime().In(loc))
}

year, mon, day := t.Year(), t.Month(), t.Day()
year, mon, day := t.Time.Year(), t.Time.Month(), t.Time.Day()
if t.IsZero() {
year, mon, day = 1, time.January, 1
year, mon, day = 1, int(time.January), 1
}
switch t.Type {
case mysql.TypeTimestamp, mysql.TypeDatetime:
data = append(data, 11)
data = append(data, dumpUint16(uint16(year))...)
data = append(data, byte(mon), byte(day), byte(t.Hour()), byte(t.Minute()), byte(t.Second()))
data = append(data, dumpUint32(uint32((t.Nanosecond() / 1000)))...)
data = append(data, byte(mon), byte(day), byte(t.Time.Hour()), byte(t.Time.Minute()), byte(t.Time.Second()))
data = append(data, dumpUint32(uint32(t.Time.Microsecond()))...)
case mysql.TypeDate, mysql.TypeNewDate:
data = append(data, 4)
data = append(data, dumpUint16(uint16(year))...) //year
Expand Down
2 changes: 1 addition & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ func checkArgs(args ...interface{}) error {
case time.Duration:
args[i] = types.Duration{Duration: x}
case time.Time:
args[i] = types.Time{Time: x, Type: mysql.TypeDatetime}
args[i] = types.Time{Time: types.FromGoTime(x), Type: mysql.TypeDatetime}
case nil:
default:
return errors.Errorf("cannot use arg[%d] (type %T):unsupported type", i, v)
Expand Down
2 changes: 1 addition & 1 deletion sessionctx/varsutil/varsutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func setSnapshotTS(s *variable.SessionVars, sVal string) error {
if err != nil {
return errors.Trace(err)
}
ts := (t.UnixNano() / int64(time.Millisecond)) << epochShiftBits
ts := (t.Time.GoTime().UnixNano() / int64(time.Millisecond)) << epochShiftBits
s.SnapshotTS = uint64(ts)
return nil
}
12 changes: 6 additions & 6 deletions util/types/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ func (s *testCompareSuite) TestCompare(c *C) {
{"1", float64(2), -1},
{"1", uint64(1), 0},
{"1", NewDecFromInt(1), 0},
{"2011-01-01 11:11:11", Time{Time: time.Now(), Type: mysql.TypeDatetime, Fsp: 0}, -1},
{"2011-01-01 11:11:11", Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 0}, -1},
{"12:00:00", ZeroDuration, 1},
{ZeroDuration, ZeroDuration, 0},
{Time{Time: time.Now().Add(time.Second * 10), Type: mysql.TypeDatetime, Fsp: 0},
Time{Time: time.Now(), Type: mysql.TypeDatetime, Fsp: 0}, 1},
{Time{Time: FromGoTime(time.Now().Add(time.Second * 10)), Type: mysql.TypeDatetime, Fsp: 0},
Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 0}, 1},

{nil, 2, -1},
{nil, nil, 0},
Expand Down Expand Up @@ -91,9 +91,9 @@ func (s *testCompareSuite) TestCompare(c *C) {
{[]byte(""), nil, 1},
{[]byte(""), []byte("sff"), -1},

{Time{}, nil, 1},
{Time{}, Time{Time: time.Now(), Type: mysql.TypeDatetime, Fsp: 3}, -1},
{Time{Time: time.Now(), Type: mysql.TypeDatetime, Fsp: 3}, "0000-00-00 00:00:00", 1},
{Time{Time: ZeroTime}, nil, 1},
{Time{Time: ZeroTime}, Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 3}, -1},
{Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 3}, "0000-00-00 00:00:00", 1},

{Duration{Duration: time.Duration(34), Fsp: 2}, nil, 1},
{Duration{Duration: time.Duration(34), Fsp: 2}, Duration{Duration: time.Duration(29034), Fsp: 2}, -1},
Expand Down
2 changes: 1 addition & 1 deletion util/types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ func (d *Datum) convertToMysqlYear(target *FieldType) (Datum, error) {
case KindString, KindBytes:
y, err = StrToInt(d.GetString())
case KindMysqlTime:
y = int64(d.GetMysqlTime().Year())
y = int64(d.GetMysqlTime().Time.Year())
case KindMysqlDuration:
y = int64(time.Now().Year())
default:
Expand Down
Loading

0 comments on commit 296f4a6

Please sign in to comment.