github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/evaluator/builtin_time_test.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package evaluator 15 16 import ( 17 "strings" 18 "time" 19 20 . "github.com/insionng/yougam/libraries/pingcap/check" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/ast" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 24 "github.com/insionng/yougam/libraries/pingcap/tidb/util/mock" 25 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 26 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testutil" 27 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 28 ) 29 30 func (s *testEvaluatorSuite) TestDate(c *C) { 31 defer testleak.AfterTest(c)() 32 tblDate := []struct { 33 Input interface{} 34 Expect interface{} 35 }{ 36 {"2011-11-11", "2011-11-11"}, 37 {nil, nil}, 38 {"2011-11-11 10:10:10", "2011-11-11"}, 39 } 40 dtblDate := tblToDtbl(tblDate) 41 42 for _, t := range dtblDate { 43 v, err := builtinDate(t["Input"], nil) 44 c.Assert(err, IsNil) 45 if v.Kind() != types.KindMysqlTime { 46 c.Assert(v, testutil.DatumEquals, t["Expect"][0]) 47 } else { 48 c.Assert(v.GetMysqlTime().String(), Equals, t["Expect"][0].GetString()) 49 } 50 } 51 52 // test year, month and day 53 tbl := []struct { 54 Input string 55 Year int64 56 Month int64 57 DayOfMonth int64 58 DayOfWeek int64 59 DayOfYear int64 60 WeekDay int64 61 DayName string 62 Week int64 63 WeekOfYear int64 64 YearWeek int64 65 }{ 66 {"2000-01-01", 2000, 1, 1, 7, 1, 5, "Saturday", 52, 52, 199952}, 67 {"2011-11-11", 2011, 11, 11, 6, 315, 4, "Friday", 45, 45, 201145}, 68 } 69 70 dtbl := tblToDtbl(tbl) 71 for _, t := range dtbl { 72 args := t["Input"] 73 v, err := builtinYear(args, nil) 74 c.Assert(err, IsNil) 75 c.Assert(v, testutil.DatumEquals, t["Year"][0]) 76 77 v, err = builtinMonth(args, nil) 78 c.Assert(err, IsNil) 79 c.Assert(v, testutil.DatumEquals, t["Month"][0]) 80 81 v, err = builtinDayOfMonth(args, nil) 82 c.Assert(err, IsNil) 83 c.Assert(v, testutil.DatumEquals, t["DayOfMonth"][0]) 84 85 v, err = builtinDayOfWeek(args, nil) 86 c.Assert(err, IsNil) 87 c.Assert(v, testutil.DatumEquals, t["DayOfWeek"][0]) 88 89 v, err = builtinDayOfYear(args, nil) 90 c.Assert(err, IsNil) 91 c.Assert(v, testutil.DatumEquals, t["DayOfYear"][0]) 92 93 v, err = builtinWeekDay(args, nil) 94 c.Assert(err, IsNil) 95 c.Assert(v, testutil.DatumEquals, t["WeekDay"][0]) 96 97 v, err = builtinDayName(args, nil) 98 c.Assert(err, IsNil) 99 c.Assert(v, testutil.DatumEquals, t["DayName"][0]) 100 101 v, err = builtinWeek(args, nil) 102 c.Assert(err, IsNil) 103 c.Assert(v, testutil.DatumEquals, t["Week"][0]) 104 105 v, err = builtinWeekOfYear(args, nil) 106 c.Assert(err, IsNil) 107 c.Assert(v, testutil.DatumEquals, t["WeekOfYear"][0]) 108 109 v, err = builtinYearWeek(args, nil) 110 c.Assert(err, IsNil) 111 c.Assert(v, testutil.DatumEquals, t["YearWeek"][0]) 112 } 113 114 // test nil 115 tblNil := []struct { 116 Input interface{} 117 Year interface{} 118 Month interface{} 119 DayOfMonth interface{} 120 DayOfWeek interface{} 121 DayOfYear interface{} 122 WeekDay interface{} 123 DayName interface{} 124 Week interface{} 125 WeekOfYear interface{} 126 YearWeek interface{} 127 }{ 128 {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}, 129 {"0000-00-00", int64(0), int64(0), int64(0), nil, nil, nil, nil, nil, nil, nil}, 130 } 131 132 dtblNil := tblToDtbl(tblNil) 133 for _, t := range dtblNil { 134 args := t["Input"] 135 v, err := builtinYear(args, nil) 136 c.Assert(err, IsNil) 137 c.Assert(v, testutil.DatumEquals, t["Year"][0]) 138 139 v, err = builtinMonth(args, nil) 140 c.Assert(err, IsNil) 141 c.Assert(v, testutil.DatumEquals, t["Month"][0]) 142 143 v, err = builtinDayOfMonth(args, nil) 144 c.Assert(err, IsNil) 145 c.Assert(v, testutil.DatumEquals, t["DayOfMonth"][0]) 146 147 v, err = builtinDayOfWeek(args, nil) 148 c.Assert(err, IsNil) 149 c.Assert(v, testutil.DatumEquals, t["DayOfWeek"][0]) 150 151 v, err = builtinDayOfYear(args, nil) 152 c.Assert(err, IsNil) 153 c.Assert(v, testutil.DatumEquals, t["DayOfYear"][0]) 154 155 v, err = builtinWeekDay(args, nil) 156 c.Assert(err, IsNil) 157 c.Assert(v, testutil.DatumEquals, t["WeekDay"][0]) 158 159 v, err = builtinWeekDay(args, nil) 160 c.Assert(err, IsNil) 161 c.Assert(v, testutil.DatumEquals, t["DayName"][0]) 162 163 v, err = builtinWeek(args, nil) 164 c.Assert(err, IsNil) 165 c.Assert(v, testutil.DatumEquals, t["Week"][0]) 166 167 v, err = builtinWeekOfYear(args, nil) 168 c.Assert(err, IsNil) 169 c.Assert(v, testutil.DatumEquals, t["WeekOfYear"][0]) 170 171 v, err = builtinYearWeek(args, nil) 172 c.Assert(err, IsNil) 173 c.Assert(v, testutil.DatumEquals, t["YearWeek"][0]) 174 } 175 } 176 177 func (s *testEvaluatorSuite) TestClock(c *C) { 178 defer testleak.AfterTest(c)() 179 // test hour, minute, second, micro second 180 181 tbl := []struct { 182 Input string 183 Hour int64 184 Minute int64 185 Second int64 186 MicroSecond int64 187 }{ 188 {"10:10:10.123456", 10, 10, 10, 123456}, 189 {"11:11:11.11", 11, 11, 11, 110000}, 190 {"2010-10-10 11:11:11.11", 11, 11, 11, 110000}, 191 } 192 193 dtbl := tblToDtbl(tbl) 194 for _, t := range dtbl { 195 v, err := builtinHour(t["Input"], nil) 196 c.Assert(err, IsNil) 197 c.Assert(v, testutil.DatumEquals, t["Hour"][0]) 198 199 v, err = builtinMinute(t["Input"], nil) 200 c.Assert(err, IsNil) 201 c.Assert(v, testutil.DatumEquals, t["Minute"][0]) 202 203 v, err = builtinSecond(t["Input"], nil) 204 c.Assert(err, IsNil) 205 c.Assert(v, testutil.DatumEquals, t["Second"][0]) 206 207 v, err = builtinMicroSecond(t["Input"], nil) 208 c.Assert(err, IsNil) 209 c.Assert(v, testutil.DatumEquals, t["MicroSecond"][0]) 210 } 211 212 // nil 213 v, err := builtinHour(types.MakeDatums(nil), nil) 214 c.Assert(err, IsNil) 215 c.Assert(v.Kind(), Equals, types.KindNull) 216 217 v, err = builtinMinute(types.MakeDatums(nil), nil) 218 c.Assert(err, IsNil) 219 c.Assert(v.Kind(), Equals, types.KindNull) 220 221 v, err = builtinSecond(types.MakeDatums(nil), nil) 222 c.Assert(err, IsNil) 223 c.Assert(v.Kind(), Equals, types.KindNull) 224 225 v, err = builtinMicroSecond(types.MakeDatums(nil), nil) 226 c.Assert(err, IsNil) 227 c.Assert(v.Kind(), Equals, types.KindNull) 228 229 // test error 230 errTbl := []string{ 231 "2011-11-11T10:10:10.11", 232 } 233 234 for _, t := range errTbl { 235 td := types.MakeDatums(t) 236 _, err := builtinHour(td, nil) 237 c.Assert(err, NotNil) 238 239 _, err = builtinMinute(td, nil) 240 c.Assert(err, NotNil) 241 242 _, err = builtinSecond(td, nil) 243 c.Assert(err, NotNil) 244 245 _, err = builtinMicroSecond(td, nil) 246 c.Assert(err, NotNil) 247 } 248 } 249 250 func (s *testEvaluatorSuite) TestNow(c *C) { 251 defer testleak.AfterTest(c)() 252 v, err := builtinNow(nil, nil) 253 c.Assert(err, IsNil) 254 t := v.GetMysqlTime() 255 // we canot use a constant value to check now, so here 256 // just to check whether has fractional seconds part. 257 c.Assert(strings.Contains(t.String(), "."), IsFalse) 258 259 v, err = builtinNow(types.MakeDatums(6), nil) 260 c.Assert(err, IsNil) 261 t = v.GetMysqlTime() 262 c.Assert(strings.Contains(t.String(), "."), IsTrue) 263 264 _, err = builtinNow(types.MakeDatums(8), nil) 265 c.Assert(err, NotNil) 266 267 _, err = builtinNow(types.MakeDatums(-2), nil) 268 c.Assert(err, NotNil) 269 } 270 271 func (s *testEvaluatorSuite) TestSysDate(c *C) { 272 defer testleak.AfterTest(c)() 273 last := time.Now() 274 v, err := builtinSysDate(types.MakeDatums(nil), nil) 275 c.Assert(err, IsNil) 276 n := v.GetMysqlTime() 277 c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat)) 278 279 v, err = builtinSysDate(types.MakeDatums(6), nil) 280 c.Assert(err, IsNil) 281 n = v.GetMysqlTime() 282 c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat)) 283 284 _, err = builtinSysDate(types.MakeDatums(-2), nil) 285 c.Assert(err, NotNil) 286 } 287 288 func (s *testEvaluatorSuite) TestCurrentDate(c *C) { 289 defer testleak.AfterTest(c)() 290 last := time.Now() 291 v, err := builtinCurrentDate(types.MakeDatums(nil), nil) 292 c.Assert(err, IsNil) 293 n := v.GetMysqlTime() 294 c.Assert(n.String(), GreaterEqual, last.Format(mysql.DateFormat)) 295 } 296 297 func (s *testEvaluatorSuite) TestCurrentTime(c *C) { 298 defer testleak.AfterTest(c)() 299 tfStr := "15:04:05" 300 301 last := time.Now() 302 v, err := builtinCurrentTime(types.MakeDatums(nil), nil) 303 c.Assert(err, IsNil) 304 n := v.GetMysqlDuration() 305 c.Assert(n.String(), HasLen, 8) 306 c.Assert(n.String(), GreaterEqual, last.Format(tfStr)) 307 308 v, err = builtinCurrentTime(types.MakeDatums(3), nil) 309 c.Assert(err, IsNil) 310 n = v.GetMysqlDuration() 311 c.Assert(n.String(), HasLen, 12) 312 c.Assert(n.String(), GreaterEqual, last.Format(tfStr)) 313 314 v, err = builtinCurrentTime(types.MakeDatums(6), nil) 315 c.Assert(err, IsNil) 316 n = v.GetMysqlDuration() 317 c.Assert(n.String(), HasLen, 15) 318 c.Assert(n.String(), GreaterEqual, last.Format(tfStr)) 319 320 v, err = builtinCurrentTime(types.MakeDatums(-1), nil) 321 c.Assert(err, NotNil) 322 323 v, err = builtinCurrentTime(types.MakeDatums(7), nil) 324 c.Assert(err, NotNil) 325 } 326 327 func (s *testEvaluatorSuite) TestUTCDate(c *C) { 328 defer testleak.AfterTest(c)() 329 last := time.Now().UTC() 330 v, err := builtinUTCDate(types.MakeDatums(nil), nil) 331 c.Assert(err, IsNil) 332 n := v.GetMysqlTime() 333 c.Assert(n.String(), GreaterEqual, last.Format(mysql.DateFormat)) 334 } 335 336 func (s *testEvaluatorSuite) TestDateArith(c *C) { 337 defer testleak.AfterTest(c)() 338 ctx := mock.NewContext() 339 340 // list all test cases 341 tests := []struct { 342 Date interface{} 343 Interval interface{} 344 Unit string 345 AddResult interface{} 346 SubResult interface{} 347 error bool 348 }{ 349 // basic test 350 {"2011-11-11", 1, "DAY", "2011-11-12", "2011-11-10", false}, 351 // nil test 352 {nil, 1, "DAY", nil, nil, false}, 353 {"2011-11-11", nil, "DAY", nil, nil, false}, 354 // tests for different units 355 {"2011-11-11 10:10:10", 1000, "MICROSECOND", "2011-11-11 10:10:10.001000", "2011-11-11 10:10:09.999000", false}, 356 {"2011-11-11 10:10:10", "10", "SECOND", "2011-11-11 10:10:20", "2011-11-11 10:10:00", false}, 357 {"2011-11-11 10:10:10", "10", "MINUTE", "2011-11-11 10:20:10", "2011-11-11 10:00:10", false}, 358 {"2011-11-11 10:10:10", "10", "HOUR", "2011-11-11 20:10:10", "2011-11-11 00:10:10", false}, 359 {"2011-11-11 10:10:10", "11", "DAY", "2011-11-22 10:10:10", "2011-10-31 10:10:10", false}, 360 {"2011-11-11 10:10:10", "2", "WEEK", "2011-11-25 10:10:10", "2011-10-28 10:10:10", false}, 361 {"2011-11-11 10:10:10", "2", "MONTH", "2012-01-11 10:10:10", "2011-09-11 10:10:10", false}, 362 {"2011-11-11 10:10:10", "4", "QUARTER", "2012-11-11 10:10:10", "2010-11-11 10:10:10", false}, 363 {"2011-11-11 10:10:10", "2", "YEAR", "2013-11-11 10:10:10", "2009-11-11 10:10:10", false}, 364 {"2011-11-11 10:10:10", "10.00100000", "SECOND_MICROSECOND", "2011-11-11 10:10:20.100000", "2011-11-11 10:09:59.900000", false}, 365 {"2011-11-11 10:10:10", "10.0010000000", "SECOND_MICROSECOND", "2011-11-11 10:10:30", "2011-11-11 10:09:50", false}, 366 {"2011-11-11 10:10:10", "10.0010000010", "SECOND_MICROSECOND", "2011-11-11 10:10:30.000010", "2011-11-11 10:09:49.999990", false}, 367 {"2011-11-11 10:10:10", "10:10.100", "MINUTE_MICROSECOND", "2011-11-11 10:20:20.100000", "2011-11-11 09:59:59.900000", false}, 368 {"2011-11-11 10:10:10", "10:10", "MINUTE_SECOND", "2011-11-11 10:20:20", "2011-11-11 10:00:00", false}, 369 {"2011-11-11 10:10:10", "10:10:10.100", "HOUR_MICROSECOND", "2011-11-11 20:20:20.100000", "2011-11-10 23:59:59.900000", false}, 370 {"2011-11-11 10:10:10", "10:10:10", "HOUR_SECOND", "2011-11-11 20:20:20", "2011-11-11 00:00:00", false}, 371 {"2011-11-11 10:10:10", "10:10", "HOUR_MINUTE", "2011-11-11 20:20:10", "2011-11-11 00:00:10", false}, 372 {"2011-11-11 10:10:10", "11 10:10:10.100", "DAY_MICROSECOND", "2011-11-22 20:20:20.100000", "2011-10-30 23:59:59.900000", false}, 373 {"2011-11-11 10:10:10", "11 10:10:10", "DAY_SECOND", "2011-11-22 20:20:20", "2011-10-31 00:00:00", false}, 374 {"2011-11-11 10:10:10", "11 10:10", "DAY_MINUTE", "2011-11-22 20:20:10", "2011-10-31 00:00:10", false}, 375 {"2011-11-11 10:10:10", "11 10", "DAY_HOUR", "2011-11-22 20:10:10", "2011-10-31 00:10:10", false}, 376 {"2011-11-11 10:10:10", "11-1", "YEAR_MONTH", "2022-12-11 10:10:10", "2000-10-11 10:10:10", false}, 377 {"2011-11-11 10:10:10", "11-11", "YEAR_MONTH", "2023-10-11 10:10:10", "1999-12-11 10:10:10", false}, 378 // tests for interval in day forms 379 {"2011-11-11 10:10:10", "20", "DAY", "2011-12-01 10:10:10", "2011-10-22 10:10:10", false}, 380 {"2011-11-11 10:10:10", 19.88, "DAY", "2011-12-01 10:10:10", "2011-10-22 10:10:10", false}, 381 {"2011-11-11 10:10:10", "19.88", "DAY", "2011-11-30 10:10:10", "2011-10-23 10:10:10", false}, 382 {"2011-11-11 10:10:10", "prefix19suffix", "DAY", "2011-11-30 10:10:10", "2011-10-23 10:10:10", false}, 383 {"2011-11-11 10:10:10", "20-11", "DAY", "2011-12-01 10:10:10", "2011-10-22 10:10:10", false}, 384 {"2011-11-11 10:10:10", "20,11", "daY", "2011-12-01 10:10:10", "2011-10-22 10:10:10", false}, 385 {"2011-11-11 10:10:10", "1000", "dAy", "2014-08-07 10:10:10", "2009-02-14 10:10:10", false}, 386 {"2011-11-11 10:10:10", "true", "Day", "2011-11-12 10:10:10", "2011-11-10 10:10:10", false}, 387 {"2011-11-11 10:10:10", true, "Day", "2011-11-12 10:10:10", "2011-11-10 10:10:10", false}, 388 // test for different return data types 389 {"2011-11-11", 1, "DAY", "2011-11-12", "2011-11-10", false}, 390 {"2011-11-11", 10, "HOUR", "2011-11-11 10:00:00", "2011-11-10 14:00:00", false}, 391 {"2011-11-11", 10, "MINUTE", "2011-11-11 00:10:00", "2011-11-10 23:50:00", false}, 392 {"2011-11-11", 10, "SECOND", "2011-11-11 00:00:10", "2011-11-10 23:59:50", false}, 393 {"2011-11-11", "10:10", "HOUR_MINUTE", "2011-11-11 10:10:00", "2011-11-10 13:50:00", false}, 394 {"2011-11-11", "10:10:10", "HOUR_SECOND", "2011-11-11 10:10:10", "2011-11-10 13:49:50", false}, 395 {"2011-11-11", "10:10:10.101010", "HOUR_MICROSECOND", "2011-11-11 10:10:10.101010", "2011-11-10 13:49:49.898990", false}, 396 {"2011-11-11", "10:10", "MINUTE_SECOND", "2011-11-11 00:10:10", "2011-11-10 23:49:50", false}, 397 {"2011-11-11", "10:10.101010", "MINUTE_MICROSECOND", "2011-11-11 00:10:10.101010", "2011-11-10 23:49:49.898990", false}, 398 {"2011-11-11", "10.101010", "SECOND_MICROSECOND", "2011-11-11 00:00:10.101010", "2011-11-10 23:59:49.898990", false}, 399 {"2011-11-11 00:00:00", 1, "DAY", "2011-11-12 00:00:00", "2011-11-10 00:00:00", false}, 400 {"2011-11-11 00:00:00", 10, "HOUR", "2011-11-11 10:00:00", "2011-11-10 14:00:00", false}, 401 {"2011-11-11 00:00:00", 10, "MINUTE", "2011-11-11 00:10:00", "2011-11-10 23:50:00", false}, 402 {"2011-11-11 00:00:00", 10, "SECOND", "2011-11-11 00:00:10", "2011-11-10 23:59:50", false}, 403 // tests for invalid input 404 {"2011-11-11", "abc1000", "MICROSECOND", nil, nil, true}, 405 {"20111111 10:10:10", "1", "DAY", nil, nil, true}, 406 {"2011-11-11", "10", "SECOND_MICROSECOND", nil, nil, true}, 407 {"2011-11-11", "10.0000", "MINUTE_MICROSECOND", nil, nil, true}, 408 {"2011-11-11", "10:10:10", "MINUTE_MICROSECOND", nil, nil, true}, 409 } 410 411 // run the test cases 412 for _, t := range tests { 413 op := ast.NewValueExpr(ast.DateAdd) 414 dateArithInterval := ast.NewValueExpr( 415 ast.DateArithInterval{ 416 Unit: t.Unit, 417 Interval: ast.NewValueExpr(t.Interval), 418 }, 419 ) 420 date := ast.NewValueExpr(t.Date) 421 expr := &ast.FuncCallExpr{ 422 FnName: model.NewCIStr("DATE_ARITH"), 423 Args: []ast.ExprNode{ 424 op, 425 date, 426 dateArithInterval, 427 }, 428 } 429 ast.SetFlag(expr) 430 v, err := Eval(ctx, expr) 431 if t.error == true { 432 c.Assert(err, NotNil) 433 } else { 434 c.Assert(err, IsNil) 435 if v.Kind() == types.KindNull { 436 c.Assert(nil, Equals, t.AddResult) 437 } else { 438 c.Assert(v.Kind(), Equals, types.KindMysqlTime) 439 value := v.GetMysqlTime() 440 c.Assert(value.String(), Equals, t.AddResult) 441 } 442 } 443 444 op = ast.NewValueExpr(ast.DateSub) 445 expr.Args[0] = op 446 v, err = Eval(ctx, expr) 447 if t.error == true { 448 c.Assert(err, NotNil) 449 } else { 450 c.Assert(err, IsNil) 451 if v.Kind() == types.KindNull { 452 c.Assert(nil, Equals, t.AddResult) 453 } else { 454 c.Assert(v.Kind(), Equals, types.KindMysqlTime) 455 value := v.GetMysqlTime() 456 c.Assert(value.String(), Equals, t.SubResult) 457 } 458 } 459 } 460 }