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