github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/time_test.go (about) 1 // Copyright 2020-2021 Dolthub, 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "fmt" 19 "testing" 20 "time" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 25 "github.com/dolthub/go-mysql-server/sql" 26 "github.com/dolthub/go-mysql-server/sql/expression" 27 "github.com/dolthub/go-mysql-server/sql/types" 28 ) 29 30 const ( 31 tsDate = 1258882545 // Sunday, November 22, 2009 10:35:45 PM GMT+01:00 32 stringDate = "2007-01-02 14:15:16" 33 ) 34 35 // TODO: look over all of the "invalid type" tests later, ignoring them for now since they're unlikely to be hit 36 func TestTime_Year(t *testing.T) { 37 ctx := sql.NewEmptyContext() 38 f := NewYear(expression.NewGetField(0, types.LongText, "foo", false)) 39 40 testCases := []struct { 41 name string 42 row sql.Row 43 expected interface{} 44 err bool 45 }{ 46 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 47 {"date as string", sql.NewRow(stringDate), int32(2007), false}, 48 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Year()), false}, 49 } 50 51 for _, tt := range testCases { 52 t.Run(tt.name, func(t *testing.T) { 53 require := require.New(t) 54 val, err := f.Eval(ctx, tt.row) 55 if tt.err { 56 require.Error(err) 57 } else { 58 require.NoError(err) 59 require.Equal(tt.expected, val) 60 } 61 }) 62 } 63 } 64 65 func TestTime_Month(t *testing.T) { 66 ctx := sql.NewEmptyContext() 67 f := NewMonth(expression.NewGetField(0, types.LongText, "foo", false)) 68 69 testCases := []struct { 70 name string 71 row sql.Row 72 expected interface{} 73 err bool 74 }{ 75 {"null date", sql.NewRow(nil), nil, false}, 76 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 77 {"date as string", sql.NewRow(stringDate), int32(1), false}, 78 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Month()), false}, 79 } 80 81 for _, tt := range testCases { 82 t.Run(tt.name, func(t *testing.T) { 83 require := require.New(t) 84 val, err := f.Eval(ctx, tt.row) 85 if tt.err { 86 require.Error(err) 87 } else { 88 require.NoError(err) 89 require.Equal(tt.expected, val) 90 } 91 }) 92 } 93 } 94 95 func TestTime_Quarter(t *testing.T) { 96 ctx := sql.NewEmptyContext() 97 f := NewQuarter(expression.NewGetField(0, types.LongText, "foo", false)) 98 99 testCases := []struct { 100 name string 101 row sql.Row 102 expected interface{} 103 err bool 104 }{ 105 { 106 name: "null date", 107 row: sql.NewRow(nil), 108 expected: nil, 109 }, 110 { 111 name: "1", 112 row: sql.NewRow(1), 113 expected: nil, 114 }, 115 { 116 name: "1.1", 117 row: sql.NewRow(1.1), 118 expected: nil, 119 }, 120 { 121 name: "invalid type", 122 row: sql.NewRow([]byte{0, 1, 2}), 123 expected: nil, 124 }, 125 { 126 name: "date as string", 127 row: sql.NewRow(stringDate), 128 expected: int32(1), 129 }, 130 { 131 name: "another date as string", 132 row: sql.NewRow("2008-08-01"), 133 expected: int32(3), 134 }, 135 { 136 name: "january", 137 row: sql.NewRow("2008-01-01"), 138 expected: int32(1), 139 }, 140 { 141 name: "february", 142 row: sql.NewRow("2008-02-01"), 143 expected: int32(1), 144 }, 145 { 146 name: "march", 147 row: sql.NewRow("2008-03-01"), 148 expected: int32(1), 149 }, 150 { 151 name: "april", 152 row: sql.NewRow("2008-04-01"), 153 expected: int32(2), 154 }, 155 { 156 name: "may", 157 row: sql.NewRow("2008-05-01"), 158 expected: int32(2), 159 }, 160 { 161 name: "june", 162 row: sql.NewRow("2008-06-01"), 163 expected: int32(2), 164 }, 165 { 166 name: "july", 167 row: sql.NewRow("2008-07-01"), 168 expected: int32(3), 169 }, 170 { 171 name: "august", 172 row: sql.NewRow("2008-08-01"), 173 expected: int32(3), 174 }, 175 { 176 name: "septemeber", 177 row: sql.NewRow("2008-09-01"), 178 expected: int32(3), 179 }, 180 { 181 name: "october", 182 row: sql.NewRow("2008-10-01"), 183 expected: int32(4), 184 }, 185 { 186 name: "november", 187 row: sql.NewRow("2008-11-01"), 188 expected: int32(4), 189 }, 190 { 191 name: "december", 192 row: sql.NewRow("2008-12-01"), 193 expected: int32(4), 194 }, 195 { 196 name: "date as time", 197 row: sql.NewRow(time.Now()), 198 expected: int32((time.Now().UTC().Month()-1)/3 + 1), 199 }, 200 } 201 202 for _, tt := range testCases { 203 t.Run(tt.name, func(t *testing.T) { 204 require := require.New(t) 205 val, err := f.Eval(ctx, tt.row) 206 if tt.err { 207 require.Error(err) 208 } else { 209 require.NoError(err) 210 require.Equal(tt.expected, val) 211 } 212 }) 213 } 214 } 215 216 func TestTime_Day(t *testing.T) { 217 ctx := sql.NewEmptyContext() 218 f := NewDay(expression.NewGetField(0, types.LongText, "foo", false)) 219 220 testCases := []struct { 221 name string 222 row sql.Row 223 expected interface{} 224 err bool 225 }{ 226 {"null date", sql.NewRow(nil), nil, false}, 227 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 228 {"date as string", sql.NewRow(stringDate), int32(2), false}, 229 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Day()), false}, 230 } 231 232 for _, tt := range testCases { 233 t.Run(tt.name, func(t *testing.T) { 234 require := require.New(t) 235 val, err := f.Eval(ctx, tt.row) 236 if tt.err { 237 require.Error(err) 238 } else { 239 require.NoError(err) 240 require.Equal(tt.expected, val) 241 } 242 }) 243 } 244 } 245 246 func TestTime_Weekday(t *testing.T) { 247 ctx := sql.NewEmptyContext() 248 f := NewWeekday(expression.NewGetField(0, types.LongText, "foo", false)) 249 250 testCases := []struct { 251 name string 252 row sql.Row 253 expected interface{} 254 err bool 255 }{ 256 {"null date", sql.NewRow(nil), nil, false}, 257 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 258 {"date as string", sql.NewRow(stringDate), int32(1), false}, 259 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Weekday()+6) % 7, false}, 260 } 261 262 for _, tt := range testCases { 263 t.Run(tt.name, func(t *testing.T) { 264 require := require.New(t) 265 val, err := f.Eval(ctx, tt.row) 266 if tt.err { 267 require.Error(err) 268 } else { 269 require.NoError(err) 270 require.Equal(tt.expected, val) 271 } 272 }) 273 } 274 } 275 276 func TestTime_Hour(t *testing.T) { 277 ctx := sql.NewEmptyContext() 278 f := NewHour(expression.NewGetField(0, types.LongText, "foo", false)) 279 280 testCases := []struct { 281 name string 282 row sql.Row 283 expected interface{} 284 err bool 285 }{ 286 {"null date", sql.NewRow(nil), nil, false}, 287 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 288 {"date as string", sql.NewRow(stringDate), int32(14), false}, 289 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Hour()), false}, 290 } 291 292 for _, tt := range testCases { 293 t.Run(tt.name, func(t *testing.T) { 294 require := require.New(t) 295 val, err := f.Eval(ctx, tt.row) 296 if tt.err { 297 require.Error(err) 298 } else { 299 require.NoError(err) 300 require.Equal(tt.expected, val) 301 } 302 }) 303 } 304 } 305 306 func TestTime_Minute(t *testing.T) { 307 ctx := sql.NewEmptyContext() 308 f := NewMinute(expression.NewGetField(0, types.LongText, "foo", false)) 309 310 testCases := []struct { 311 name string 312 row sql.Row 313 expected interface{} 314 err bool 315 }{ 316 {"null date", sql.NewRow(nil), nil, false}, 317 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 318 {"date as string", sql.NewRow(stringDate), int32(15), false}, 319 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Minute()), false}, 320 } 321 322 for _, tt := range testCases { 323 t.Run(tt.name, func(t *testing.T) { 324 require := require.New(t) 325 val, err := f.Eval(ctx, tt.row) 326 if tt.err { 327 require.Error(err) 328 } else { 329 require.NoError(err) 330 require.Equal(tt.expected, val) 331 } 332 }) 333 } 334 } 335 336 func TestTime_Second(t *testing.T) { 337 ctx := sql.NewEmptyContext() 338 f := NewSecond(expression.NewGetField(0, types.LongText, "foo", false)) 339 340 testCases := []struct { 341 name string 342 row sql.Row 343 expected interface{} 344 err bool 345 }{ 346 {"null date", sql.NewRow(nil), nil, false}, 347 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 348 {"date as string", sql.NewRow(stringDate), int32(16), false}, 349 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Second()), false}, 350 } 351 352 for _, tt := range testCases { 353 t.Run(tt.name, func(t *testing.T) { 354 require := require.New(t) 355 val, err := f.Eval(ctx, tt.row) 356 if tt.err { 357 require.Error(err) 358 } else { 359 require.NoError(err) 360 require.Equal(tt.expected, val) 361 } 362 }) 363 } 364 } 365 366 func TestTime_Microsecond(t *testing.T) { 367 ctx := sql.NewEmptyContext() 368 f := NewMicrosecond(expression.NewGetField(0, types.LongText, "foo", false)) 369 currTime := time.Now() 370 371 testCases := []struct { 372 name string 373 row sql.Row 374 expected interface{} 375 err bool 376 }{ 377 {"null date", sql.NewRow(nil), nil, false}, 378 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, true}, 379 {"date as string", sql.NewRow(stringDate), uint64(0), false}, 380 {"date as time", sql.NewRow(currTime), uint64(currTime.Nanosecond()) / uint64(time.Microsecond), false}, 381 } 382 383 for _, tt := range testCases { 384 t.Run(tt.name, func(t *testing.T) { 385 require := require.New(t) 386 val, err := f.Eval(ctx, tt.row) 387 if tt.err { 388 require.Error(err) 389 } else { 390 require.NoError(err) 391 require.Equal(tt.expected, val) 392 } 393 }) 394 } 395 } 396 397 func TestTime_DayOfWeek(t *testing.T) { 398 ctx := sql.NewEmptyContext() 399 f := NewDayOfWeek(expression.NewGetField(0, types.LongText, "foo", false)) 400 401 testCases := []struct { 402 name string 403 row sql.Row 404 expected interface{} 405 err bool 406 }{ 407 {"null date", sql.NewRow(nil), nil, false}, 408 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 409 {"date as string", sql.NewRow(stringDate), int32(3), false}, 410 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Weekday() + 1), false}, 411 } 412 413 for _, tt := range testCases { 414 t.Run(tt.name, func(t *testing.T) { 415 require := require.New(t) 416 val, err := f.Eval(ctx, tt.row) 417 if tt.err { 418 require.Error(err) 419 } else { 420 require.NoError(err) 421 require.Equal(tt.expected, val) 422 } 423 }) 424 } 425 } 426 427 func TestTime_DayOfYear(t *testing.T) { 428 ctx := sql.NewEmptyContext() 429 f := NewDayOfYear(expression.NewGetField(0, types.LongText, "foo", false)) 430 431 testCases := []struct { 432 name string 433 row sql.Row 434 expected interface{} 435 err bool 436 }{ 437 {"null date", sql.NewRow(nil), nil, false}, 438 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 439 {"date as string", sql.NewRow(stringDate), int32(2), false}, 440 {"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().YearDay()), false}, 441 } 442 443 for _, tt := range testCases { 444 t.Run(tt.name, func(t *testing.T) { 445 require := require.New(t) 446 val, err := f.Eval(ctx, tt.row) 447 if tt.err { 448 require.Error(err) 449 } else { 450 require.NoError(err) 451 require.Equal(tt.expected, val) 452 } 453 }) 454 } 455 } 456 457 func TestTime_WeekOfYear(t *testing.T) { 458 ctx := sql.NewEmptyContext() 459 f := NewWeekOfYear(expression.NewGetField(0, types.LongText, "foo", false)) 460 currTime := time.Now() 461 _, week := currTime.ISOWeek() 462 463 testCases := []struct { 464 name string 465 row sql.Row 466 expected interface{} 467 err bool 468 }{ 469 {"null date", sql.NewRow(nil), nil, false}, 470 {"invalid type", sql.NewRow([]byte{0, 1, 2}), int32(1), true}, 471 {"date as string", sql.NewRow(stringDate), 1, false}, 472 {"date as time", sql.NewRow(currTime), week, false}, 473 } 474 475 for _, tt := range testCases { 476 t.Run(tt.name, func(t *testing.T) { 477 require := require.New(t) 478 val, err := f.Eval(ctx, tt.row) 479 if tt.err { 480 require.Error(err) 481 } else { 482 require.NoError(err) 483 require.Equal(tt.expected, val) 484 } 485 }) 486 } 487 } 488 489 func TestYearWeek(t *testing.T) { 490 ctx := sql.NewEmptyContext() 491 f, err := NewYearWeek(expression.NewGetField(0, types.LongText, "foo", false)) 492 require.NoError(t, err) 493 494 testCases := []struct { 495 name string 496 row sql.Row 497 expected interface{} 498 err bool 499 }{ 500 {"null date", sql.NewRow(nil), nil, false}, 501 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 502 {"date as string", sql.NewRow(stringDate), int32(200653), false}, 503 } 504 505 for _, tt := range testCases { 506 t.Run(tt.name, func(t *testing.T) { 507 require := require.New(t) 508 val, err := f.Eval(ctx, tt.row) 509 if tt.err { 510 require.Error(err) 511 } else { 512 require.NoError(err) 513 require.Equal(tt.expected, val) 514 } 515 }) 516 } 517 } 518 519 func TestCalcDaynr(t *testing.T) { 520 require.EqualValues(t, calcDaynr(0, 0, 0), 0) 521 require.EqualValues(t, calcDaynr(9999, 12, 31), 3652424) 522 require.EqualValues(t, calcDaynr(1970, 1, 1), 719528) 523 require.EqualValues(t, calcDaynr(2006, 12, 16), 733026) 524 require.EqualValues(t, calcDaynr(10, 1, 2), 3654) 525 require.EqualValues(t, calcDaynr(2008, 2, 20), 733457) 526 } 527 528 func TestCalcWeek(t *testing.T) { 529 _, w := calcWeek(2008, 2, 20, weekMode(0)) 530 531 _, w = calcWeek(2008, 2, 20, weekMode(1)) 532 require.EqualValues(t, w, 8) 533 534 _, w = calcWeek(2008, 12, 31, weekMode(1)) 535 require.EqualValues(t, w, 53) 536 } 537 538 func TestUTCTimestamp(t *testing.T) { 539 date := time.Date(2018, time.December, 2, 16, 25, 0, 0, time.Local) 540 testNowFunc := func() time.Time { 541 return date 542 } 543 544 var ctx *sql.Context 545 err := sql.RunWithNowFunc(testNowFunc, func() error { 546 ctx = sql.NewEmptyContext() 547 return nil 548 }) 549 require.NoError(t, err) 550 551 tests := []struct { 552 args []sql.Expression 553 result time.Time 554 expectErr bool 555 }{ 556 { 557 args: nil, 558 result: date, 559 expectErr: false, 560 }, 561 { 562 args: []sql.Expression{expression.NewLiteral(0, types.Int8)}, 563 result: date, 564 expectErr: false, 565 }, 566 { 567 args: []sql.Expression{expression.NewLiteral(0, types.Int64)}, 568 result: date, 569 expectErr: false, 570 }, 571 { 572 args: []sql.Expression{expression.NewLiteral(6, types.Uint8)}, 573 result: date, 574 expectErr: false, 575 }, 576 { 577 args: []sql.Expression{expression.NewLiteral(7, types.Int8)}, 578 result: time.Time{}, 579 expectErr: true, 580 }, 581 { 582 args: []sql.Expression{expression.NewLiteral(-1, types.Int8)}, 583 result: time.Time{}, 584 expectErr: true, 585 }, 586 { 587 args: []sql.Expression{expression.NewConvert(expression.NewLiteral("2020-10-10 01:02:03", types.Text), expression.ConvertToDatetime)}, 588 result: time.Time{}, 589 expectErr: true, 590 }, 591 } 592 593 for _, test := range tests { 594 t.Run(fmt.Sprint(test.args), func(t *testing.T) { 595 ut, err := NewUTCTimestamp(test.args...) 596 if !test.expectErr { 597 require.NoError(t, err) 598 val, err := ut.Eval(ctx, nil) 599 require.NoError(t, err) 600 assert.Equal(t, test.result.UTC(), val) 601 } else { 602 assert.Error(t, err) 603 } 604 }) 605 } 606 } 607 608 func TestDate(t *testing.T) { 609 ctx := sql.NewEmptyContext() 610 f := NewDate(expression.NewGetField(0, types.LongText, "foo", false)) 611 612 testCases := []struct { 613 name string 614 row sql.Row 615 expected interface{} 616 err bool 617 }{ 618 {"null date", sql.NewRow(nil), nil, false}, 619 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 620 {"date as string", sql.NewRow(stringDate), "2007-01-02", false}, 621 {"date as time", sql.NewRow(time.Now().UTC()), time.Now().UTC().Format("2006-01-02"), false}, 622 } 623 624 for _, tt := range testCases { 625 t.Run(tt.name, func(t *testing.T) { 626 require := require.New(t) 627 val, err := f.Eval(ctx, tt.row) 628 if tt.err { 629 require.Error(err) 630 } else { 631 require.NoError(err) 632 require.Equal(tt.expected, val) 633 } 634 }) 635 } 636 } 637 638 func TestNow(t *testing.T) { 639 f, _ := NewNow(expression.NewGetField(0, types.LongText, "foo", false)) 640 date := time.Date( 641 2021, // year 642 1, // month 643 1, // day 644 8, // hour 645 30, // min 646 15, // sec 647 123456789, // nsec 648 time.UTC, // location (UTC) 649 ) 650 651 testCases := []struct { 652 name string 653 row sql.Row 654 expected interface{} 655 err bool 656 }{ 657 {"null date", sql.NewRow(nil), nil, true}, 658 {"different int type", sql.NewRow(int8(0)), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 0, time.UTC), false}, 659 {"precision of -1", sql.NewRow(-1), nil, true}, 660 {"precision of 0", sql.NewRow(0), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 0, time.UTC), false}, 661 {"precision of 1", sql.NewRow(1), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 100000000, time.UTC), false}, 662 {"precision of 2", sql.NewRow(2), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 120000000, time.UTC), false}, 663 {"precision of 3", sql.NewRow(3), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123000000, time.UTC), false}, 664 {"precision of 4", sql.NewRow(4), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123400000, time.UTC), false}, 665 {"precision of 5", sql.NewRow(5), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123450000, time.UTC), false}, 666 {"precision of 6", sql.NewRow(6), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123456000, time.UTC), false}, 667 {"precision of 7 which is too high", sql.NewRow(7), nil, true}, 668 {"incorrect type", sql.NewRow("notanint"), nil, true}, 669 } 670 671 for _, tt := range testCases { 672 t.Run(tt.name, func(t *testing.T) { 673 sql.RunWithNowFunc(func() time.Time { 674 return date 675 }, func() error { 676 ctx := sql.NewEmptyContext() 677 require := require.New(t) 678 val, err := f.Eval(ctx, tt.row) 679 if tt.err { 680 require.Error(err) 681 } else { 682 require.NoError(err) 683 require.Equal(tt.expected, val) 684 } 685 return nil 686 }) 687 }) 688 } 689 } 690 691 // TestSysdate tests the SYSDATE() function, which should generally behave identically to NOW(), but unlike NOW(), 692 // SYSDATE() should always return the exact current time, and not the cached query start time. That behavior is 693 // tested in the enginetests, instead of these unit tests. 694 func TestSysdate(t *testing.T) { 695 f, _ := NewSysdate(expression.NewGetField(0, types.LongText, "foo", false)) 696 date := time.Date( 697 2021, // year 698 1, // month 699 1, // day 700 8, // hour 701 30, // min 702 15, // sec 703 123456789, // nsec 704 time.UTC, // location (UTC) 705 ) 706 707 testCases := []struct { 708 name string 709 row sql.Row 710 expected interface{} 711 err bool 712 }{ 713 {"null date", sql.NewRow(nil), nil, true}, 714 {"different int type", sql.NewRow(int8(0)), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 0, time.UTC), false}, 715 {"precision of -1", sql.NewRow(-1), nil, true}, 716 {"precision of 0", sql.NewRow(0), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 0, time.UTC), false}, 717 {"precision of 1", sql.NewRow(1), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 100000000, time.UTC), false}, 718 {"precision of 2", sql.NewRow(2), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 120000000, time.UTC), false}, 719 {"precision of 3", sql.NewRow(3), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123000000, time.UTC), false}, 720 {"precision of 4", sql.NewRow(4), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123400000, time.UTC), false}, 721 {"precision of 5", sql.NewRow(5), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123450000, time.UTC), false}, 722 {"precision of 6", sql.NewRow(6), time.Date(date.Year(), date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), 123456000, time.UTC), false}, 723 {"precision of 7 which is too high", sql.NewRow(7), nil, true}, 724 {"incorrect type", sql.NewRow("notanint"), nil, true}, 725 } 726 727 for _, tt := range testCases { 728 t.Run(tt.name, func(t *testing.T) { 729 sql.RunWithNowFunc(func() time.Time { 730 return date 731 }, func() error { 732 ctx := sql.NewEmptyContext() 733 require := require.New(t) 734 val, err := f.Eval(ctx, tt.row) 735 if tt.err { 736 require.Error(err) 737 } else { 738 require.NoError(err) 739 require.Equal(tt.expected, val) 740 } 741 return nil 742 }) 743 }) 744 } 745 } 746 747 func TestTime(t *testing.T) { 748 ctx := sql.NewEmptyContext() 749 f := NewTime(expression.NewGetField(0, types.LongText, "foo", false)) 750 751 testCases := []struct { 752 name string 753 row sql.Row 754 expected interface{} 755 err bool 756 }{ 757 {"null date", sql.NewRow(nil), nil, false}, 758 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 759 {"time as string", sql.NewRow(stringDate), "14:15:16", false}, 760 } 761 762 for _, tt := range testCases { 763 t.Run(tt.name, func(t *testing.T) { 764 require := require.New(t) 765 val, err := f.Eval(ctx, tt.row) 766 if tt.err { 767 require.Error(err) 768 } else { 769 require.NoError(err) 770 if v, ok := val.(types.Timespan); ok { 771 require.Equal(tt.expected, v.String()) 772 } else { 773 require.Equal(tt.expected, val) 774 } 775 } 776 }) 777 } 778 } 779 780 func TestTime_DayName(t *testing.T) { 781 ctx := sql.NewEmptyContext() 782 f := NewDayName(expression.NewGetField(0, types.LongText, "foo", false)) 783 784 testCases := []struct { 785 name string 786 row sql.Row 787 expected interface{} 788 err bool 789 }{ 790 {"null date", sql.NewRow(nil), nil, false}, 791 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false}, 792 {"time as string", sql.NewRow(stringDate), "Tuesday", false}, 793 } 794 795 for _, tt := range testCases { 796 t.Run(tt.name, func(t *testing.T) { 797 require := require.New(t) 798 val, err := f.Eval(ctx, tt.row) 799 if tt.err { 800 require.Error(err) 801 } else { 802 require.NoError(err) 803 if v, ok := val.(types.Timespan); ok { 804 require.Equal(tt.expected, v.String()) 805 } else { 806 require.Equal(tt.expected, val) 807 } 808 } 809 }) 810 } 811 } 812 813 func TestTime_MonthName(t *testing.T) { 814 ctx := sql.NewEmptyContext() 815 f := NewMonthName(expression.NewGetField(0, types.LongText, "foo", false)) 816 817 testCases := []struct { 818 name string 819 row sql.Row 820 expected interface{} 821 err bool 822 }{ 823 {"null date", sql.NewRow(nil), nil, false}, 824 {"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, true}, 825 {"time as string", sql.NewRow(stringDate), "January", false}, 826 } 827 828 for _, tt := range testCases { 829 t.Run(tt.name, func(t *testing.T) { 830 require := require.New(t) 831 val, err := f.Eval(ctx, tt.row) 832 if tt.err { 833 require.Error(err) 834 } else { 835 require.NoError(err) 836 if v, ok := val.(types.Timespan); ok { 837 require.Equal(tt.expected, v.String()) 838 } else { 839 require.Equal(tt.expected, val) 840 } 841 } 842 }) 843 } 844 }