github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/time.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 "strings" 20 "time" 21 22 "gopkg.in/src-d/go-errors.v1" 23 24 gmstime "github.com/dolthub/go-mysql-server/internal/time" 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 // ErrTimeUnexpectedlyNil is thrown when a function encounters and unexpectedly nil time 31 var ErrTimeUnexpectedlyNil = errors.NewKind("time in function '%s' unexpectedly nil") 32 33 // ErrUnknownType is thrown when a function encounters and unknown type 34 var ErrUnknownType = errors.NewKind("function '%s' encountered unknown type %T") 35 36 var ErrTooHighPrecision = errors.NewKind("Too-big precision %d for '%s'. Maximum is %d.") 37 38 func getDate(ctx *sql.Context, 39 u expression.UnaryExpression, 40 row sql.Row) (interface{}, error) { 41 42 val, err := u.Child.Eval(ctx, row) 43 if err != nil { 44 return nil, err 45 } 46 47 if val == nil { 48 return nil, nil 49 } 50 51 date, err := types.DatetimeMaxPrecision.ConvertWithoutRangeCheck(val) 52 if err != nil { 53 ctx.Warn(1292, "Incorrect datetime value: '%s'", val) 54 return nil, nil 55 //date = types.DatetimeMaxPrecision.Zero().(time.Time) 56 } 57 58 return date, nil 59 } 60 61 func getDatePart(ctx *sql.Context, 62 u expression.UnaryExpression, 63 row sql.Row, 64 f func(interface{}) interface{}) (interface{}, error) { 65 66 date, err := getDate(ctx, u, row) 67 if err != nil { 68 return nil, err 69 } 70 71 return f(date), nil 72 } 73 74 // Year is a function that returns the year of a date. 75 type Year struct { 76 expression.UnaryExpression 77 } 78 79 var _ sql.FunctionExpression = (*Year)(nil) 80 var _ sql.CollationCoercible = (*Year)(nil) 81 82 // NewYear creates a new Year UDF. 83 func NewYear(date sql.Expression) sql.Expression { 84 return &Year{expression.UnaryExpression{Child: date}} 85 } 86 87 // FunctionName implements sql.FunctionExpression 88 func (y *Year) FunctionName() string { 89 return "year" 90 } 91 92 // Description implements sql.FunctionExpression 93 func (y *Year) Description() string { 94 return "returns the year of the given date." 95 } 96 97 func (y *Year) String() string { return fmt.Sprintf("%s(%s)", y.FunctionName(), y.Child) } 98 99 // Type implements the Expression interface. 100 func (y *Year) Type() sql.Type { return types.Int32 } 101 102 // CollationCoercibility implements the interface sql.CollationCoercible. 103 func (*Year) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 104 return sql.Collation_binary, 5 105 } 106 107 // Eval implements the Expression interface. 108 func (y *Year) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 109 return getDatePart(ctx, y.UnaryExpression, row, year) 110 } 111 112 // WithChildren implements the Expression interface. 113 func (y *Year) WithChildren(children ...sql.Expression) (sql.Expression, error) { 114 if len(children) != 1 { 115 return nil, sql.ErrInvalidChildrenNumber.New(y, len(children), 1) 116 } 117 return NewYear(children[0]), nil 118 } 119 120 type Quarter struct { 121 expression.UnaryExpression 122 } 123 124 var _ sql.FunctionExpression = (*Quarter)(nil) 125 var _ sql.CollationCoercible = (*Quarter)(nil) 126 127 // NewQuarter creates a new Month UDF. 128 func NewQuarter(date sql.Expression) sql.Expression { 129 return &Quarter{expression.UnaryExpression{Child: date}} 130 } 131 132 // FunctionName implements sql.FunctionExpression 133 func (q *Quarter) FunctionName() string { 134 return "quarter" 135 } 136 137 // Description implements sql.FunctionExpression 138 func (q *Quarter) Description() string { 139 return "returns the quarter of the given date." 140 } 141 142 func (q *Quarter) String() string { return fmt.Sprintf("%s(%s)", q.FunctionName(), q.Child) } 143 144 // Type implements the Expression interface. 145 func (q *Quarter) Type() sql.Type { return types.Int32 } 146 147 // CollationCoercibility implements the interface sql.CollationCoercible. 148 func (q *Quarter) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 149 return sql.Collation_binary, 5 150 } 151 152 // Eval implements the Expression interface. 153 func (q *Quarter) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 154 mon, err := getDatePart(ctx, q.UnaryExpression, row, month) 155 if err != nil { 156 return nil, err 157 } 158 159 if mon == nil { 160 return nil, nil 161 } 162 163 return (mon.(int32)-1)/3 + 1, nil 164 } 165 166 // WithChildren implements the Expression interface. 167 func (q *Quarter) WithChildren(children ...sql.Expression) (sql.Expression, error) { 168 if len(children) != 1 { 169 return nil, sql.ErrInvalidChildrenNumber.New(q, len(children), 1) 170 } 171 return NewQuarter(children[0]), nil 172 } 173 174 // Month is a function that returns the month of a date. 175 type Month struct { 176 expression.UnaryExpression 177 } 178 179 var _ sql.FunctionExpression = (*Month)(nil) 180 var _ sql.CollationCoercible = (*Month)(nil) 181 182 // NewMonth creates a new Month UDF. 183 func NewMonth(date sql.Expression) sql.Expression { 184 return &Month{expression.UnaryExpression{Child: date}} 185 } 186 187 // FunctionName implements sql.FunctionExpression 188 func (m *Month) FunctionName() string { 189 return "month" 190 } 191 192 // Description implements sql.FunctionExpression 193 func (m *Month) Description() string { 194 return "returns the month of the given date." 195 } 196 197 func (m *Month) String() string { return fmt.Sprintf("%s(%s)", m.FunctionName(), m.Child) } 198 199 // Type implements the Expression interface. 200 func (m *Month) Type() sql.Type { return types.Int32 } 201 202 // CollationCoercibility implements the interface sql.CollationCoercible. 203 func (*Month) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 204 return sql.Collation_binary, 5 205 } 206 207 // Eval implements the Expression interface. 208 func (m *Month) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 209 return getDatePart(ctx, m.UnaryExpression, row, month) 210 } 211 212 // WithChildren implements the Expression interface. 213 func (m *Month) WithChildren(children ...sql.Expression) (sql.Expression, error) { 214 if len(children) != 1 { 215 return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1) 216 } 217 return NewMonth(children[0]), nil 218 } 219 220 // Day is a function that returns the day of a date. 221 type Day struct { 222 expression.UnaryExpression 223 } 224 225 var _ sql.FunctionExpression = (*Day)(nil) 226 var _ sql.CollationCoercible = (*Day)(nil) 227 228 // NewDay creates a new Day UDF. 229 func NewDay(date sql.Expression) sql.Expression { 230 return &Day{expression.UnaryExpression{Child: date}} 231 } 232 233 // FunctionName implements sql.FunctionExpression 234 func (d *Day) FunctionName() string { 235 return "day" 236 } 237 238 // Description implements sql.FunctionExpression 239 func (d *Day) Description() string { 240 return "returns the day of the month (0-31)." 241 } 242 243 func (d *Day) String() string { return fmt.Sprintf("%s(%s)", d.FunctionName(), d.Child) } 244 245 // Type implements the Expression interface. 246 func (d *Day) Type() sql.Type { return types.Int32 } 247 248 // CollationCoercibility implements the interface sql.CollationCoercible. 249 func (*Day) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 250 return sql.Collation_binary, 5 251 } 252 253 // Eval implements the Expression interface. 254 func (d *Day) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 255 return getDatePart(ctx, d.UnaryExpression, row, day) 256 } 257 258 // WithChildren implements the Expression interface. 259 func (d *Day) WithChildren(children ...sql.Expression) (sql.Expression, error) { 260 if len(children) != 1 { 261 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 262 } 263 return NewDay(children[0]), nil 264 } 265 266 // Weekday is a function that returns the weekday of a date where 0 = Monday, 267 // ..., 6 = Sunday. 268 type Weekday struct { 269 expression.UnaryExpression 270 } 271 272 var _ sql.FunctionExpression = (*Weekday)(nil) 273 var _ sql.CollationCoercible = (*Weekday)(nil) 274 275 // NewWeekday creates a new Weekday UDF. 276 func NewWeekday(date sql.Expression) sql.Expression { 277 return &Weekday{expression.UnaryExpression{Child: date}} 278 } 279 280 // FunctionName implements sql.FunctionExpression 281 func (d *Weekday) FunctionName() string { 282 return "weekday" 283 } 284 285 // Description implements sql.FunctionExpression 286 func (d *Weekday) Description() string { 287 return "returns the weekday of the given date." 288 } 289 290 func (d *Weekday) String() string { return fmt.Sprintf("%s(%s)", d.FunctionName(), d.Child) } 291 292 // Type implements the Expression interface. 293 func (d *Weekday) Type() sql.Type { return types.Int32 } 294 295 // CollationCoercibility implements the interface sql.CollationCoercible. 296 func (*Weekday) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 297 return sql.Collation_binary, 5 298 } 299 300 // Eval implements the Expression interface. 301 func (d *Weekday) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 302 return getDatePart(ctx, d.UnaryExpression, row, weekday) 303 } 304 305 // WithChildren implements the Expression interface. 306 func (d *Weekday) WithChildren(children ...sql.Expression) (sql.Expression, error) { 307 if len(children) != 1 { 308 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 309 } 310 return NewWeekday(children[0]), nil 311 } 312 313 // Hour is a function that returns the hour of a date. 314 type Hour struct { 315 expression.UnaryExpression 316 } 317 318 var _ sql.FunctionExpression = (*Hour)(nil) 319 var _ sql.CollationCoercible = (*Hour)(nil) 320 321 // NewHour creates a new Hour UDF. 322 func NewHour(date sql.Expression) sql.Expression { 323 return &Hour{expression.UnaryExpression{Child: date}} 324 } 325 326 // FunctionName implements sql.FunctionExpression 327 func (h *Hour) FunctionName() string { 328 return "hour" 329 } 330 331 // Description implements sql.FunctionExpression 332 func (h *Hour) Description() string { 333 return "returns the hours of the given date." 334 } 335 336 func (h *Hour) String() string { return fmt.Sprintf("%s(%s)", h.FunctionName(), h.Child) } 337 338 // Type implements the Expression interface. 339 func (h *Hour) Type() sql.Type { return types.Int32 } 340 341 // CollationCoercibility implements the interface sql.CollationCoercible. 342 func (*Hour) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 343 return sql.Collation_binary, 5 344 } 345 346 // Eval implements the Expression interface. 347 func (h *Hour) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 348 return getDatePart(ctx, h.UnaryExpression, row, hour) 349 } 350 351 // WithChildren implements the Expression interface. 352 func (h *Hour) WithChildren(children ...sql.Expression) (sql.Expression, error) { 353 if len(children) != 1 { 354 return nil, sql.ErrInvalidChildrenNumber.New(h, len(children), 1) 355 } 356 return NewHour(children[0]), nil 357 } 358 359 // Minute is a function that returns the minute of a date. 360 type Minute struct { 361 expression.UnaryExpression 362 } 363 364 var _ sql.FunctionExpression = (*Minute)(nil) 365 var _ sql.CollationCoercible = (*Minute)(nil) 366 367 // NewMinute creates a new Minute UDF. 368 func NewMinute(date sql.Expression) sql.Expression { 369 return &Minute{expression.UnaryExpression{Child: date}} 370 } 371 372 // FunctionName implements sql.FunctionExpression 373 func (m *Minute) FunctionName() string { 374 return "minute" 375 } 376 377 // Description implements sql.FunctionExpression 378 func (m *Minute) Description() string { 379 return "returns the minutes of the given date." 380 } 381 382 func (m *Minute) String() string { return fmt.Sprintf("%s(%d)", m.FunctionName(), m.Child) } 383 384 // Type implements the Expression interface. 385 func (m *Minute) Type() sql.Type { return types.Int32 } 386 387 // CollationCoercibility implements the interface sql.CollationCoercible. 388 func (*Minute) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 389 return sql.Collation_binary, 5 390 } 391 392 // Eval implements the Expression interface. 393 func (m *Minute) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 394 return getDatePart(ctx, m.UnaryExpression, row, minute) 395 } 396 397 // WithChildren implements the Expression interface. 398 func (m *Minute) WithChildren(children ...sql.Expression) (sql.Expression, error) { 399 if len(children) != 1 { 400 return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1) 401 } 402 return NewMinute(children[0]), nil 403 } 404 405 // Second is a function that returns the second of a date. 406 type Second struct { 407 expression.UnaryExpression 408 } 409 410 var _ sql.FunctionExpression = (*Second)(nil) 411 var _ sql.CollationCoercible = (*Second)(nil) 412 413 // NewSecond creates a new Second UDF. 414 func NewSecond(date sql.Expression) sql.Expression { 415 return &Second{expression.UnaryExpression{Child: date}} 416 } 417 418 // FunctionName implements sql.FunctionExpression 419 func (s *Second) FunctionName() string { 420 return "second" 421 } 422 423 // Description implements sql.FunctionExpression 424 func (s *Second) Description() string { 425 return "returns the seconds of the given date." 426 } 427 428 func (s *Second) String() string { return fmt.Sprintf("%s(%s)", s.FunctionName(), s.Child) } 429 430 // Type implements the Expression interface. 431 func (s *Second) Type() sql.Type { return types.Int32 } 432 433 // CollationCoercibility implements the interface sql.CollationCoercible. 434 func (*Second) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 435 return sql.Collation_binary, 5 436 } 437 438 // Eval implements the Expression interface. 439 func (s *Second) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 440 return getDatePart(ctx, s.UnaryExpression, row, second) 441 } 442 443 // WithChildren implements the Expression interface. 444 func (s *Second) WithChildren(children ...sql.Expression) (sql.Expression, error) { 445 if len(children) != 1 { 446 return nil, sql.ErrInvalidChildrenNumber.New(s, len(children), 1) 447 } 448 return NewSecond(children[0]), nil 449 } 450 451 // DayOfWeek is a function that returns the day of the week from a date where 452 // 1 = Sunday, ..., 7 = Saturday. 453 type DayOfWeek struct { 454 expression.UnaryExpression 455 } 456 457 var _ sql.FunctionExpression = (*DayOfWeek)(nil) 458 var _ sql.CollationCoercible = (*DayOfWeek)(nil) 459 460 // NewDayOfWeek creates a new DayOfWeek UDF. 461 func NewDayOfWeek(date sql.Expression) sql.Expression { 462 return &DayOfWeek{expression.UnaryExpression{Child: date}} 463 } 464 465 // FunctionName implements sql.FunctionExpression 466 func (d *DayOfWeek) FunctionName() string { 467 return "dayofweek" 468 } 469 470 // Description implements sql.FunctionExpression 471 func (d *DayOfWeek) Description() string { 472 return "returns the day of the week of the given date." 473 } 474 475 func (d *DayOfWeek) String() string { return fmt.Sprintf("DAYOFWEEK(%s)", d.Child) } 476 477 // Type implements the Expression interface. 478 func (d *DayOfWeek) Type() sql.Type { return types.Int32 } 479 480 // CollationCoercibility implements the interface sql.CollationCoercible. 481 func (*DayOfWeek) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 482 return sql.Collation_binary, 5 483 } 484 485 // Eval implements the Expression interface. 486 func (d *DayOfWeek) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 487 return getDatePart(ctx, d.UnaryExpression, row, dayOfWeek) 488 } 489 490 // WithChildren implements the Expression interface. 491 func (d *DayOfWeek) WithChildren(children ...sql.Expression) (sql.Expression, error) { 492 if len(children) != 1 { 493 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 494 } 495 return NewDayOfWeek(children[0]), nil 496 } 497 498 // DayOfYear is a function that returns the day of the year from a date. 499 type DayOfYear struct { 500 expression.UnaryExpression 501 } 502 503 var _ sql.FunctionExpression = (*DayOfYear)(nil) 504 var _ sql.CollationCoercible = (*DayOfYear)(nil) 505 506 // NewDayOfYear creates a new DayOfYear UDF. 507 func NewDayOfYear(date sql.Expression) sql.Expression { 508 return &DayOfYear{expression.UnaryExpression{Child: date}} 509 } 510 511 // FunctionName implements sql.FunctionExpression 512 func (d *DayOfYear) FunctionName() string { 513 return "dayofyear" 514 } 515 516 // Description implements sql.FunctionExpression 517 func (d *DayOfYear) Description() string { 518 return "returns the day of the year of the given date." 519 } 520 521 func (d *DayOfYear) String() string { return fmt.Sprintf("DAYOFYEAR(%s)", d.Child) } 522 523 // Type implements the Expression interface. 524 func (d *DayOfYear) Type() sql.Type { return types.Int32 } 525 526 // CollationCoercibility implements the interface sql.CollationCoercible. 527 func (*DayOfYear) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 528 return sql.Collation_binary, 5 529 } 530 531 // Eval implements the Expression interface. 532 func (d *DayOfYear) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 533 return getDatePart(ctx, d.UnaryExpression, row, dayOfYear) 534 } 535 536 // WithChildren implements the Expression interface. 537 func (d *DayOfYear) WithChildren(children ...sql.Expression) (sql.Expression, error) { 538 if len(children) != 1 { 539 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 540 } 541 return NewDayOfYear(children[0]), nil 542 } 543 544 func datePartFunc(fn func(time.Time) int) func(interface{}) interface{} { 545 return func(v interface{}) interface{} { 546 if v == nil { 547 return nil 548 } 549 550 return int32(fn(v.(time.Time))) 551 } 552 } 553 554 // YearWeek is a function that returns year and week for a date. 555 // The year in the result may be different from the year in the date argument for the first and the last week of the year. 556 // Details: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_yearweek 557 type YearWeek struct { 558 date sql.Expression 559 mode sql.Expression 560 } 561 562 var _ sql.FunctionExpression = (*YearWeek)(nil) 563 var _ sql.CollationCoercible = (*YearWeek)(nil) 564 565 // NewYearWeek creates a new YearWeek UDF 566 func NewYearWeek(args ...sql.Expression) (sql.Expression, error) { 567 if len(args) == 0 { 568 return nil, sql.ErrInvalidArgumentNumber.New("YEARWEEK", "1 or more", 0) 569 } 570 571 yw := &YearWeek{date: args[0]} 572 if len(args) > 1 && args[1].Resolved() && types.IsInteger(args[1].Type()) { 573 yw.mode = args[1] 574 } else if len(args) > 1 && expression.IsBindVar(args[1]) { 575 yw.mode = args[1] 576 } else { 577 yw.mode = expression.NewLiteral(0, types.Int64) 578 } 579 580 return yw, nil 581 } 582 583 // FunctionName implements sql.FunctionExpression 584 func (d *YearWeek) FunctionName() string { 585 return "yearweek" 586 } 587 588 // Description implements sql.FunctionExpression 589 func (d *YearWeek) Description() string { 590 return "returns year and week for a date. The year in the result may be different from the year in the date argument for the first and the last week of the year." 591 } 592 593 func (d *YearWeek) String() string { return fmt.Sprintf("YEARWEEK(%s, %d)", d.date, d.mode) } 594 595 // Type implements the Expression interface. 596 func (d *YearWeek) Type() sql.Type { return types.Int32 } 597 598 // CollationCoercibility implements the interface sql.CollationCoercible. 599 func (*YearWeek) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 600 return sql.Collation_binary, 5 601 } 602 603 // Eval implements the Expression interface. 604 func (d *YearWeek) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 605 date, err := getDate(ctx, expression.UnaryExpression{Child: d.date}, row) 606 if err != nil { 607 return nil, err 608 } 609 if date == nil { 610 return nil, nil 611 } 612 yyyy, ok := year(date).(int32) 613 if !ok { 614 return nil, sql.ErrInvalidArgumentDetails.New("YEARWEEK", "invalid year") 615 } 616 mm, ok := month(date).(int32) 617 if !ok { 618 return nil, sql.ErrInvalidArgumentDetails.New("YEARWEEK", "invalid month") 619 } 620 dd, ok := day(date).(int32) 621 if !ok { 622 return nil, sql.ErrInvalidArgumentDetails.New("YEARWEEK", "invalid day") 623 } 624 625 mode := int64(0) 626 val, err := d.mode.Eval(ctx, row) 627 if err != nil { 628 return nil, err 629 } 630 if val != nil { 631 if i64, _, err := types.Int64.Convert(val); err == nil { 632 if mode, ok = i64.(int64); ok { 633 mode %= 8 // mode in [0, 7] 634 } 635 } 636 } 637 yyyy, week := calcWeek(yyyy, mm, dd, weekMode(mode)|weekBehaviourYear) 638 639 return (yyyy * 100) + week, nil 640 } 641 642 // Resolved implements the Expression interface. 643 func (d *YearWeek) Resolved() bool { 644 return d.date.Resolved() && d.mode.Resolved() 645 } 646 647 // Children implements the Expression interface. 648 func (d *YearWeek) Children() []sql.Expression { return []sql.Expression{d.date, d.mode} } 649 650 // IsNullable implements the Expression interface. 651 func (d *YearWeek) IsNullable() bool { 652 return d.date.IsNullable() 653 } 654 655 // WithChildren implements the Expression interface. 656 func (*YearWeek) WithChildren(children ...sql.Expression) (sql.Expression, error) { 657 return NewYearWeek(children...) 658 } 659 660 // Week is a function that returns year and week for a date. 661 // The year in the result may be different from the year in the date argument for the first and the last week of the year. 662 // Details: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_yearweek 663 type Week struct { 664 date sql.Expression 665 mode sql.Expression 666 } 667 668 var _ sql.FunctionExpression = (*Week)(nil) 669 var _ sql.CollationCoercible = (*Week)(nil) 670 671 // NewWeek creates a new Week UDF 672 func NewWeek(args ...sql.Expression) (sql.Expression, error) { 673 if len(args) == 0 { 674 return nil, sql.ErrInvalidArgumentNumber.New("YEARWEEK", "1 or more", 0) 675 } 676 677 w := &Week{date: args[0]} 678 if len(args) > 1 && args[1].Resolved() && types.IsInteger(args[1].Type()) { 679 w.mode = args[1] 680 } else { 681 w.mode = expression.NewLiteral(0, types.Int64) 682 } 683 684 return w, nil 685 } 686 687 // FunctionName implements sql.FunctionExpression 688 func (d *Week) FunctionName() string { 689 return "week" 690 } 691 692 // Description implements sql.FunctionExpression 693 func (d *Week) Description() string { 694 return "returns the week number." 695 } 696 697 func (d *Week) String() string { return fmt.Sprintf("WEEK(%s, %d)", d.date, d.mode) } 698 699 // Type implements the Expression interface. 700 func (d *Week) Type() sql.Type { return types.Int32 } 701 702 // CollationCoercibility implements the interface sql.CollationCoercible. 703 func (*Week) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 704 return sql.Collation_binary, 5 705 } 706 707 // Eval implements the Expression interface. 708 func (d *Week) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 709 date, err := getDate(ctx, expression.UnaryExpression{Child: d.date}, row) 710 if err != nil { 711 return nil, err 712 } 713 714 yyyy, ok := year(date).(int32) 715 if !ok { 716 return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid year") 717 } 718 mm, ok := month(date).(int32) 719 if !ok { 720 return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid month") 721 } 722 dd, ok := day(date).(int32) 723 if !ok { 724 return nil, sql.ErrInvalidArgumentDetails.New("WEEK", "invalid day") 725 } 726 727 mode := int64(0) 728 val, err := d.mode.Eval(ctx, row) 729 if err != nil { 730 return nil, err 731 } 732 if val != nil { 733 if i64, _, err := types.Int64.Convert(val); err == nil { 734 if mode, ok = i64.(int64); ok { 735 mode %= 8 // mode in [0, 7] 736 } 737 } 738 } 739 740 yearForWeek, week := calcWeek(yyyy, mm, dd, weekMode(mode)|weekBehaviourYear) 741 742 if yearForWeek < yyyy { 743 week = 0 744 } else if yearForWeek > yyyy { 745 week = 53 746 } 747 748 return week, nil 749 } 750 751 // Resolved implements the Expression interface. 752 func (d *Week) Resolved() bool { 753 return d.date.Resolved() && d.mode.Resolved() 754 } 755 756 // Children implements the Expression interface. 757 func (d *Week) Children() []sql.Expression { return []sql.Expression{d.date, d.mode} } 758 759 // IsNullable implements the Expression interface. 760 func (d *Week) IsNullable() bool { 761 return d.date.IsNullable() 762 } 763 764 // WithChildren implements the Expression interface. 765 func (*Week) WithChildren(children ...sql.Expression) (sql.Expression, error) { 766 return NewWeek(children...) 767 } 768 769 // Following solution of YearWeek was taken from tidb: https://github.com/pingcap/tidb/blob/master/types/mytime.go 770 type weekBehaviour int64 771 772 const ( 773 // weekBehaviourMondayFirst set Monday as first day of week; otherwise Sunday is first day of week 774 weekBehaviourMondayFirst weekBehaviour = 1 << iota 775 // If set, Week is in range 1-53, otherwise Week is in range 0-53. 776 // Note that this flag is only relevant if WEEK_JANUARY is not set. 777 weekBehaviourYear 778 // If not set, Weeks are numbered according to ISO 8601:1988. 779 // If set, the week that contains the first 'first-day-of-week' is week 1. 780 weekBehaviourFirstWeekday 781 ) 782 783 func (v weekBehaviour) test(flag weekBehaviour) bool { 784 return (v & flag) != 0 785 } 786 787 func weekMode(mode int64) weekBehaviour { 788 weekFormat := weekBehaviour(mode & 7) 789 if (weekFormat & weekBehaviourMondayFirst) == 0 { 790 weekFormat ^= weekBehaviourFirstWeekday 791 } 792 return weekFormat 793 } 794 795 // calcWeekday calculates weekday from daynr, returns 0 for Monday, 1 for Tuesday ... 796 func calcWeekday(daynr int32, sundayFirstDayOfWeek bool) int32 { 797 daynr += 5 798 if sundayFirstDayOfWeek { 799 daynr++ 800 } 801 return daynr % 7 802 } 803 804 // calcWeek calculates week and year for the time. 805 func calcWeek(yyyy, mm, dd int32, wb weekBehaviour) (int32, int32) { 806 daynr := calcDaynr(yyyy, mm, dd) 807 firstDaynr := calcDaynr(yyyy, 1, 1) 808 mondayFirst := wb.test(weekBehaviourMondayFirst) 809 weekYear := wb.test(weekBehaviourYear) 810 firstWeekday := wb.test(weekBehaviourFirstWeekday) 811 weekday := calcWeekday(firstDaynr, !mondayFirst) 812 813 week, days := int32(0), int32(0) 814 if mm == 1 && dd <= 7-weekday { 815 if !weekYear && 816 ((firstWeekday && weekday != 0) || (!firstWeekday && weekday >= 4)) { 817 return yyyy, week 818 } 819 weekYear = true 820 yyyy-- 821 days = calcDaysInYear(yyyy) 822 firstDaynr -= days 823 weekday = (weekday + 53*7 - days) % 7 824 } 825 826 if (firstWeekday && weekday != 0) || 827 (!firstWeekday && weekday >= 4) { 828 days = daynr - (firstDaynr + 7 - weekday) 829 } else { 830 days = daynr - (firstDaynr - weekday) 831 } 832 833 if weekYear && days >= 52*7 { 834 weekday = (weekday + calcDaysInYear(yyyy)) % 7 835 if (!firstWeekday && weekday < 4) || 836 (firstWeekday && weekday == 0) { 837 yyyy++ 838 week = 1 839 return yyyy, week 840 } 841 } 842 week = days/7 + 1 843 return yyyy, week 844 } 845 846 // calcDaysInYear calculates days in one year, it works with 0 <= yyyy <= 99. 847 func calcDaysInYear(yyyy int32) int32 { 848 if (yyyy&3) == 0 && (yyyy%100 != 0 || (yyyy%400 == 0 && (yyyy != 0))) { 849 return 366 850 } 851 return 365 852 } 853 854 // calcDaynr calculates days since 0000-00-00. 855 func calcDaynr(yyyy, mm, dd int32) int32 { 856 if yyyy == 0 && mm == 0 { 857 return 0 858 } 859 860 delsum := 365*yyyy + 31*(mm-1) + dd 861 if mm <= 2 { 862 yyyy-- 863 } else { 864 delsum -= (mm*4 + 23) / 10 865 } 866 return delsum + yyyy/4 - ((yyyy/100+1)*3)/4 867 } 868 869 var ( 870 year = datePartFunc((time.Time).Year) 871 month = datePartFunc(func(t time.Time) int { return int(t.Month()) }) 872 day = datePartFunc((time.Time).Day) 873 weekday = datePartFunc(func(t time.Time) int { return (int(t.Weekday()) + 6) % 7 }) 874 hour = datePartFunc((time.Time).Hour) 875 minute = datePartFunc((time.Time).Minute) 876 second = datePartFunc((time.Time).Second) 877 dayOfWeek = datePartFunc(func(t time.Time) int { return int(t.Weekday()) + 1 }) 878 dayOfYear = datePartFunc((time.Time).YearDay) 879 ) 880 881 const maxCurrTimestampPrecision = 6 882 883 // Now is a function that returns the current time. 884 type Now struct { 885 // prec stores the requested precision for fractional seconds. 886 prec sql.Expression 887 // alwaysUseExactTime controls whether the NOW() function gets the current time, or 888 // uses a cached value that records the starting time of the query. By default, a 889 // cached time is used, but in some cases (such as the SYSDATE() function), the func 890 // needs to always return the exact current time of each function invocation(). 891 alwaysUseExactTime bool 892 } 893 894 func (n *Now) IsNonDeterministic() bool { 895 return true 896 } 897 898 var _ sql.FunctionExpression = (*Now)(nil) 899 var _ sql.CollationCoercible = (*Now)(nil) 900 901 // NewNow returns a new Now node. 902 func NewNow(args ...sql.Expression) (sql.Expression, error) { 903 n := &Now{} 904 // parser should make it impossible to pass in more than one argument 905 if len(args) > 0 { 906 n.prec = args[0] 907 } 908 return n, nil 909 } 910 911 func subSecondPrecision(t time.Time, precision int) string { 912 if precision == 0 { 913 return "" 914 } 915 916 s := fmt.Sprintf(".%09d", t.Nanosecond()) 917 return s[:precision+1] 918 } 919 920 func fractionOfSecString(t time.Time) string { 921 s := fmt.Sprintf("%09d", t.Nanosecond()) 922 s = s[:6] 923 924 for i := len(s) - 1; i >= 0; i-- { 925 if s[i] != '0' { 926 break 927 } 928 929 s = s[:i] 930 } 931 932 if len(s) == 0 { 933 return "" 934 } 935 936 return "." + s 937 } 938 939 // FunctionName implements sql.FunctionExpression 940 func (n *Now) FunctionName() string { 941 return "now" 942 } 943 944 // Description implements sql.FunctionExpression 945 func (n *Now) Description() string { 946 return "returns the current timestamp." 947 } 948 949 // Type implements the sql.Expression interface. 950 func (n *Now) Type() sql.Type { 951 // TODO: precision 952 if n.prec == nil { 953 return types.Datetime 954 } 955 return types.DatetimeMaxPrecision 956 } 957 958 // CollationCoercibility implements the interface sql.CollationCoercible. 959 func (*Now) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 960 return sql.Collation_binary, 5 961 } 962 963 // String implements the sql.Expression interface. 964 func (n *Now) String() string { 965 if n.prec == nil { 966 return "NOW()" 967 } 968 969 return fmt.Sprintf("NOW(%s)", n.prec.String()) 970 } 971 972 // IsNullable implements the sql.Expression interface. 973 func (n *Now) IsNullable() bool { return false } 974 975 // Resolved implements the sql.Expression interface. 976 func (n *Now) Resolved() bool { 977 if n.prec == nil { 978 return true 979 } 980 return n.prec.Resolved() 981 } 982 983 // Children implements the sql.Expression interface. 984 func (n *Now) Children() []sql.Expression { 985 if n.prec == nil { 986 return nil 987 } 988 return []sql.Expression{n.prec} 989 } 990 991 // Eval implements the sql.Expression interface. 992 func (n *Now) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 993 // Cannot evaluate with nil context 994 if ctx == nil { 995 return nil, fmt.Errorf("cannot Eval Now with nil context") 996 } 997 998 // The timestamp must be in the session time zone 999 sessionTimeZone, err := SessionTimeZone(ctx) 1000 if err != nil { 1001 return nil, err 1002 } 1003 1004 // For NOW(), we use the cached QueryTime, so that all NOW() calls in a query return the same value. 1005 // SYSDATE() requires that we use the *exact* current time, and not use the cached version. 1006 currentTime := ctx.QueryTime() 1007 if n.alwaysUseExactTime { 1008 currentTime = sql.Now() 1009 } 1010 1011 // If no arguments, just return with 0 precision 1012 // The way the parser is implemented 0 should always be passed in; have this here just in case 1013 if n.prec == nil { 1014 t, ok := gmstime.ConvertTimeZone(currentTime, gmstime.SystemTimezoneOffset(), sessionTimeZone) 1015 if !ok { 1016 return nil, fmt.Errorf("invalid time zone: %s", sessionTimeZone) 1017 } 1018 tt := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), 0, time.UTC) 1019 return tt, nil 1020 } 1021 1022 // Should syntax error before this; check anyway 1023 if types.IsNull(n.prec) { 1024 return nil, ErrTimeUnexpectedlyNil.New(n.FunctionName()) 1025 } 1026 1027 // Evaluate precision 1028 prec, err := n.prec.Eval(ctx, row) 1029 if err != nil { 1030 return nil, err 1031 } 1032 1033 // Should syntax error before this; check anyway 1034 if prec == nil { 1035 return nil, ErrTimeUnexpectedlyNil.New(n.FunctionName()) 1036 } 1037 1038 // Must receive integer 1039 // Should syntax error before this; check anyway 1040 fsp, ok := types.CoalesceInt(prec) 1041 if !ok { 1042 return nil, sql.ErrInvalidArgumentType.New(n.FunctionName()) 1043 } 1044 1045 // Parse and return answer 1046 if fsp > maxCurrTimestampPrecision { 1047 return nil, ErrTooHighPrecision.New(fsp, n.FunctionName(), maxCurrTimestampPrecision) 1048 } else if fsp < 0 { 1049 // Should syntax error before this; check anyway 1050 return nil, sql.ErrInvalidArgumentType.New(n.FunctionName()) 1051 } 1052 1053 // Get the timestamp 1054 t, ok := gmstime.ConvertTimeZone(currentTime, gmstime.SystemTimezoneOffset(), sessionTimeZone) 1055 if !ok { 1056 return nil, fmt.Errorf("invalid time zone: %s", sessionTimeZone) 1057 } 1058 1059 // Calculate precision 1060 precision := 1 1061 for i := 0; i < 9-fsp; i++ { 1062 precision *= 10 1063 } 1064 1065 // Round down nano based on precision 1066 nano := precision * (t.Nanosecond() / precision) 1067 1068 // Generate a new timestamp 1069 tt := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), nano, time.UTC) 1070 1071 return tt, nil 1072 } 1073 1074 // WithChildren implements the Expression interface. 1075 func (n *Now) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1076 return NewNow(children...) 1077 } 1078 1079 // NewSysdate returns a new SYSDATE() function, using the supplied |args| for an 1080 // optional value for fractional second precision. The SYSDATE() function is a synonym 1081 // for NOW(), but does NOT use the query's cached start time, and instead always returns 1082 // the current time, even when executed multiple times in a query or stored procedure. 1083 // https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_sysdate 1084 func NewSysdate(args ...sql.Expression) (sql.Expression, error) { 1085 n, err := NewNow(args...) 1086 n.(*Now).alwaysUseExactTime = true 1087 return n, err 1088 } 1089 1090 // SessionTimeZone returns a MySQL timezone offset string for the value of @@session_time_zone. If the session 1091 // timezone is set to SYSTEM, then the system timezone offset is calculated and returned. 1092 func SessionTimeZone(ctx *sql.Context) (string, error) { 1093 sessionTimeZoneVar, err := ctx.GetSessionVariable(ctx, "time_zone") 1094 if err != nil { 1095 return "", err 1096 } 1097 1098 sessionTimeZone, ok := sessionTimeZoneVar.(string) 1099 if !ok { 1100 return "", fmt.Errorf("invalid type for @@session.time_zone: %T", sessionTimeZoneVar) 1101 } 1102 1103 if sessionTimeZone == "SYSTEM" { 1104 sessionTimeZone = gmstime.SystemTimezoneOffset() 1105 } 1106 return sessionTimeZone, nil 1107 } 1108 1109 // UTCTimestamp is a function that returns the current time. 1110 type UTCTimestamp struct { 1111 precision *int 1112 } 1113 1114 var _ sql.FunctionExpression = (*UTCTimestamp)(nil) 1115 var _ sql.CollationCoercible = (*UTCTimestamp)(nil) 1116 1117 // NewUTCTimestamp returns a new UTCTimestamp node. 1118 func NewUTCTimestamp(args ...sql.Expression) (sql.Expression, error) { 1119 var precision *int 1120 if len(args) > 1 { 1121 return nil, sql.ErrInvalidArgumentNumber.New("UTC_TIMESTAMP", 1, len(args)) 1122 } else if len(args) == 1 { 1123 argType := args[0].Type().Promote() 1124 if argType != types.Int64 && argType != types.Uint64 { 1125 return nil, sql.ErrInvalidType.New(args[0].Type().String()) 1126 } 1127 // todo: making a context here is expensive 1128 val, err := args[0].Eval(sql.NewEmptyContext(), nil) 1129 if err != nil { 1130 return nil, err 1131 } 1132 precisionArg, _, err := types.Int32.Convert(val) 1133 1134 if err != nil { 1135 return nil, err 1136 } 1137 1138 n := int(precisionArg.(int32)) 1139 if n < 0 || n > 6 { 1140 return nil, sql.ErrValueOutOfRange.New("precision", "utc_timestamp") 1141 } 1142 precision = &n 1143 } 1144 1145 return &UTCTimestamp{precision}, nil 1146 } 1147 1148 // FunctionName implements sql.FunctionExpression 1149 func (ut *UTCTimestamp) FunctionName() string { 1150 return "utc_timestamp" 1151 } 1152 1153 // Description implements sql.FunctionExpression 1154 func (ut *UTCTimestamp) Description() string { 1155 return "returns the current UTC timestamp." 1156 } 1157 1158 // Type implements the sql.Expression interface. 1159 func (ut *UTCTimestamp) Type() sql.Type { 1160 return types.DatetimeMaxPrecision 1161 } 1162 1163 // CollationCoercibility implements the interface sql.CollationCoercible. 1164 func (*UTCTimestamp) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1165 return sql.Collation_binary, 5 1166 } 1167 1168 func (ut *UTCTimestamp) String() string { 1169 if ut.precision == nil { 1170 return "UTC_TIMESTAMP()" 1171 } 1172 1173 return fmt.Sprintf("UTC_TIMESTAMP(%d)", *ut.precision) 1174 } 1175 1176 // IsNullable implements the sql.Expression interface. 1177 func (ut *UTCTimestamp) IsNullable() bool { return false } 1178 1179 // Resolved implements the sql.Expression interface. 1180 func (ut *UTCTimestamp) Resolved() bool { return true } 1181 1182 // Children implements the sql.Expression interface. 1183 func (ut *UTCTimestamp) Children() []sql.Expression { return nil } 1184 1185 // Eval implements the sql.Expression interface. 1186 func (ut *UTCTimestamp) Eval(ctx *sql.Context, _ sql.Row) (interface{}, error) { 1187 t := ctx.QueryTime() 1188 // TODO: UTC Timestamp needs to also handle precision arguments 1189 nano := 1000 * (t.Nanosecond() / 1000) 1190 tt := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), nano, t.Location()) 1191 return tt.UTC(), nil 1192 } 1193 1194 // WithChildren implements the Expression interface. 1195 func (ut *UTCTimestamp) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1196 return NewUTCTimestamp(children...) 1197 } 1198 1199 // Date a function takes the DATE part out from a datetime expression. 1200 type Date struct { 1201 expression.UnaryExpression 1202 } 1203 1204 var _ sql.FunctionExpression = (*Date)(nil) 1205 var _ sql.CollationCoercible = (*Date)(nil) 1206 1207 // FunctionName implements sql.FunctionExpression 1208 func (d *Date) FunctionName() string { 1209 return "date" 1210 } 1211 1212 // Description implements sql.FunctionExpression 1213 func (d *Date) Description() string { 1214 return "returns the date part of the given date." 1215 } 1216 1217 // NewDate returns a new Date node. 1218 func NewDate(date sql.Expression) sql.Expression { 1219 return &Date{expression.UnaryExpression{Child: date}} 1220 } 1221 1222 func (d *Date) String() string { return fmt.Sprintf("DATE(%s)", d.Child) } 1223 1224 // Type implements the Expression interface. 1225 func (d *Date) Type() sql.Type { return types.Date } 1226 1227 // CollationCoercibility implements the interface sql.CollationCoercible. 1228 func (*Date) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1229 return sql.Collation_binary, 5 1230 } 1231 1232 // Eval implements the Expression interface. 1233 func (d *Date) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1234 return getDatePart(ctx, d.UnaryExpression, row, func(v interface{}) interface{} { 1235 if v == nil { 1236 return nil 1237 } 1238 1239 return v.(time.Time).Format("2006-01-02") 1240 }) 1241 } 1242 1243 // WithChildren implements the Expression interface. 1244 func (d *Date) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1245 if len(children) != 1 { 1246 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 1247 } 1248 return NewDate(children[0]), nil 1249 } 1250 1251 // UnaryDatetimeFunc is a sql.Function which takes a single datetime argument 1252 type UnaryDatetimeFunc struct { 1253 expression.UnaryExpression 1254 // Name is the name of the function 1255 Name string 1256 // SQLType is the return type of the function 1257 SQLType sql.Type 1258 } 1259 1260 func NewUnaryDatetimeFunc(arg sql.Expression, name string, sqlType sql.Type) *UnaryDatetimeFunc { 1261 return &UnaryDatetimeFunc{expression.UnaryExpression{Child: arg}, name, sqlType} 1262 } 1263 1264 // FunctionName implements sql.FunctionExpression 1265 func (dtf *UnaryDatetimeFunc) FunctionName() string { 1266 return dtf.Name 1267 } 1268 1269 func (dtf *UnaryDatetimeFunc) EvalChild(ctx *sql.Context, row sql.Row) (interface{}, error) { 1270 val, err := dtf.Child.Eval(ctx, row) 1271 1272 if err != nil { 1273 return nil, err 1274 } 1275 1276 if val == nil { 1277 return nil, nil 1278 } 1279 1280 ret, _, err := types.DatetimeMaxPrecision.Convert(val) 1281 return ret, err 1282 } 1283 1284 // String implements the fmt.Stringer interface. 1285 func (dtf *UnaryDatetimeFunc) String() string { 1286 return fmt.Sprintf("%s(%s)", strings.ToUpper(dtf.Name), dtf.Child.String()) 1287 } 1288 1289 // Type implements the Expression interface. 1290 func (dtf *UnaryDatetimeFunc) Type() sql.Type { 1291 return dtf.SQLType 1292 } 1293 1294 // DayName implements the DAYNAME function 1295 type DayName struct { 1296 *UnaryFunc 1297 } 1298 1299 var _ sql.FunctionExpression = (*DayName)(nil) 1300 1301 func NewDayName(arg sql.Expression) sql.Expression { 1302 return &DayName{NewUnaryFunc(arg, "DAYNAME", types.Text)} 1303 } 1304 1305 // FunctionName implements sql.FunctionExpression 1306 func (d *DayName) FunctionName() string { 1307 return "dayname" 1308 } 1309 1310 // Description implements sql.FunctionExpression 1311 func (d *DayName) Description() string { 1312 return "returns the name of the weekday." 1313 } 1314 1315 // CollationCoercibility implements the interface sql.CollationCoercible. 1316 func (*DayName) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1317 return ctx.GetCollation(), 4 1318 } 1319 1320 func (d *DayName) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1321 val, err := d.EvalChild(ctx, row) 1322 if err != nil { 1323 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1324 return nil, nil 1325 } 1326 1327 if s, ok := val.(string); ok { 1328 val, _, err = types.DatetimeMaxPrecision.Convert(s) 1329 if err != nil { 1330 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1331 return nil, nil 1332 } 1333 } 1334 1335 t, ok := val.(time.Time) 1336 if !ok { 1337 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1338 return nil, nil 1339 } 1340 1341 return t.Weekday().String(), nil 1342 } 1343 1344 func (d *DayName) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1345 if len(children) != 1 { 1346 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 1347 } 1348 return NewDayName(children[0]), nil 1349 } 1350 1351 // Microsecond implements the MICROSECOND function 1352 type Microsecond struct { 1353 *UnaryDatetimeFunc 1354 } 1355 1356 var _ sql.FunctionExpression = (*Microsecond)(nil) 1357 var _ sql.CollationCoercible = (*Microsecond)(nil) 1358 1359 // Description implements sql.FunctionExpression 1360 func (m *Microsecond) Description() string { 1361 return "returns the microseconds from argument." 1362 } 1363 1364 // CollationCoercibility implements the interface sql.CollationCoercible. 1365 func (*Microsecond) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1366 return sql.Collation_binary, 5 1367 } 1368 1369 func NewMicrosecond(arg sql.Expression) sql.Expression { 1370 return &Microsecond{NewUnaryDatetimeFunc(arg, "MICROSECOND", types.Uint64)} 1371 } 1372 1373 func (m *Microsecond) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1374 val, err := m.EvalChild(ctx, row) 1375 if err != nil { 1376 return nil, err 1377 } 1378 1379 switch v := val.(type) { 1380 case time.Time: 1381 return uint64(v.Nanosecond()) / uint64(time.Microsecond), nil 1382 case nil: 1383 return nil, nil 1384 default: 1385 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1386 return nil, nil 1387 } 1388 } 1389 1390 func (m *Microsecond) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1391 if len(children) != 1 { 1392 return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1) 1393 } 1394 return NewMicrosecond(children[0]), nil 1395 } 1396 1397 // MonthName implements the MONTHNAME function 1398 type MonthName struct { 1399 *UnaryDatetimeFunc 1400 } 1401 1402 var _ sql.FunctionExpression = (*MonthName)(nil) 1403 var _ sql.CollationCoercible = (*MonthName)(nil) 1404 1405 func NewMonthName(arg sql.Expression) sql.Expression { 1406 return &MonthName{NewUnaryDatetimeFunc(arg, "MONTHNAME", types.Text)} 1407 } 1408 1409 // Description implements sql.FunctionExpression 1410 func (d *MonthName) Description() string { 1411 return "returns the name of the month." 1412 } 1413 1414 // CollationCoercibility implements the interface sql.CollationCoercible. 1415 func (*MonthName) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1416 return ctx.GetCollation(), 4 1417 } 1418 1419 func (d *MonthName) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1420 val, err := d.EvalChild(ctx, row) 1421 if err != nil { 1422 return nil, err 1423 } 1424 1425 switch v := val.(type) { 1426 case time.Time: 1427 return v.Month().String(), nil 1428 case nil: 1429 return nil, nil 1430 default: 1431 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1432 return nil, nil 1433 } 1434 } 1435 1436 func (d *MonthName) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1437 if len(children) != 1 { 1438 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 1439 } 1440 return NewMonthName(children[0]), nil 1441 } 1442 1443 // TimeToSec implements the time_to_sec function 1444 type TimeToSec struct { 1445 *UnaryDatetimeFunc 1446 } 1447 1448 var _ sql.FunctionExpression = (*TimeToSec)(nil) 1449 var _ sql.CollationCoercible = (*TimeToSec)(nil) 1450 1451 func NewTimeToSec(arg sql.Expression) sql.Expression { 1452 return &TimeToSec{NewUnaryDatetimeFunc(arg, "TIME_TO_SEC", types.Uint64)} 1453 } 1454 1455 // Description implements sql.FunctionExpression 1456 func (m *TimeToSec) Description() string { 1457 return "returns the argument converted to seconds." 1458 } 1459 1460 // CollationCoercibility implements the interface sql.CollationCoercible. 1461 func (*TimeToSec) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1462 return sql.Collation_binary, 5 1463 } 1464 1465 func (m *TimeToSec) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1466 val, err := m.EvalChild(ctx, row) 1467 if err != nil { 1468 return nil, err 1469 } 1470 1471 switch v := val.(type) { 1472 case time.Time: 1473 return uint64(v.Hour()*3600 + v.Minute()*60 + v.Second()), nil 1474 case nil: 1475 return nil, nil 1476 default: 1477 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1478 return nil, nil 1479 } 1480 } 1481 1482 func (m *TimeToSec) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1483 if len(children) != 1 { 1484 return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1) 1485 } 1486 return NewTimeToSec(children[0]), nil 1487 } 1488 1489 // WeekOfYear implements the weekofyear function 1490 type WeekOfYear struct { 1491 *UnaryDatetimeFunc 1492 } 1493 1494 var _ sql.FunctionExpression = (*WeekOfYear)(nil) 1495 var _ sql.CollationCoercible = (*WeekOfYear)(nil) 1496 1497 func NewWeekOfYear(arg sql.Expression) sql.Expression { 1498 return &WeekOfYear{NewUnaryDatetimeFunc(arg, "WEEKOFYEAR", types.Uint64)} 1499 } 1500 1501 // Description implements sql.FunctionExpression 1502 func (m *WeekOfYear) Description() string { 1503 return "returns the calendar week of the date (1-53)." 1504 } 1505 1506 // CollationCoercibility implements the interface sql.CollationCoercible. 1507 func (*WeekOfYear) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1508 return sql.Collation_binary, 5 1509 } 1510 1511 func (m *WeekOfYear) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1512 val, err := m.EvalChild(ctx, row) 1513 if err != nil { 1514 return nil, err 1515 } 1516 1517 switch v := val.(type) { 1518 case time.Time: 1519 _, wk := v.ISOWeek() 1520 return wk, nil 1521 case nil: 1522 return nil, nil 1523 default: 1524 ctx.Warn(1292, types.ErrConvertingToTime.New(val).Error()) 1525 return nil, nil 1526 } 1527 } 1528 1529 func (m *WeekOfYear) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1530 if len(children) != 1 { 1531 return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1) 1532 } 1533 return NewWeekOfYear(children[0]), nil 1534 } 1535 1536 type CurrTime struct { 1537 prec sql.Expression 1538 } 1539 1540 func (c CurrTime) IsNonDeterministic() bool { 1541 return true 1542 } 1543 1544 var _ sql.FunctionExpression = (*CurrTime)(nil) 1545 var _ sql.CollationCoercible = (*CurrTime)(nil) 1546 1547 func NewCurrTime(args ...sql.Expression) (sql.Expression, error) { 1548 c := &CurrTime{} 1549 // parser should make it impossible to pass in more than one argument 1550 if len(args) > 0 { 1551 c.prec = args[0] 1552 } 1553 return c, nil 1554 } 1555 1556 // FunctionName implements sql.FunctionExpression 1557 func (c *CurrTime) FunctionName() string { 1558 return "current_time" 1559 } 1560 1561 // Description implements sql.FunctionExpression 1562 func (c *CurrTime) Description() string { 1563 return "returns the current time." 1564 } 1565 1566 // Type implements the sql.Expression interface. 1567 func (c *CurrTime) Type() sql.Type { 1568 return types.Time 1569 } 1570 1571 // CollationCoercibility implements the interface sql.CollationCoercible. 1572 func (*CurrTime) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1573 return sql.Collation_binary, 5 1574 } 1575 1576 // String implements the sql.Expression interface. 1577 func (c *CurrTime) String() string { 1578 if c.prec == nil { 1579 return "CURRENT_TIME()" 1580 } 1581 1582 return fmt.Sprintf("CURRENT_TIME(%s)", c.prec.String()) 1583 } 1584 1585 // IsNullable implements the sql.Expression interface. 1586 func (c *CurrTime) IsNullable() bool { return false } 1587 1588 // Resolved implements the sql.Expression interface. 1589 func (c *CurrTime) Resolved() bool { 1590 if c.prec == nil { 1591 return true 1592 } 1593 return c.prec.Resolved() 1594 } 1595 1596 // Children implements the sql.Expression interface. 1597 func (c *CurrTime) Children() []sql.Expression { 1598 if c.prec == nil { 1599 return nil 1600 } 1601 return []sql.Expression{c.prec} 1602 } 1603 1604 // Eval implements sql.Expression 1605 func (c *CurrTime) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1606 newNow, err := NewNow(c.prec) 1607 if err != nil { 1608 return nil, err 1609 } 1610 1611 result, err := newNow.Eval(ctx, row) 1612 if err != nil { 1613 return nil, err 1614 } 1615 1616 if t, ok := result.(time.Time); ok { 1617 // TODO: this is wrong, we need to include nanoseconds 1618 return fmt.Sprintf("%02d:%02d:%02d", t.Hour(), t.Minute(), t.Second()), nil 1619 } else { 1620 return nil, fmt.Errorf("unexpected type %T for NOW() result", result) 1621 } 1622 } 1623 1624 // WithChildren implements sql.Expression 1625 func (c *CurrTime) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1626 return NoArgFuncWithChildren(c, children) 1627 } 1628 1629 // Time is a function takes the Time part out from a datetime expression. 1630 type Time struct { 1631 expression.UnaryExpression 1632 } 1633 1634 var _ sql.FunctionExpression = (*Time)(nil) 1635 var _ sql.CollationCoercible = (*Time)(nil) 1636 1637 // NewTime returns a new Date node. 1638 func NewTime(time sql.Expression) sql.Expression { 1639 return &Time{expression.UnaryExpression{Child: time}} 1640 } 1641 1642 func (t *Time) FunctionName() string { 1643 return "time" 1644 } 1645 1646 func (t *Time) Description() string { 1647 return "extracts the time part of a time or datetime expression and returns it as a string" 1648 } 1649 1650 func (t *Time) String() string { 1651 return fmt.Sprintf("TIME(%s)", t.Child) 1652 } 1653 1654 // Type implements the Expression interface. 1655 func (t *Time) Type() sql.Type { 1656 return types.Time 1657 } 1658 1659 // CollationCoercibility implements the interface sql.CollationCoercible. 1660 func (*Time) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 1661 return sql.Collation_binary, 5 1662 } 1663 1664 // Eval implements the Expression interface. 1665 func (t *Time) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 1666 v, err := t.UnaryExpression.Child.Eval(ctx, row) 1667 if err != nil { 1668 return nil, err 1669 } 1670 if v == nil { 1671 return nil, nil 1672 } 1673 1674 // convert to date 1675 date, err := types.DatetimeMaxPrecision.ConvertWithoutRangeCheck(v) 1676 if err == nil { 1677 h, m, s := date.Clock() 1678 us := date.Nanosecond() / 1000 1679 return types.Timespan(1000000*(3600*h+60*m+s) + us), nil 1680 } 1681 1682 // convert to time 1683 val, _, err := types.Time.Convert(v) 1684 if err != nil { 1685 ctx.Warn(1292, err.Error()) 1686 return nil, nil 1687 } 1688 return val, nil 1689 } 1690 1691 // WithChildren implements the Expression interface. 1692 func (t *Time) WithChildren(children ...sql.Expression) (sql.Expression, error) { 1693 if len(children) != 1 { 1694 return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), 1) 1695 } 1696 return NewTime(children[0]), nil 1697 }