1 #ifndef ITEM_TIMEFUNC_INCLUDED 2 #define ITEM_TIMEFUNC_INCLUDED 3 4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 25 26 27 /* Function items used by mysql */ 28 29 #include <algorithm> 30 31 class MY_LOCALE; 32 33 bool get_interval_value(Item *args,interval_type int_type, 34 String *str_value, INTERVAL *interval); 35 36 class Item_func_period_add :public Item_int_func 37 { 38 public: Item_func_period_add(Item * a,Item * b)39 Item_func_period_add(Item *a,Item *b) :Item_int_func(a,b) {} 40 longlong val_int(); func_name()41 const char *func_name() const { return "period_add"; } fix_length_and_dec()42 void fix_length_and_dec() 43 { 44 fix_char_length(6); /* YYYYMM */ 45 } 46 }; 47 48 49 class Item_func_period_diff :public Item_int_func 50 { 51 public: Item_func_period_diff(Item * a,Item * b)52 Item_func_period_diff(Item *a,Item *b) :Item_int_func(a,b) {} 53 longlong val_int(); func_name()54 const char *func_name() const { return "period_diff"; } fix_length_and_dec()55 void fix_length_and_dec() 56 { 57 fix_char_length(6); /* YYYYMM */ 58 } 59 }; 60 61 62 class Item_func_to_days :public Item_int_func 63 { 64 public: Item_func_to_days(Item * a)65 Item_func_to_days(Item *a) :Item_int_func(a) {} 66 longlong val_int(); func_name()67 const char *func_name() const { return "to_days"; } fix_length_and_dec()68 void fix_length_and_dec() 69 { 70 fix_char_length(6); 71 maybe_null=1; 72 } 73 enum_monotonicity_info get_monotonicity_info() const; 74 longlong val_int_endpoint(bool left_endp, bool *incl_endp); check_partition_func_processor(uchar * int_arg)75 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)76 bool check_valid_arguments_processor(uchar *int_arg) 77 { 78 return !has_date_args(); 79 } 80 }; 81 82 83 class Item_func_to_seconds :public Item_int_func 84 { 85 public: Item_func_to_seconds(Item * a)86 Item_func_to_seconds(Item *a) :Item_int_func(a) {} 87 longlong val_int(); func_name()88 const char *func_name() const { return "to_seconds"; } fix_length_and_dec()89 void fix_length_and_dec() 90 { 91 fix_char_length(6); 92 maybe_null=1; 93 } 94 enum_monotonicity_info get_monotonicity_info() const; 95 longlong val_int_endpoint(bool left_endp, bool *incl_endp); check_partition_func_processor(uchar * bool_arg)96 bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} 97 intro_version(uchar * int_arg)98 bool intro_version(uchar *int_arg) 99 { 100 using std::max; 101 int *input_version= (int*)int_arg; 102 /* This function was introduced in 5.5 */ 103 int output_version= max(*input_version, 50500); 104 *input_version= output_version; 105 return 0; 106 } 107 108 /* Only meaningful with date part and optional time part */ check_valid_arguments_processor(uchar * int_arg)109 bool check_valid_arguments_processor(uchar *int_arg) 110 { 111 return !has_date_args(); 112 } 113 }; 114 115 116 class Item_func_dayofmonth :public Item_int_func 117 { 118 public: Item_func_dayofmonth(Item * a)119 Item_func_dayofmonth(Item *a) :Item_int_func(a) {} 120 longlong val_int(); func_name()121 const char *func_name() const { return "dayofmonth"; } fix_length_and_dec()122 void fix_length_and_dec() 123 { 124 fix_char_length(2); /* 1..31 */ 125 maybe_null=1; 126 } check_partition_func_processor(uchar * int_arg)127 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)128 bool check_valid_arguments_processor(uchar *int_arg) 129 { 130 return !has_date_args(); 131 } 132 }; 133 134 135 /** 136 TS-TODO: This should probably have Item_int_func as parent class. 137 */ 138 class Item_func_month :public Item_func 139 { 140 public: Item_func_month(Item * a)141 Item_func_month(Item *a) :Item_func(a) { collation.set_numeric(); } 142 longlong val_int(); val_real()143 double val_real() 144 { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } val_str(String * str)145 String *val_str(String *str) 146 { 147 longlong nr= val_int(); 148 if (null_value) 149 return 0; 150 str->set(nr, collation.collation); 151 return str; 152 } get_date(MYSQL_TIME * ltime,uint fuzzydate)153 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 154 { 155 return get_date_from_int(ltime, fuzzydate); 156 } get_time(MYSQL_TIME * ltime)157 bool get_time(MYSQL_TIME *ltime) 158 { 159 return get_time_from_int(ltime); 160 } func_name()161 const char *func_name() const { return "month"; } result_type()162 enum Item_result result_type () const { return INT_RESULT; } fix_length_and_dec()163 void fix_length_and_dec() 164 { 165 fix_char_length(2); 166 maybe_null= 1; 167 } check_partition_func_processor(uchar * int_arg)168 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)169 bool check_valid_arguments_processor(uchar *int_arg) 170 { 171 return !has_date_args(); 172 } 173 }; 174 175 176 class Item_func_monthname :public Item_str_func 177 { 178 MY_LOCALE *locale; 179 public: Item_func_monthname(Item * a)180 Item_func_monthname(Item *a) :Item_str_func(a) {} func_name()181 const char *func_name() const { return "monthname"; } 182 String *val_str(String *str); 183 void fix_length_and_dec(); check_partition_func_processor(uchar * int_arg)184 bool check_partition_func_processor(uchar *int_arg) {return TRUE;} check_valid_arguments_processor(uchar * int_arg)185 bool check_valid_arguments_processor(uchar *int_arg) 186 { 187 return !has_date_args(); 188 } 189 }; 190 191 192 class Item_func_dayofyear :public Item_int_func 193 { 194 public: Item_func_dayofyear(Item * a)195 Item_func_dayofyear(Item *a) :Item_int_func(a) {} 196 longlong val_int(); func_name()197 const char *func_name() const { return "dayofyear"; } fix_length_and_dec()198 void fix_length_and_dec() 199 { 200 fix_char_length(3); 201 maybe_null= 1; 202 } check_partition_func_processor(uchar * int_arg)203 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)204 bool check_valid_arguments_processor(uchar *int_arg) 205 { 206 return !has_date_args(); 207 } 208 }; 209 210 211 class Item_func_hour :public Item_int_func 212 { 213 public: Item_func_hour(Item * a)214 Item_func_hour(Item *a) :Item_int_func(a) {} 215 longlong val_int(); func_name()216 const char *func_name() const { return "hour"; } fix_length_and_dec()217 void fix_length_and_dec() 218 { 219 fix_char_length(2); /* 0..23 */ 220 maybe_null=1; 221 } check_partition_func_processor(uchar * int_arg)222 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)223 bool check_valid_arguments_processor(uchar *int_arg) 224 { 225 return !has_time_args(); 226 } 227 }; 228 229 230 class Item_func_minute :public Item_int_func 231 { 232 public: Item_func_minute(Item * a)233 Item_func_minute(Item *a) :Item_int_func(a) {} 234 longlong val_int(); func_name()235 const char *func_name() const { return "minute"; } fix_length_and_dec()236 void fix_length_and_dec() 237 { 238 fix_char_length(2); /* 0..59 */ 239 maybe_null=1; 240 } check_partition_func_processor(uchar * int_arg)241 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)242 bool check_valid_arguments_processor(uchar *int_arg) 243 { 244 return !has_time_args(); 245 } 246 }; 247 248 249 class Item_func_quarter :public Item_int_func 250 { 251 public: Item_func_quarter(Item * a)252 Item_func_quarter(Item *a) :Item_int_func(a) {} 253 longlong val_int(); func_name()254 const char *func_name() const { return "quarter"; } fix_length_and_dec()255 void fix_length_and_dec() 256 { 257 fix_char_length(1); /* 1..4 */ 258 maybe_null=1; 259 } check_partition_func_processor(uchar * int_arg)260 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)261 bool check_valid_arguments_processor(uchar *int_arg) 262 { 263 return !has_date_args(); 264 } 265 }; 266 267 268 class Item_func_second :public Item_int_func 269 { 270 public: Item_func_second(Item * a)271 Item_func_second(Item *a) :Item_int_func(a) {} 272 longlong val_int(); func_name()273 const char *func_name() const { return "second"; } fix_length_and_dec()274 void fix_length_and_dec() 275 { 276 fix_char_length(2); /* 0..59 */ 277 maybe_null=1; 278 } check_partition_func_processor(uchar * int_arg)279 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)280 bool check_valid_arguments_processor(uchar *int_arg) 281 { 282 return !has_time_args(); 283 } 284 }; 285 286 287 class Item_func_week :public Item_int_func 288 { 289 public: Item_func_week(Item * a,Item * b)290 Item_func_week(Item *a,Item *b) :Item_int_func(a,b) {} 291 longlong val_int(); func_name()292 const char *func_name() const { return "week"; } fix_length_and_dec()293 void fix_length_and_dec() 294 { 295 fix_char_length(2); /* 0..54 */ 296 maybe_null=1; 297 } 298 }; 299 300 class Item_func_yearweek :public Item_int_func 301 { 302 public: Item_func_yearweek(Item * a,Item * b)303 Item_func_yearweek(Item *a,Item *b) :Item_int_func(a,b) {} 304 longlong val_int(); func_name()305 const char *func_name() const { return "yearweek"; } fix_length_and_dec()306 void fix_length_and_dec() 307 { 308 fix_char_length(6); /* YYYYWW */ 309 maybe_null=1; 310 } check_partition_func_processor(uchar * int_arg)311 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)312 bool check_valid_arguments_processor(uchar *int_arg) 313 { 314 return !has_date_args(); 315 } 316 }; 317 318 319 class Item_func_year :public Item_int_func 320 { 321 public: Item_func_year(Item * a)322 Item_func_year(Item *a) :Item_int_func(a) {} 323 longlong val_int(); func_name()324 const char *func_name() const { return "year"; } 325 enum_monotonicity_info get_monotonicity_info() const; 326 longlong val_int_endpoint(bool left_endp, bool *incl_endp); fix_length_and_dec()327 void fix_length_and_dec() 328 { 329 fix_char_length(4); /* 9999 */ 330 maybe_null=1; 331 } check_partition_func_processor(uchar * int_arg)332 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)333 bool check_valid_arguments_processor(uchar *int_arg) 334 { 335 return !has_date_args(); 336 } 337 }; 338 339 340 /** 341 TS-TODO: This should probably have Item_int_func as parent class. 342 */ 343 class Item_func_weekday :public Item_func 344 { 345 bool odbc_type; 346 public: Item_func_weekday(Item * a,bool type_arg)347 Item_func_weekday(Item *a,bool type_arg) 348 :Item_func(a), odbc_type(type_arg) { collation.set_numeric(); } 349 longlong val_int(); val_real()350 double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } val_str(String * str)351 String *val_str(String *str) 352 { 353 DBUG_ASSERT(fixed == 1); 354 str->set(val_int(), &my_charset_bin); 355 return null_value ? 0 : str; 356 } get_date(MYSQL_TIME * ltime,uint fuzzydate)357 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 358 { 359 return get_date_from_int(ltime, fuzzydate); 360 } get_time(MYSQL_TIME * ltime)361 bool get_time(MYSQL_TIME *ltime) 362 { 363 return get_time_from_int(ltime); 364 } func_name()365 const char *func_name() const 366 { 367 return (odbc_type ? "dayofweek" : "weekday"); 368 } result_type()369 enum Item_result result_type () const { return INT_RESULT; } fix_length_and_dec()370 void fix_length_and_dec() 371 { 372 fix_char_length(1); 373 maybe_null= 1; 374 } check_partition_func_processor(uchar * int_arg)375 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)376 bool check_valid_arguments_processor(uchar *int_arg) 377 { 378 return !has_date_args(); 379 } 380 }; 381 382 /** 383 TS-TODO: Item_func_dayname should be derived from Item_str_func. 384 In the current implementation funny things can happen: 385 select dayname(now())+1 -> 4 386 */ 387 class Item_func_dayname :public Item_func_weekday 388 { 389 MY_LOCALE *locale; 390 public: Item_func_dayname(Item * a)391 Item_func_dayname(Item *a) :Item_func_weekday(a,0) {} func_name()392 const char *func_name() const { return "dayname"; } 393 String *val_str(String *str); get_date(MYSQL_TIME * ltime,uint fuzzydate)394 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 395 { 396 return get_date_from_string(ltime, fuzzydate); 397 } get_time(MYSQL_TIME * ltime)398 bool get_time(MYSQL_TIME *ltime) 399 { 400 return get_time_from_string(ltime); 401 } result_type()402 enum Item_result result_type () const { return STRING_RESULT; } 403 void fix_length_and_dec(); check_partition_func_processor(uchar * int_arg)404 bool check_partition_func_processor(uchar *int_arg) {return TRUE;} 405 }; 406 407 408 /* 409 Abstract class for functions returning "struct timeval". 410 */ 411 class Item_timeval_func :public Item_func 412 { 413 public: Item_timeval_func()414 Item_timeval_func() :Item_func() { } Item_timeval_func(Item * a)415 Item_timeval_func(Item *a) :Item_func(a) { } 416 /** 417 Return timestamp in "struct timeval" format. 418 @param OUT tm The value is store here. 419 @retval false On success 420 @retval true On error 421 */ 422 virtual bool val_timeval(struct timeval *tm)= 0; 423 longlong val_int(); 424 double val_real(); 425 String *val_str(String *str); 426 my_decimal *val_decimal(my_decimal *decimal_value); get_date(MYSQL_TIME * ltime,uint fuzzydate)427 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 428 { 429 return get_date_from_numeric(ltime, fuzzydate); 430 } get_time(MYSQL_TIME * ltime)431 bool get_time(MYSQL_TIME *ltime) 432 { 433 return get_time_from_numeric(ltime); 434 } result_type()435 enum Item_result result_type() const 436 { 437 return decimals ? DECIMAL_RESULT : INT_RESULT; 438 } 439 }; 440 441 442 class Item_func_unix_timestamp :public Item_timeval_func 443 { 444 public: Item_func_unix_timestamp()445 Item_func_unix_timestamp() :Item_timeval_func() {} Item_func_unix_timestamp(Item * a)446 Item_func_unix_timestamp(Item *a) :Item_timeval_func(a) {} func_name()447 const char *func_name() const { return "unix_timestamp"; } 448 enum_monotonicity_info get_monotonicity_info() const; 449 longlong val_int_endpoint(bool left_endp, bool *incl_endp); check_partition_func_processor(uchar * int_arg)450 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} 451 /* 452 UNIX_TIMESTAMP() depends on the current timezone 453 (and thus may not be used as a partitioning function) 454 when its argument is NOT of the TIMESTAMP type. 455 */ check_valid_arguments_processor(uchar * int_arg)456 bool check_valid_arguments_processor(uchar *int_arg) 457 { 458 return !has_timestamp_args(); 459 } fix_length_and_dec()460 void fix_length_and_dec() 461 { 462 fix_length_and_dec_and_charset_datetime(11, arg_count == 0 ? 0 : 463 args[0]->datetime_precision()); 464 } 465 bool val_timeval(struct timeval *tm); 466 }; 467 468 469 class Item_func_time_to_sec :public Item_int_func 470 { 471 public: Item_func_time_to_sec(Item * item)472 Item_func_time_to_sec(Item *item) :Item_int_func(item) {} 473 longlong val_int(); func_name()474 const char *func_name() const { return "time_to_sec"; } fix_length_and_dec()475 void fix_length_and_dec() 476 { 477 maybe_null= TRUE; 478 fix_char_length(10); 479 } check_partition_func_processor(uchar * int_arg)480 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)481 bool check_valid_arguments_processor(uchar *int_arg) 482 { 483 return !has_time_args(); 484 } 485 }; 486 487 488 /** 489 Abstract class for functions returning TIME, DATE, DATETIME types 490 whose data type is known at constructor time. 491 */ 492 class Item_temporal_func :public Item_func 493 { 494 protected: 495 bool check_precision(); 496 public: Item_temporal_func()497 Item_temporal_func() :Item_func() {} Item_temporal_func(Item * a)498 Item_temporal_func(Item *a) :Item_func(a) {} Item_temporal_func(Item * a,Item * b)499 Item_temporal_func(Item *a, Item *b) :Item_func(a, b) {} Item_temporal_func(Item * a,Item * b,Item * c)500 Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a, b, c) {} result_type()501 enum Item_result result_type () const 502 { 503 return STRING_RESULT; 504 } charset_for_protocol()505 CHARSET_INFO *charset_for_protocol() const 506 { 507 return &my_charset_bin; 508 } tmp_table_field(TABLE * table)509 Field *tmp_table_field(TABLE *table) 510 { 511 return tmp_table_field_from_field_type(table, 0); 512 } time_precision()513 uint time_precision() 514 { 515 DBUG_ASSERT(fixed); 516 return decimals; 517 } datetime_precision()518 uint datetime_precision() 519 { 520 DBUG_ASSERT(fixed); 521 return decimals; 522 } 523 }; 524 525 526 /** 527 Abstract class for functions returning TIME, DATE, DATETIME or string values, 528 whose data type depends on parameters and is set at fix_field time. 529 */ 530 class Item_temporal_hybrid_func :public Item_str_func 531 { 532 protected: 533 sql_mode_t sql_mode; // sql_mode value is cached here in fix_length_and_dec() 534 enum_field_types cached_field_type; // TIME, DATE, DATETIME or STRING 535 String ascii_buf; // Conversion buffer 536 /** 537 Get "native" temporal value as MYSQL_TIME 538 @param OUT ltime The value is stored here. 539 @param IN fuzzy_date Date flags. 540 @retval false On success. 541 @retval true On error. 542 */ 543 virtual bool val_datetime(MYSQL_TIME *ltime, uint fuzzy_date)= 0; 544 545 public: Item_temporal_hybrid_func(Item * a,Item * b)546 Item_temporal_hybrid_func(Item *a, Item *b) :Item_str_func(a, b), 547 sql_mode(0) 548 { } result_type()549 enum Item_result result_type () const { return STRING_RESULT; } field_type()550 enum_field_types field_type() const { return cached_field_type; } charset_for_protocol()551 const CHARSET_INFO *charset_for_protocol() const 552 { 553 /* 554 Can return TIME, DATE, DATETIME or VARCHAR depending on arguments. 555 Send using "binary" when TIME, DATE or DATETIME, 556 or using collation.collation when VARCHAR 557 (which is fixed from @collation_connection in fix_length_and_dec). 558 */ 559 DBUG_ASSERT(fixed == 1); 560 return cached_field_type == MYSQL_TYPE_STRING ? 561 collation.collation : &my_charset_bin; 562 } tmp_table_field(TABLE * table)563 Field *tmp_table_field(TABLE *table) 564 { 565 return tmp_table_field_from_field_type(table, 0); 566 } val_int()567 longlong val_int() { return val_int_from_decimal(); } val_real()568 double val_real() { return val_real_from_decimal(); } 569 my_decimal *val_decimal(my_decimal *decimal_value); 570 type_conversion_status save_in_field(Field *field, bool no_conversions); 571 /** 572 Return string value in ASCII character set. 573 */ 574 String *val_str_ascii(String *str); 575 /** 576 Return string value in @@character_set_connection. 577 */ val_str(String * str)578 String *val_str(String *str) 579 { 580 return val_str_from_val_str_ascii(str, &ascii_buf); 581 } 582 bool get_date(MYSQL_TIME *ltime, uint fuzzydate); 583 bool get_time(MYSQL_TIME *ltime); 584 }; 585 586 587 /* 588 This can't be a Item_str_func, because the val_real() functions are special 589 */ 590 591 /** 592 Abstract class for functions returning DATE values. 593 */ 594 class Item_date_func :public Item_temporal_func 595 { 596 public: Item_date_func()597 Item_date_func() :Item_temporal_func() 598 { } Item_date_func(Item * a)599 Item_date_func(Item *a) :Item_temporal_func(a) 600 { } Item_date_func(Item * a,Item * b)601 Item_date_func(Item *a, Item *b) :Item_temporal_func(a, b) 602 { } field_type()603 enum_field_types field_type() const { return MYSQL_TYPE_DATE; } get_time(MYSQL_TIME * ltime)604 bool get_time(MYSQL_TIME *ltime) 605 { 606 return get_time_from_date(ltime); 607 } val_str(String * str)608 String *val_str(String *str) 609 { 610 return val_string_from_date(str); 611 } val_int()612 longlong val_int() 613 { 614 return val_int_from_date(); 615 } 616 longlong val_date_temporal(); val_real()617 double val_real() { return (double) val_int(); } func_name()618 const char *func_name() const { return "date"; } fix_length_and_dec()619 void fix_length_and_dec() 620 { 621 fix_length_and_dec_and_charset_datetime(MAX_DATE_WIDTH, 0); 622 } val_decimal(my_decimal * decimal_value)623 my_decimal *val_decimal(my_decimal *decimal_value) 624 { 625 DBUG_ASSERT(fixed == 1); 626 return val_decimal_from_date(decimal_value); 627 } save_in_field(Field * field,bool no_conversions)628 type_conversion_status save_in_field(Field *field, bool no_conversions) 629 { 630 return save_date_in_field(field); 631 } 632 // All date functions must implement get_date() 633 // to avoid use of generic Item::get_date() 634 // which converts to string and then parses the string as DATE. 635 virtual bool get_date(MYSQL_TIME *res, uint fuzzy_date)= 0; 636 }; 637 638 639 /** 640 Abstract class for functions returning DATETIME values. 641 */ 642 class Item_datetime_func :public Item_temporal_func 643 { 644 public: Item_datetime_func()645 Item_datetime_func() :Item_temporal_func() 646 { } Item_datetime_func(Item * a)647 Item_datetime_func(Item *a) :Item_temporal_func(a) 648 { } Item_datetime_func(Item * a,Item * b)649 Item_datetime_func(Item *a,Item *b) :Item_temporal_func(a,b) 650 { } Item_datetime_func(Item * a,Item * b,Item * c)651 Item_datetime_func(Item *a,Item *b, Item *c) :Item_temporal_func(a,b,c) 652 { } field_type()653 enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } val_real()654 double val_real() { return val_real_from_decimal(); } val_str(String * str)655 String *val_str(String *str) 656 { 657 return val_string_from_datetime(str); 658 } val_int()659 longlong val_int() 660 { 661 return val_int_from_datetime(); 662 } 663 longlong val_date_temporal(); val_decimal(my_decimal * decimal_value)664 my_decimal *val_decimal(my_decimal *decimal_value) 665 { 666 DBUG_ASSERT(fixed == 1); 667 return val_decimal_from_date(decimal_value); 668 } save_in_field(Field * field,bool no_conversions)669 type_conversion_status save_in_field(Field *field, bool no_conversions) 670 { 671 return save_date_in_field(field); 672 } get_time(MYSQL_TIME * ltime)673 bool get_time(MYSQL_TIME *ltime) 674 { 675 return get_time_from_datetime(ltime); 676 } 677 // All datetime functions must implement get_date() 678 // to avoid use of generic Item::get_date() 679 // which converts to string and then parses the string as DATETIME. 680 virtual bool get_date(MYSQL_TIME *res, uint fuzzy_date)= 0; 681 }; 682 683 684 /** 685 Abstract class for functions returning TIME values. 686 */ 687 class Item_time_func :public Item_temporal_func 688 { 689 public: Item_time_func()690 Item_time_func() :Item_temporal_func() {} Item_time_func(Item * a)691 Item_time_func(Item *a) :Item_temporal_func(a) {} Item_time_func(Item * a,Item * b)692 Item_time_func(Item *a,Item *b) :Item_temporal_func(a,b) {} Item_time_func(Item * a,Item * b,Item * c)693 Item_time_func(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {} field_type()694 enum_field_types field_type() const { return MYSQL_TYPE_TIME; } val_real()695 double val_real() { return val_real_from_decimal(); } val_decimal(my_decimal * decimal_value)696 my_decimal *val_decimal(my_decimal *decimal_value) 697 { 698 DBUG_ASSERT(fixed == 1); 699 return val_decimal_from_time(decimal_value); 700 } save_in_field(Field * field,bool no_conversions)701 type_conversion_status save_in_field(Field *field, bool no_conversions) 702 { 703 return save_time_in_field(field); 704 } val_int()705 longlong val_int() 706 { 707 return val_int_from_time(); 708 } 709 longlong val_time_temporal(); get_date(MYSQL_TIME * res,uint fuzzy_date)710 bool get_date(MYSQL_TIME *res, uint fuzzy_date) 711 { 712 return get_date_from_time(res); 713 } val_str(String * str)714 String *val_str(String *str) 715 { 716 return val_string_from_time(str); 717 } 718 // All time functions must implement get_time() 719 // to avoid use of generic Item::get_time() 720 // which converts to string and then parses the string as TIME. 721 virtual bool get_time(MYSQL_TIME *res)= 0; 722 }; 723 724 725 /** 726 Cache for MYSQL_TIME value with various representations. 727 728 - MYSQL_TIME representation (time) is initialized during set_XXX(). 729 - Packed representation (time_packed) is also initialized during set_XXX(). 730 - String representation (string_buff) is not initialized during set_XXX(); 731 it's initialized only if val_str() or cptr() are called. 732 */ 733 class MYSQL_TIME_cache 734 { 735 MYSQL_TIME time; ///< MYSQL_TIME representation 736 longlong time_packed; ///< packed representation 737 char string_buff[MAX_DATE_STRING_REP_LENGTH]; ///< string representation 738 uint string_length; ///< length of string 739 uint8 dec; ///< Number of decimals 740 /** 741 Cache string representation from the cached MYSQL_TIME representation. 742 If string representation has already been cached, then nothing happens. 743 */ 744 void cache_string(); 745 /** 746 Reset string representation. 747 */ reset_string()748 void reset_string() 749 { 750 string_length= 0; 751 string_buff[0]= '\0'; 752 } 753 /** 754 Reset all members. 755 */ reset()756 void reset() 757 { 758 time.time_type= MYSQL_TIMESTAMP_NONE; 759 time_packed= 0; 760 reset_string(); 761 dec= 0; 762 } 763 /** 764 Store MYSQL_TIME representation into the given MYSQL_TIME variable. 765 */ get_TIME(MYSQL_TIME * ltime)766 void get_TIME(MYSQL_TIME *ltime) const 767 { 768 DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE); 769 *ltime= time; 770 } 771 public: 772 MYSQL_TIME_cache()773 MYSQL_TIME_cache() 774 { 775 reset(); 776 } 777 /** 778 Set time and time_packed from a DATE value. 779 */ 780 void set_date(MYSQL_TIME *ltime); 781 /** 782 Set time and time_packed from a TIME value. 783 */ 784 void set_time(MYSQL_TIME *ltime, uint8 dec_arg); 785 /** 786 Set time and time_packed from a DATETIME value. 787 */ 788 void set_datetime(MYSQL_TIME *ltime, uint8 dec_arg); 789 /** 790 Set time and time_packed according to DATE value 791 in "struct timeval" representation and its time zone. 792 */ 793 void set_date(struct timeval tv, Time_zone *tz); 794 /** 795 Set time and time_packed according to TIME value 796 in "struct timeval" representation and its time zone. 797 */ 798 void set_time(struct timeval tv, uint8 dec_arg, Time_zone *tz); 799 /** 800 Set time and time_packed according to DATETIME value 801 in "struct timeval" representation and its time zone. 802 */ 803 void set_datetime(struct timeval tv, uint8 dec_arg, Time_zone *tz); 804 /** 805 Test if cached value is equal to another MYSQL_TIME_cache value. 806 */ eq(const MYSQL_TIME_cache & tm)807 bool eq(const MYSQL_TIME_cache &tm) const 808 { 809 return val_packed() == tm.val_packed(); 810 } 811 812 /** 813 Return number of decimal digits. 814 */ decimals()815 uint8 decimals() const 816 { 817 DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE); 818 return dec; 819 } 820 821 /** 822 Return packed representation. 823 */ val_packed()824 longlong val_packed() const 825 { 826 DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE); 827 return time_packed; 828 } 829 /** 830 Store MYSQL_TIME representation into the given date/datetime variable 831 checking date flags. 832 */ 833 bool get_date(MYSQL_TIME *ltime, uint fuzzyflags) const; 834 /** 835 Store MYSQL_TIME representation into the given time variable. 836 */ get_time(MYSQL_TIME * ltime)837 bool get_time(MYSQL_TIME *ltime) const 838 { 839 get_TIME(ltime); 840 return false; 841 } 842 /** 843 Return pointer to MYSQL_TIME representation. 844 */ get_TIME_ptr()845 MYSQL_TIME *get_TIME_ptr() 846 { 847 DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE); 848 return &time; 849 } 850 /** 851 Store string representation into String. 852 */ 853 String *val_str(String *str); 854 /** 855 Return C string representation. 856 */ 857 const char *cptr(); 858 }; 859 860 861 /** 862 DATE'2010-01-01' 863 */ 864 class Item_date_literal :public Item_date_func 865 { 866 MYSQL_TIME_cache cached_time; 867 public: 868 /** 869 Constructor for Item_date_literal. 870 @param ltime DATE value. 871 */ Item_date_literal(MYSQL_TIME * ltime)872 Item_date_literal(MYSQL_TIME *ltime) :Item_date_func() 873 { 874 cached_time.set_date(ltime); 875 fix_length_and_dec(); 876 fixed= 1; 877 } func_name()878 const char *func_name() const { return "date_literal"; } 879 void print(String *str, enum_query_type query_type); val_date_temporal()880 longlong val_date_temporal() 881 { 882 DBUG_ASSERT(fixed); 883 return cached_time.val_packed(); 884 } get_date(MYSQL_TIME * ltime,uint fuzzy_date)885 bool get_date(MYSQL_TIME *ltime, uint fuzzy_date) 886 { 887 DBUG_ASSERT(fixed); 888 return cached_time.get_date(ltime, fuzzy_date); 889 } val_str(String * str)890 String *val_str(String *str) 891 { 892 DBUG_ASSERT(fixed); 893 return cached_time.val_str(str); 894 } fix_length_and_dec()895 void fix_length_and_dec() 896 { 897 fix_length_and_dec_and_charset_datetime(MAX_DATE_WIDTH, 0); 898 } check_partition_func_processor(uchar * int_arg)899 bool check_partition_func_processor(uchar *int_arg) 900 { 901 return FALSE; 902 } basic_const_item()903 bool basic_const_item() const { return true; } const_item()904 bool const_item() const { return true; } used_tables()905 table_map used_tables() const { return (table_map) 0L; } not_null_tables()906 table_map not_null_tables() const { return used_tables(); } cleanup()907 void cleanup() 908 { 909 // See Item_basic_const::cleanup() 910 if (orig_name.is_set()) 911 item_name= orig_name; 912 } 913 bool eq(const Item *item, bool binary_cmp) const; 914 }; 915 916 917 /** 918 TIME'10:10:10' 919 */ 920 class Item_time_literal :public Item_time_func 921 { 922 MYSQL_TIME_cache cached_time; 923 public: 924 /** 925 Constructor for Item_time_literal. 926 @param ltime TIME value. 927 @param dec_arg number of fractional digits in ltime. 928 */ Item_time_literal(MYSQL_TIME * ltime,uint dec_arg)929 Item_time_literal(MYSQL_TIME *ltime, uint dec_arg) :Item_time_func() 930 { 931 decimals= MY_MIN(dec_arg, DATETIME_MAX_DECIMALS); 932 cached_time.set_time(ltime, decimals); 933 fix_length_and_dec(); 934 fixed= 1; 935 } func_name()936 const char *func_name() const { return "time_literal"; } 937 void print(String *str, enum_query_type query_type); val_time_temporal()938 longlong val_time_temporal() 939 { 940 DBUG_ASSERT(fixed); 941 return cached_time.val_packed(); 942 } get_time(MYSQL_TIME * ltime)943 bool get_time(MYSQL_TIME *ltime) 944 { 945 DBUG_ASSERT(fixed); 946 return cached_time.get_time(ltime); 947 } val_str(String * str)948 String *val_str(String *str) 949 { 950 DBUG_ASSERT(fixed); 951 return cached_time.val_str(str); 952 } fix_length_and_dec()953 void fix_length_and_dec() 954 { 955 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, decimals); 956 } check_partition_func_processor(uchar * int_arg)957 bool check_partition_func_processor(uchar *int_arg) 958 { 959 return FALSE; 960 } basic_const_item()961 bool basic_const_item() const { return true; } const_item()962 bool const_item() const { return true; } used_tables()963 table_map used_tables() const { return (table_map) 0L; } not_null_tables()964 table_map not_null_tables() const { return used_tables(); } cleanup()965 void cleanup() 966 { 967 // See Item_basic_const::cleanup() 968 if (orig_name.is_set()) 969 item_name= orig_name; 970 } 971 bool eq(const Item *item, bool binary_cmp) const; 972 }; 973 974 975 /** 976 TIMESTAMP'2001-01-01 10:20:30' 977 */ 978 class Item_datetime_literal :public Item_datetime_func 979 { 980 MYSQL_TIME_cache cached_time; 981 public: 982 /** 983 Constructor for Item_datetime_literal. 984 @param ltime DATETIME value. 985 @param dec_arg number of fractional digits in ltime. 986 */ Item_datetime_literal(MYSQL_TIME * ltime,uint dec_arg)987 Item_datetime_literal(MYSQL_TIME *ltime, uint dec_arg) :Item_datetime_func() 988 { 989 decimals= MY_MIN(dec_arg, DATETIME_MAX_DECIMALS); 990 cached_time.set_datetime(ltime, decimals); 991 fix_length_and_dec(); 992 fixed= 1; 993 } func_name()994 const char *func_name() const { return "datetime_literal"; } 995 void print(String *str, enum_query_type query_type); val_date_temporal()996 longlong val_date_temporal() 997 { 998 DBUG_ASSERT(fixed); 999 return cached_time.val_packed(); 1000 } get_date(MYSQL_TIME * ltime,uint fuzzy_date)1001 bool get_date(MYSQL_TIME *ltime, uint fuzzy_date) 1002 { 1003 DBUG_ASSERT(fixed); 1004 return cached_time.get_date(ltime, fuzzy_date); 1005 } val_str(String * str)1006 String *val_str(String *str) 1007 { 1008 DBUG_ASSERT(fixed); 1009 return cached_time.val_str(str); 1010 } fix_length_and_dec()1011 void fix_length_and_dec() 1012 { 1013 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, decimals); 1014 } check_partition_func_processor(uchar * int_arg)1015 bool check_partition_func_processor(uchar *int_arg) 1016 { 1017 return FALSE; 1018 } basic_const_item()1019 bool basic_const_item() const { return true; } const_item()1020 bool const_item() const { return true; } used_tables()1021 table_map used_tables() const { return (table_map) 0L; } not_null_tables()1022 table_map not_null_tables() const { return used_tables(); } cleanup()1023 void cleanup() 1024 { 1025 // See Item_basic_const::cleanup() 1026 if (orig_name.is_set()) 1027 item_name= orig_name; 1028 } 1029 bool eq(const Item *item, bool binary_cmp) const; 1030 }; 1031 1032 1033 /* Abstract CURTIME function. Children should define what time zone is used */ 1034 1035 class Item_func_curtime :public Item_time_func 1036 { 1037 MYSQL_TIME_cache cached_time; // Initialized in fix_length_and_dec 1038 protected: 1039 // Abstract method that defines which time zone is used for conversion. 1040 virtual Time_zone *time_zone()= 0; 1041 public: 1042 /** 1043 Constructor for Item_func_curtime. 1044 @param dec_arg Number of fractional digits. 1045 */ Item_func_curtime(uint8 dec_arg)1046 Item_func_curtime(uint8 dec_arg) :Item_time_func() { decimals= dec_arg; } 1047 void fix_length_and_dec(); val_time_temporal()1048 longlong val_time_temporal() 1049 { 1050 DBUG_ASSERT(fixed == 1); 1051 return cached_time.val_packed(); 1052 } get_time(MYSQL_TIME * ltime)1053 bool get_time(MYSQL_TIME *ltime) 1054 { 1055 DBUG_ASSERT(fixed == 1); 1056 return cached_time.get_time(ltime); 1057 } val_str(String * str)1058 String *val_str(String *str) 1059 { 1060 DBUG_ASSERT(fixed == 1); 1061 return cached_time.val_str(&str_value); 1062 } 1063 }; 1064 1065 1066 class Item_func_curtime_local :public Item_func_curtime 1067 { 1068 protected: 1069 Time_zone *time_zone(); 1070 public: Item_func_curtime_local(uint8 dec_arg)1071 Item_func_curtime_local(uint8 dec_arg) :Item_func_curtime(dec_arg) {} func_name()1072 const char *func_name() const { return "curtime"; } 1073 }; 1074 1075 1076 class Item_func_curtime_utc :public Item_func_curtime 1077 { 1078 protected: 1079 Time_zone *time_zone(); 1080 public: Item_func_curtime_utc(uint8 dec_arg)1081 Item_func_curtime_utc(uint8 dec_arg) :Item_func_curtime(dec_arg) {} func_name()1082 const char *func_name() const { return "utc_time"; } 1083 }; 1084 1085 1086 /* Abstract CURDATE function. See also Item_func_curtime. */ 1087 1088 class Item_func_curdate :public Item_date_func 1089 { 1090 MYSQL_TIME_cache cached_time; // Initialized in fix_length_and_dec 1091 protected: 1092 virtual Time_zone *time_zone()= 0; 1093 public: Item_func_curdate()1094 Item_func_curdate() :Item_date_func() {} 1095 void fix_length_and_dec(); val_date_temporal()1096 longlong val_date_temporal() 1097 { 1098 DBUG_ASSERT(fixed == 1); 1099 return cached_time.val_packed(); 1100 } get_date(MYSQL_TIME * res,uint fuzzy_date)1101 bool get_date(MYSQL_TIME *res, uint fuzzy_date) 1102 { 1103 DBUG_ASSERT(fixed == 1); 1104 return cached_time.get_time(res); 1105 } val_str(String * str)1106 String *val_str(String *str) 1107 { 1108 DBUG_ASSERT(fixed == 1); 1109 return cached_time.val_str(&str_value); 1110 } 1111 }; 1112 1113 1114 class Item_func_curdate_local :public Item_func_curdate 1115 { 1116 protected: 1117 Time_zone *time_zone(); 1118 public: Item_func_curdate_local()1119 Item_func_curdate_local() :Item_func_curdate() {} func_name()1120 const char *func_name() const { return "curdate"; } 1121 }; 1122 1123 1124 class Item_func_curdate_utc :public Item_func_curdate 1125 { 1126 protected: 1127 Time_zone *time_zone(); 1128 public: Item_func_curdate_utc()1129 Item_func_curdate_utc() :Item_func_curdate() {} func_name()1130 const char *func_name() const { return "utc_date"; } 1131 }; 1132 1133 1134 /* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */ 1135 1136 class Item_func_now :public Item_datetime_func 1137 { 1138 MYSQL_TIME_cache cached_time; 1139 protected: 1140 virtual Time_zone *time_zone()= 0; 1141 public: 1142 /** 1143 Constructor for Item_func_now. 1144 @param dec_arg Number of fractional digits. 1145 */ Item_func_now(uint8 dec_arg)1146 Item_func_now(uint8 dec_arg) :Item_datetime_func() { decimals= dec_arg; } 1147 void fix_length_and_dec(); 1148 type_conversion_status save_in_field(Field *to, bool no_conversions); val_date_temporal()1149 longlong val_date_temporal() 1150 { 1151 DBUG_ASSERT(fixed == 1); 1152 return cached_time.val_packed(); 1153 } get_date(MYSQL_TIME * res,uint fuzzy_date)1154 bool get_date(MYSQL_TIME *res, uint fuzzy_date) 1155 { 1156 DBUG_ASSERT(fixed == 1); 1157 return cached_time.get_time(res); 1158 } val_str(String * str)1159 String *val_str(String *str) 1160 { 1161 DBUG_ASSERT(fixed == 1); 1162 return cached_time.val_str(&str_value); 1163 } 1164 }; 1165 1166 1167 class Item_func_now_local :public Item_func_now 1168 { 1169 protected: 1170 Time_zone *time_zone(); 1171 public: 1172 /** 1173 Stores the query start time in a field, truncating to the field's number 1174 of fractional second digits. 1175 1176 @param field The field to store in. 1177 */ 1178 static void store_in(Field *field); 1179 Item_func_now_local(uint8 dec_arg)1180 Item_func_now_local(uint8 dec_arg) :Item_func_now(dec_arg) {} func_name()1181 const char *func_name() const { return "now"; } functype()1182 virtual enum Functype functype() const { return NOW_FUNC; } 1183 }; 1184 1185 1186 class Item_func_now_utc :public Item_func_now 1187 { 1188 protected: 1189 Time_zone *time_zone(); 1190 public: Item_func_now_utc(uint8 dec_arg)1191 Item_func_now_utc(uint8 dec_arg) :Item_func_now(dec_arg) {} func_name()1192 const char *func_name() const { return "utc_timestamp"; } 1193 }; 1194 1195 1196 /* 1197 This is like NOW(), but always uses the real current time, not the 1198 query_start(). This matches the Oracle behavior. 1199 */ 1200 class Item_func_sysdate_local :public Item_datetime_func 1201 { 1202 public: Item_func_sysdate_local(uint8 dec_arg)1203 Item_func_sysdate_local(uint8 dec_arg) : 1204 Item_datetime_func() { decimals= dec_arg; } const_item()1205 bool const_item() const { return 0; } func_name()1206 const char *func_name() const { return "sysdate"; } 1207 void fix_length_and_dec(); 1208 bool get_date(MYSQL_TIME *res, uint fuzzy_date); 1209 /** 1210 This function is non-deterministic and hence depends on the 'RAND' pseudo-table. 1211 1212 @retval Always RAND_TABLE_BIT 1213 */ get_initial_pseudo_tables()1214 table_map get_initial_pseudo_tables() const { return RAND_TABLE_BIT; } 1215 }; 1216 1217 1218 class Item_func_from_days :public Item_date_func 1219 { 1220 public: Item_func_from_days(Item * a)1221 Item_func_from_days(Item *a) :Item_date_func(a) {} func_name()1222 const char *func_name() const { return "from_days"; } 1223 bool get_date(MYSQL_TIME *res, uint fuzzy_date); check_partition_func_processor(uchar * int_arg)1224 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)1225 bool check_valid_arguments_processor(uchar *int_arg) 1226 { 1227 return has_date_args() || has_time_args(); 1228 } 1229 }; 1230 1231 1232 class Item_func_date_format :public Item_str_func 1233 { 1234 int fixed_length; 1235 const bool is_time_format; 1236 String value; 1237 public: Item_func_date_format(Item * a,Item * b,bool is_time_format_arg)1238 Item_func_date_format(Item *a,Item *b,bool is_time_format_arg) 1239 :Item_str_func(a,b),is_time_format(is_time_format_arg) {} 1240 String *val_str(String *str); func_name()1241 const char *func_name() const 1242 { return is_time_format ? "time_format" : "date_format"; } 1243 void fix_length_and_dec(); 1244 uint format_length(const String *format); 1245 bool eq(const Item *item, bool binary_cmp) const; 1246 }; 1247 1248 1249 class Item_func_from_unixtime :public Item_datetime_func 1250 { 1251 THD *thd; 1252 public: Item_func_from_unixtime(Item * a)1253 Item_func_from_unixtime(Item *a) :Item_datetime_func(a) {} func_name()1254 const char *func_name() const { return "from_unixtime"; } 1255 void fix_length_and_dec(); 1256 bool get_date(MYSQL_TIME *res, uint fuzzy_date); 1257 }; 1258 1259 1260 /* 1261 We need Time_zone class declaration for storing pointers in 1262 Item_func_convert_tz. 1263 */ 1264 class Time_zone; 1265 1266 /* 1267 This class represents CONVERT_TZ() function. 1268 The important fact about this function that it is handled in special way. 1269 When such function is met in expression time_zone system tables are added 1270 to global list of tables to open, so later those already opened and locked 1271 tables can be used during this function calculation for loading time zone 1272 descriptions. 1273 */ 1274 class Item_func_convert_tz :public Item_datetime_func 1275 { 1276 /* 1277 If time zone parameters are constants we are caching objects that 1278 represent them (we use separate from_tz_cached/to_tz_cached members 1279 to indicate this fact, since NULL is legal value for from_tz/to_tz 1280 members. 1281 */ 1282 bool from_tz_cached, to_tz_cached; 1283 Time_zone *from_tz, *to_tz; 1284 public: Item_func_convert_tz(Item * a,Item * b,Item * c)1285 Item_func_convert_tz(Item *a, Item *b, Item *c): 1286 Item_datetime_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} func_name()1287 const char *func_name() const { return "convert_tz"; } 1288 void fix_length_and_dec(); 1289 bool get_date(MYSQL_TIME *res, uint fuzzy_date); 1290 void cleanup(); 1291 }; 1292 1293 1294 class Item_func_sec_to_time :public Item_time_func 1295 { 1296 public: Item_func_sec_to_time(Item * item)1297 Item_func_sec_to_time(Item *item) :Item_time_func(item) {} fix_length_and_dec()1298 void fix_length_and_dec() 1299 { 1300 maybe_null=1; 1301 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, 1302 MY_MIN(args[0]->decimals, 1303 DATETIME_MAX_DECIMALS)); 1304 } func_name()1305 const char *func_name() const { return "sec_to_time"; } 1306 bool get_time(MYSQL_TIME *ltime); 1307 }; 1308 1309 1310 class Item_date_add_interval :public Item_temporal_hybrid_func 1311 { 1312 String value; 1313 bool get_date_internal(MYSQL_TIME *res, uint fuzzy_date); 1314 bool get_time_internal(MYSQL_TIME *res); 1315 protected: 1316 bool val_datetime(MYSQL_TIME *ltime, uint fuzzy_date); 1317 1318 public: 1319 const interval_type int_type; // keep it public 1320 const bool date_sub_interval; // keep it public Item_date_add_interval(Item * a,Item * b,interval_type type_arg,bool neg_arg)1321 Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg) 1322 :Item_temporal_hybrid_func(a, b), 1323 int_type(type_arg), date_sub_interval(neg_arg) {} func_name()1324 const char *func_name() const { return "date_add_interval"; } 1325 void fix_length_and_dec(); 1326 bool eq(const Item *item, bool binary_cmp) const; 1327 void print(String *str, enum_query_type query_type); 1328 }; 1329 1330 1331 class Item_extract :public Item_int_func 1332 { 1333 bool date_value; 1334 public: 1335 const interval_type int_type; // keep it public Item_extract(interval_type type_arg,Item * a)1336 Item_extract(interval_type type_arg, Item *a) 1337 :Item_int_func(a), int_type(type_arg) {} 1338 longlong val_int(); functype()1339 enum Functype functype() const { return EXTRACT_FUNC; } func_name()1340 const char *func_name() const { return "extract"; } 1341 void fix_length_and_dec(); 1342 bool eq(const Item *item, bool binary_cmp) const; 1343 virtual void print(String *str, enum_query_type query_type); check_partition_func_processor(uchar * int_arg)1344 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)1345 bool check_valid_arguments_processor(uchar *int_arg) 1346 { 1347 switch (int_type) { 1348 case INTERVAL_YEAR: 1349 case INTERVAL_YEAR_MONTH: 1350 case INTERVAL_QUARTER: 1351 case INTERVAL_MONTH: 1352 /* case INTERVAL_WEEK: Not allowed as partitioning function, bug#57071 */ 1353 case INTERVAL_DAY: 1354 return !has_date_args(); 1355 case INTERVAL_DAY_HOUR: 1356 case INTERVAL_DAY_MINUTE: 1357 case INTERVAL_DAY_SECOND: 1358 case INTERVAL_DAY_MICROSECOND: 1359 return !has_datetime_args(); 1360 case INTERVAL_HOUR: 1361 case INTERVAL_HOUR_MINUTE: 1362 case INTERVAL_HOUR_SECOND: 1363 case INTERVAL_MINUTE: 1364 case INTERVAL_MINUTE_SECOND: 1365 case INTERVAL_SECOND: 1366 case INTERVAL_MICROSECOND: 1367 case INTERVAL_HOUR_MICROSECOND: 1368 case INTERVAL_MINUTE_MICROSECOND: 1369 case INTERVAL_SECOND_MICROSECOND: 1370 return !has_time_args(); 1371 default: 1372 /* 1373 INTERVAL_LAST is only an end marker, 1374 INTERVAL_WEEK depends on default_week_format which is a session 1375 variable and cannot be used for partitioning. See bug#57071. 1376 */ 1377 break; 1378 } 1379 return true; 1380 } 1381 }; 1382 1383 1384 class Item_date_typecast :public Item_date_func 1385 { 1386 public: Item_date_typecast(Item * a)1387 Item_date_typecast(Item *a) :Item_date_func(a) { maybe_null= 1; } 1388 void print(String *str, enum_query_type query_type); func_name()1389 const char *func_name() const { return "cast_as_date"; } 1390 bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); cast_type()1391 const char *cast_type() const { return "date"; } 1392 }; 1393 1394 1395 class Item_time_typecast :public Item_time_func 1396 { 1397 bool detect_precision_from_arg; 1398 public: Item_time_typecast(Item * a)1399 Item_time_typecast(Item *a): Item_time_func(a) 1400 { 1401 detect_precision_from_arg= true; 1402 } Item_time_typecast(Item * a,uint8 dec_arg)1403 Item_time_typecast(Item *a, uint8 dec_arg): Item_time_func(a) 1404 { 1405 detect_precision_from_arg= false; 1406 decimals= dec_arg; 1407 } 1408 void print(String *str, enum_query_type query_type); func_name()1409 const char *func_name() const { return "cast_as_time"; } 1410 bool get_time(MYSQL_TIME *ltime); cast_type()1411 const char *cast_type() const { return "time"; } fix_length_and_dec()1412 void fix_length_and_dec() 1413 { 1414 maybe_null= 1; 1415 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, 1416 detect_precision_from_arg ? 1417 args[0]->time_precision() : 1418 decimals); 1419 } 1420 }; 1421 1422 1423 class Item_datetime_typecast :public Item_datetime_func 1424 { 1425 bool detect_precision_from_arg; 1426 public: Item_datetime_typecast(Item * a)1427 Item_datetime_typecast(Item *a) :Item_datetime_func(a) 1428 { 1429 detect_precision_from_arg= true; 1430 } Item_datetime_typecast(Item * a,uint8 dec_arg)1431 Item_datetime_typecast(Item *a, uint8 dec_arg) :Item_datetime_func(a) 1432 { 1433 detect_precision_from_arg= false; 1434 decimals= dec_arg; 1435 } 1436 void print(String *str, enum_query_type query_type); func_name()1437 const char *func_name() const { return "cast_as_datetime"; } cast_type()1438 const char *cast_type() const { return "datetime"; } fix_length_and_dec()1439 void fix_length_and_dec() 1440 { 1441 maybe_null= 1; 1442 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, 1443 detect_precision_from_arg ? 1444 args[0]->datetime_precision(): 1445 decimals); 1446 } 1447 bool get_date(MYSQL_TIME *res, uint fuzzy_date); 1448 }; 1449 1450 1451 class Item_func_makedate :public Item_date_func 1452 { 1453 public: Item_func_makedate(Item * a,Item * b)1454 Item_func_makedate(Item *a, Item *b) :Item_date_func(a, b) { maybe_null= 1; } func_name()1455 const char *func_name() const { return "makedate"; } 1456 bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); 1457 }; 1458 1459 1460 class Item_func_add_time :public Item_temporal_hybrid_func 1461 { 1462 const bool is_date; 1463 int sign; 1464 bool val_datetime(MYSQL_TIME *time, uint fuzzy_date); 1465 public: Item_func_add_time(Item * a,Item * b,bool type_arg,bool neg_arg)1466 Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg) 1467 :Item_temporal_hybrid_func(a, b), is_date(type_arg) 1468 { 1469 sign= neg_arg ? -1 : 1; 1470 } 1471 void fix_length_and_dec(); 1472 void print(String *str, enum_query_type query_type); func_name()1473 const char *func_name() const { return "add_time"; } 1474 }; 1475 1476 1477 class Item_func_timediff :public Item_time_func 1478 { 1479 public: Item_func_timediff(Item * a,Item * b)1480 Item_func_timediff(Item *a, Item *b) :Item_time_func(a, b) {} func_name()1481 const char *func_name() const { return "timediff"; } fix_length_and_dec()1482 void fix_length_and_dec() 1483 { 1484 uint dec= MY_MAX(args[0]->time_precision(), args[1]->time_precision()); 1485 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, dec); 1486 maybe_null= 1; 1487 } 1488 bool get_time(MYSQL_TIME *ltime); 1489 }; 1490 1491 class Item_func_maketime :public Item_time_func 1492 { 1493 public: Item_func_maketime(Item * a,Item * b,Item * c)1494 Item_func_maketime(Item *a, Item *b, Item *c) :Item_time_func(a, b, c) 1495 { 1496 maybe_null= TRUE; 1497 } fix_length_and_dec()1498 void fix_length_and_dec() 1499 { 1500 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, 1501 MY_MIN(args[2]->decimals, 1502 DATETIME_MAX_DECIMALS)); 1503 } func_name()1504 const char *func_name() const { return "maketime"; } 1505 bool get_time(MYSQL_TIME *ltime); 1506 }; 1507 1508 class Item_func_microsecond :public Item_int_func 1509 { 1510 public: Item_func_microsecond(Item * a)1511 Item_func_microsecond(Item *a) :Item_int_func(a) {} 1512 longlong val_int(); func_name()1513 const char *func_name() const { return "microsecond"; } fix_length_and_dec()1514 void fix_length_and_dec() 1515 { 1516 maybe_null=1; 1517 } check_partition_func_processor(uchar * int_arg)1518 bool check_partition_func_processor(uchar *int_arg) {return FALSE;} check_valid_arguments_processor(uchar * int_arg)1519 bool check_valid_arguments_processor(uchar *int_arg) 1520 { 1521 return !has_time_args(); 1522 } 1523 }; 1524 1525 1526 class Item_func_timestamp_diff :public Item_int_func 1527 { 1528 const interval_type int_type; 1529 public: Item_func_timestamp_diff(Item * a,Item * b,interval_type type_arg)1530 Item_func_timestamp_diff(Item *a,Item *b,interval_type type_arg) 1531 :Item_int_func(a,b), int_type(type_arg) {} func_name()1532 const char *func_name() const { return "timestampdiff"; } 1533 longlong val_int(); fix_length_and_dec()1534 void fix_length_and_dec() 1535 { 1536 maybe_null=1; 1537 } 1538 virtual void print(String *str, enum_query_type query_type); 1539 }; 1540 1541 1542 enum date_time_format 1543 { 1544 USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT 1545 }; 1546 1547 class Item_func_get_format :public Item_str_ascii_func 1548 { 1549 public: 1550 const timestamp_type type; // keep it public Item_func_get_format(timestamp_type type_arg,Item * a)1551 Item_func_get_format(timestamp_type type_arg, Item *a) 1552 :Item_str_ascii_func(a), type(type_arg) 1553 {} 1554 String *val_str_ascii(String *str); func_name()1555 const char *func_name() const { return "get_format"; } fix_length_and_dec()1556 void fix_length_and_dec() 1557 { 1558 maybe_null= 1; 1559 decimals=0; 1560 fix_length_and_charset(17, default_charset()); 1561 } 1562 virtual void print(String *str, enum_query_type query_type); 1563 }; 1564 1565 1566 class Item_func_str_to_date :public Item_temporal_hybrid_func 1567 { 1568 timestamp_type cached_timestamp_type; 1569 bool const_item; 1570 void fix_from_format(const char *format, uint length); 1571 protected: 1572 bool val_datetime(MYSQL_TIME *ltime, uint fuzzy_date); 1573 public: Item_func_str_to_date(Item * a,Item * b)1574 Item_func_str_to_date(Item *a, Item *b) 1575 :Item_temporal_hybrid_func(a, b), const_item(false) 1576 {} func_name()1577 const char *func_name() const { return "str_to_date"; } 1578 void fix_length_and_dec(); 1579 }; 1580 1581 1582 class Item_func_last_day :public Item_date_func 1583 { 1584 public: Item_func_last_day(Item * a)1585 Item_func_last_day(Item *a) :Item_date_func(a) { maybe_null= 1; } func_name()1586 const char *func_name() const { return "last_day"; } 1587 bool get_date(MYSQL_TIME *res, uint fuzzy_date); 1588 }; 1589 1590 1591 /* Function prototypes */ 1592 1593 bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, 1594 timestamp_type type, String *str); 1595 1596 #endif /* ITEM_TIMEFUNC_INCLUDED */ 1597