item_timefunc.h 29.7 KB
Newer Older
1 2
#ifndef ITEM_TIMEFUNC_INCLUDED
#define ITEM_TIMEFUNC_INCLUDED
3 4
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
   Copyright (c) 2009-2011, Monty Program Ab
unknown's avatar
unknown committed
5

unknown's avatar
unknown committed
6 7
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
8
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
9

unknown's avatar
unknown committed
10 11 12 13
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
14

unknown's avatar
unknown committed
15 16
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
17
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
unknown's avatar
unknown committed
18 19 20 21


/* Function items used by mysql */

22
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
23 24 25
#pragma interface			/* gcc class implementation */
#endif

26 27
class MY_LOCALE;

28 29 30 31 32
enum date_time_format_types 
{ 
  TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
};

Alexander Barkov's avatar
Alexander Barkov committed
33 34 35

static inline uint
mysql_temporal_int_part_length(enum enum_field_types mysql_type)
Sergei Golubchik's avatar
Sergei Golubchik committed
36
{
Alexander Barkov's avatar
Alexander Barkov committed
37 38 39 40
  static uint max_time_type_width[5]=
  { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
    MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
  return max_time_type_width[mysql_type_to_time_type(mysql_type)+2];
Sergei Golubchik's avatar
Sergei Golubchik committed
41 42
}

Alexander Barkov's avatar
Alexander Barkov committed
43

Sergei Golubchik's avatar
Sergei Golubchik committed
44
bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval);
45

unknown's avatar
unknown committed
46 47 48 49 50 51
class Item_func_period_add :public Item_int_func
{
public:
  Item_func_period_add(Item *a,Item *b) :Item_int_func(a,b) {}
  longlong val_int();
  const char *func_name() const { return "period_add"; }
52 53
  void fix_length_and_dec() 
  { 
54
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
55
  }
unknown's avatar
unknown committed
56 57 58 59 60 61 62 63 64
};


class Item_func_period_diff :public Item_int_func
{
public:
  Item_func_period_diff(Item *a,Item *b) :Item_int_func(a,b) {}
  longlong val_int();
  const char *func_name() const { return "period_diff"; }
65 66 67
  void fix_length_and_dec()
  { 
    decimals=0;
68
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
69
  }
unknown's avatar
unknown committed
70 71 72 73 74 75 76 77 78
};


class Item_func_to_days :public Item_int_func
{
public:
  Item_func_to_days(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "to_days"; }
79 80 81
  void fix_length_and_dec() 
  { 
    decimals=0; 
82
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
83
    set_persist_maybe_null(1);
84
  }
unknown's avatar
unknown committed
85
  enum_monotonicity_info get_monotonicity_info() const;
86
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
87
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
88
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
89
  bool check_valid_arguments_processor(uchar *int_arg)
90 91 92
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
93 94 95
};


96 97 98 99 100 101 102 103 104 105
class Item_func_to_seconds :public Item_int_func
{
public:
  Item_func_to_seconds(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "to_seconds"; }
  void fix_length_and_dec() 
  { 
    decimals=0; 
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
Sergei Golubchik's avatar
Sergei Golubchik committed
106
    set_persist_maybe_null(1);
107 108 109 110
  }
  enum_monotonicity_info get_monotonicity_info() const;
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
  bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
111 112 113 114 115

  bool intro_version(uchar *int_arg)
  {
    int *input_version= (int*)int_arg;
    /* This function was introduced in 5.5 */
116
    int output_version= max(*input_version, 50500);
117 118 119
    *input_version= output_version;
    return 0;
  }
Mattias Jonsson's avatar
Mattias Jonsson committed
120 121 122 123 124 125

  /* Only meaningful with date part and optional time part */
  bool check_valid_arguments_processor(uchar *int_arg)
  {
    return !has_date_args();
  }
126 127 128
};


unknown's avatar
unknown committed
129 130 131 132 133 134
class Item_func_dayofmonth :public Item_int_func
{
public:
  Item_func_dayofmonth(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "dayofmonth"; }
135 136 137
  void fix_length_and_dec() 
  { 
    decimals=0; 
138
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
139
    set_persist_maybe_null(1);
140
  }
141
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
142
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
143
  bool check_valid_arguments_processor(uchar *int_arg)
144 145 146
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
147 148 149 150 151 152
};


class Item_func_month :public Item_func
{
public:
153
  Item_func_month(Item *a) :Item_func(a) { collation.set_numeric(); }
unknown's avatar
unknown committed
154
  longlong val_int();
155
  double val_real()
156
  { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
157 158
  String *val_str(String *str) 
  {
159 160 161
    longlong nr= val_int();
    if (null_value)
      return 0;
Sergey Glukhov's avatar
Sergey Glukhov committed
162
    str->set(nr, collation.collation);
163
    return str;
164
  }
unknown's avatar
unknown committed
165 166
  const char *func_name() const { return "month"; }
  enum Item_result result_type () const { return INT_RESULT; }
167 168
  void fix_length_and_dec() 
  { 
169 170
    decimals= 0;
    fix_char_length(2);
171
    set_persist_maybe_null(1);
172
  }
173
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
174
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
175
  bool check_valid_arguments_processor(uchar *int_arg)
176 177 178
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
179 180
};

181

182
class Item_func_monthname :public Item_str_func
unknown's avatar
unknown committed
183
{
184
  MY_LOCALE *locale;
unknown's avatar
unknown committed
185
public:
186
  Item_func_monthname(Item *a) :Item_str_func(a) {}
unknown's avatar
unknown committed
187 188
  const char *func_name() const { return "monthname"; }
  String *val_str(String *str);
189
  void fix_length_and_dec();
unknown's avatar
unknown committed
190
  bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
191
  bool check_vcol_func_processor(uchar *int_arg) {return FALSE;}
192 193 194 195
  bool check_valid_arguments_processor(uchar *int_arg)
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
196 197 198 199 200 201 202 203 204
};


class Item_func_dayofyear :public Item_int_func
{
public:
  Item_func_dayofyear(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "dayofyear"; }
205 206
  void fix_length_and_dec() 
  { 
207 208
    decimals= 0;
    fix_char_length(3);
209
    set_persist_maybe_null(1);
210
  }
211
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
212
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
213
  bool check_valid_arguments_processor(uchar *int_arg)
214 215 216
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
217 218 219 220 221 222 223 224 225
};


class Item_func_hour :public Item_int_func
{
public:
  Item_func_hour(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "hour"; }
226 227 228
  void fix_length_and_dec()
  {
    decimals=0;
229
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
230
    set_persist_maybe_null(1);
231
  }
232
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
233
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
234
  bool check_valid_arguments_processor(uchar *int_arg)
235 236 237
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
238 239 240 241 242 243 244 245 246
};


class Item_func_minute :public Item_int_func
{
public:
  Item_func_minute(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "minute"; }
247 248 249
  void fix_length_and_dec()
  {
    decimals=0;
250
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
251
    set_persist_maybe_null(1);
252
  }
253
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
254
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
255
  bool check_valid_arguments_processor(uchar *int_arg)
256 257 258
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
259 260 261 262 263 264 265 266 267
};


class Item_func_quarter :public Item_int_func
{
public:
  Item_func_quarter(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "quarter"; }
268 269 270
  void fix_length_and_dec()
  { 
     decimals=0;
271
     max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
272
     set_persist_maybe_null(1);
273
  }
274
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
275
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
276
  bool check_valid_arguments_processor(uchar *int_arg)
277 278 279
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
280 281 282 283 284 285 286 287 288
};


class Item_func_second :public Item_int_func
{
public:
  Item_func_second(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "second"; }
289 290 291
  void fix_length_and_dec() 
  { 
    decimals=0;
292
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
293
    set_persist_maybe_null(1);
294
  }
295
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
296
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
297
  bool check_valid_arguments_processor(uchar *int_arg)
298 299 300
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
301 302 303 304 305 306 307 308 309
};


class Item_func_week :public Item_int_func
{
public:
  Item_func_week(Item *a,Item *b) :Item_int_func(a,b) {}
  longlong val_int();
  const char *func_name() const { return "week"; }
310 311 312
  void fix_length_and_dec()
  { 
    decimals=0;
313
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
314
    set_persist_maybe_null(1);
315
  }
unknown's avatar
unknown committed
316 317 318 319 320 321 322 323
};

class Item_func_yearweek :public Item_int_func
{
public:
  Item_func_yearweek(Item *a,Item *b) :Item_int_func(a,b) {}
  longlong val_int();
  const char *func_name() const { return "yearweek"; }
324 325 326
  void fix_length_and_dec()
  { 
    decimals=0;
327
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
328
    set_persist_maybe_null(1);
329
  }
330
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
331
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
332
  bool check_valid_arguments_processor(uchar *int_arg)
333 334 335
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
336 337 338 339 340 341 342 343 344
};


class Item_func_year :public Item_int_func
{
public:
  Item_func_year(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "year"; }
unknown's avatar
unknown committed
345
  enum_monotonicity_info get_monotonicity_info() const;
346
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
347 348 349
  void fix_length_and_dec()
  { 
    decimals=0;
350
    max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
351
    set_persist_maybe_null(1);
352
  }
353
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
354
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
355
  bool check_valid_arguments_processor(uchar *int_arg)
356 357 358
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
359 360 361 362 363 364 365 366
};


class Item_func_weekday :public Item_func
{
  bool odbc_type;
public:
  Item_func_weekday(Item *a,bool type_arg)
367
    :Item_func(a), odbc_type(type_arg) { collation.set_numeric(); }
unknown's avatar
unknown committed
368
  longlong val_int();
369
  double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
370
  String *val_str(String *str)
371 372
  {
    DBUG_ASSERT(fixed == 1);
373
    str->set(val_int(), &my_charset_bin);
374 375
    return null_value ? 0 : str;
  }
376 377 378 379
  const char *func_name() const
  {
     return (odbc_type ? "dayofweek" : "weekday");
  }
unknown's avatar
unknown committed
380
  enum Item_result result_type () const { return INT_RESULT; }
381 382
  void fix_length_and_dec()
  {
383 384
    decimals= 0;
    fix_char_length(1);
385
    set_persist_maybe_null(1);
386
  }
387
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
388
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
389
  bool check_valid_arguments_processor(uchar *int_arg)
390 391 392
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
393 394 395 396
};

class Item_func_dayname :public Item_func_weekday
{
397
  MY_LOCALE *locale;
unknown's avatar
unknown committed
398 399 400 401 402
 public:
  Item_func_dayname(Item *a) :Item_func_weekday(a,0) {}
  const char *func_name() const { return "dayname"; }
  String *val_str(String *str);
  enum Item_result result_type () const { return STRING_RESULT; }
403
  void fix_length_and_dec();
unknown's avatar
unknown committed
404
  bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
405
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
unknown's avatar
unknown committed
406 407 408
};


409
class Item_func_seconds_hybrid: public Item_func_numhybrid
unknown's avatar
unknown committed
410 411
{
public:
412 413 414 415 416 417
  Item_func_seconds_hybrid() :Item_func_numhybrid() {}
  Item_func_seconds_hybrid(Item *a) :Item_func_numhybrid(a) {}
  void fix_num_length_and_dec()
  {
    if (arg_count)
      decimals= args[0]->decimals;
418
    set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
419
    max_length=17 + (decimals ? decimals + 1 : 0);
Sergei Golubchik's avatar
Sergei Golubchik committed
420
    set_persist_maybe_null(1);
421
  }
422 423
  void find_num_type()
  { cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
424
  double real_op() { DBUG_ASSERT(0); return 0; }
425
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
426
  bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
427 428
};

429

430 431 432 433 434 435
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
{
  bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
public:
  Item_func_unix_timestamp() :Item_func_seconds_hybrid() {}
  Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {}
436
  const char *func_name() const { return "unix_timestamp"; }
Mattias Jonsson's avatar
Mattias Jonsson committed
437 438
  enum_monotonicity_info get_monotonicity_info() const;
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
439 440 441 442 443 444
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
  /*
    UNIX_TIMESTAMP() depends on the current timezone
    (and thus may not be used as a partitioning function)
    when its argument is NOT of the TIMESTAMP type.
  */
445
  bool check_valid_arguments_processor(uchar *int_arg)
446 447 448
  {
    return !has_timestamp_args();
  }
449 450 451 452 453 454 455 456
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    /*
      TODO: Allow UNIX_TIMESTAMP called with an argument to be a part
      of the expression for a virtual column
    */
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
457
  longlong int_op();
458
  my_decimal *decimal_op(my_decimal* buf);
unknown's avatar
unknown committed
459 460 461
};


462
class Item_func_time_to_sec :public Item_func_seconds_hybrid
unknown's avatar
unknown committed
463 464
{
public:
465
  Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {}
unknown's avatar
unknown committed
466
  const char *func_name() const { return "time_to_sec"; }
467
  void fix_num_length_and_dec()
unknown's avatar
unknown committed
468
  {
469
    set_persist_maybe_null(1);
470
    Item_func_seconds_hybrid::fix_num_length_and_dec();
unknown's avatar
unknown committed
471
  }
472
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
473
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
474
  bool check_valid_arguments_processor(uchar *int_arg)
475 476 477
  {
    return !has_time_args();
  }
478
  longlong int_op();
479
  my_decimal *decimal_op(my_decimal* buf);
unknown's avatar
unknown committed
480 481 482
};


483
class Item_temporal_func: public Item_func
unknown's avatar
unknown committed
484
{
Sergei Golubchik's avatar
Sergei Golubchik committed
485
  ulonglong sql_mode;
unknown's avatar
unknown committed
486
public:
487 488 489 490
  Item_temporal_func() :Item_func() {}
  Item_temporal_func(Item *a) :Item_func(a) {}
  Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {}
  Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {}
unknown's avatar
unknown committed
491
  enum Item_result result_type () const { return STRING_RESULT; }
492
  CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
493
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
494
  Item_result cmp_type() const { return TIME_RESULT; }
unknown's avatar
unknown committed
495
  String *val_str(String *str);
496
  longlong val_int();
497
  double val_real();
498
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date) { DBUG_ASSERT(0); return 1; }
499
  my_decimal *val_decimal(my_decimal *decimal_value)
500 501 502
  { return  val_decimal_from_date(decimal_value); }
  Field *tmp_table_field(TABLE *table)
  { return tmp_table_field_from_field_type(table, 0); }
503
  int save_in_field(Field *field, bool no_conversions)
504
  { return save_date_in_field(field); }
Sergei Golubchik's avatar
Sergei Golubchik committed
505
  void fix_length_and_dec();
506 507 508
};


509
class Item_datefunc :public Item_temporal_func
510 511
{
public:
Sergei Golubchik's avatar
Sergei Golubchik committed
512 513
  Item_datefunc() :Item_temporal_func() { }
  Item_datefunc(Item *a) :Item_temporal_func(a) { }
514
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
515 516 517
};


518
class Item_timefunc :public Item_temporal_func
519 520
{
public:
521 522 523 524
  Item_timefunc() :Item_temporal_func() {}
  Item_timefunc(Item *a) :Item_temporal_func(a) {}
  Item_timefunc(Item *a,Item *b) :Item_temporal_func(a,b) {}
  Item_timefunc(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {}
525
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
unknown's avatar
unknown committed
526 527 528
};


529
/* Abstract CURTIME function. Children should define what time zone is used */
530

531
class Item_func_curtime :public Item_timefunc
unknown's avatar
unknown committed
532
{
533
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
534
public:
535 536
  Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; }
  bool fix_fields(THD *, Item **);
Sergei Golubchik's avatar
Sergei Golubchik committed
537 538 539 540
  void fix_length_and_dec()
  {
    store_now_in_TIME(&ltime);
    Item_timefunc::fix_length_and_dec();
541
    set_persist_maybe_null(0);
Sergei Golubchik's avatar
Sergei Golubchik committed
542
  }
543
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
544 545
  /* 
    Abstract method that defines which time zone is used for conversion.
546
    Converts time current time in my_time_t representation to broken-down
547
    MYSQL_TIME representation using UTC-SYSTEM or per-thread time zone.
548
  */
549
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
550 551 552 553
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
unknown's avatar
unknown committed
554 555 556
};


557 558 559
class Item_func_curtime_local :public Item_func_curtime
{
public:
560
  Item_func_curtime_local(uint dec) :Item_func_curtime(dec) {}
561
  const char *func_name() const { return "curtime"; }
562
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
563 564 565 566 567 568
};


class Item_func_curtime_utc :public Item_func_curtime
{
public:
569
  Item_func_curtime_utc(uint dec) :Item_func_curtime(dec) {}
570
  const char *func_name() const { return "utc_time"; }
571
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
572 573 574 575 576
};


/* Abstract CURDATE function. See also Item_func_curtime. */

577
class Item_func_curdate :public Item_datefunc
unknown's avatar
unknown committed
578
{
579
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
580
public:
581
  Item_func_curdate() :Item_datefunc() {}
582
  void fix_length_and_dec();
583
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
584
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
585 586 587 588
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
589 590 591 592 593 594 595 596
};


class Item_func_curdate_local :public Item_func_curdate
{
public:
  Item_func_curdate_local() :Item_func_curdate() {}
  const char *func_name() const { return "curdate"; }
597
  void store_now_in_TIME(MYSQL_TIME *now_time);
unknown's avatar
unknown committed
598 599 600
};


601 602 603 604 605
class Item_func_curdate_utc :public Item_func_curdate
{
public:
  Item_func_curdate_utc() :Item_func_curdate() {}
  const char *func_name() const { return "utc_date"; }
606
  void store_now_in_TIME(MYSQL_TIME *now_time);
607 608 609 610 611
};


/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */

612

613
class Item_func_now :public Item_temporal_func
unknown's avatar
unknown committed
614
{
615
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
616
public:
617 618
  Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; }
  bool fix_fields(THD *, Item **);
Sergei Golubchik's avatar
Sergei Golubchik committed
619 620 621 622
  void fix_length_and_dec()
  {
    store_now_in_TIME(&ltime);
    Item_temporal_func::fix_length_and_dec();
623
    set_persist_maybe_null(0);
Sergei Golubchik's avatar
Sergei Golubchik committed
624
  }
625
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
626
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
627 628 629 630
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
631 632 633 634 635 636
};


class Item_func_now_local :public Item_func_now
{
public:
637
  Item_func_now_local(uint dec) :Item_func_now(dec) {}
638
  const char *func_name() const { return "now"; }
639
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
640
  virtual enum Functype functype() const { return NOW_FUNC; }
641 642 643 644 645 646
};


class Item_func_now_utc :public Item_func_now
{
public:
647
  Item_func_now_utc(uint dec) :Item_func_now(dec) {}
648
  const char *func_name() const { return "utc_timestamp"; }
649
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
unknown's avatar
unknown committed
650 651 652
};


653 654 655 656 657 658 659
/*
  This is like NOW(), but always uses the real current time, not the
  query_start(). This matches the Oracle behavior.
*/
class Item_func_sysdate_local :public Item_func_now
{
public:
660
  Item_func_sysdate_local(uint dec) :Item_func_now(dec) {}
661 662
  bool const_item() const { return 0; }
  const char *func_name() const { return "sysdate"; }
663
  void store_now_in_TIME(MYSQL_TIME *now_time);
664
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
665 666 667
  void update_used_tables()
  {
    Item_func_now::update_used_tables();
Sergei Golubchik's avatar
Sergei Golubchik committed
668
    set_persist_maybe_null(0);
669 670 671 672 673
    used_tables_cache|= RAND_TABLE_BIT;
  }
};


674
class Item_func_from_days :public Item_datefunc
unknown's avatar
unknown committed
675 676
{
public:
677
  Item_func_from_days(Item *a) :Item_datefunc(a) {}
unknown's avatar
unknown committed
678
  const char *func_name() const { return "from_days"; }
679
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
680
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
681
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
682
  bool check_valid_arguments_processor(uchar *int_arg)
683 684 685
  {
    return has_date_args() || has_time_args();
  }
unknown's avatar
unknown committed
686 687 688 689 690 691
};


class Item_func_date_format :public Item_str_func
{
  int fixed_length;
692
  const bool is_time_format;
693
  String value;
unknown's avatar
unknown committed
694
public:
695 696
  Item_func_date_format(Item *a,Item *b,bool is_time_format_arg)
    :Item_str_func(a,b),is_time_format(is_time_format_arg) {}
unknown's avatar
unknown committed
697
  String *val_str(String *str);
698 699
  const char *func_name() const
    { return is_time_format ? "time_format" : "date_format"; }
unknown's avatar
unknown committed
700 701
  void fix_length_and_dec();
  uint format_length(const String *format);
unknown's avatar
unknown committed
702
  bool eq(const Item *item, bool binary_cmp) const;
unknown's avatar
unknown committed
703 704 705
};


706
class Item_func_from_unixtime :public Item_temporal_func
unknown's avatar
unknown committed
707
{
708
  THD *thd;
unknown's avatar
unknown committed
709
 public:
710
  Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
unknown's avatar
unknown committed
711
  const char *func_name() const { return "from_unixtime"; }
712
  void fix_length_and_dec();
713
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
714 715 716 717 718 719 720 721 722
};


/* 
  We need Time_zone class declaration for storing pointers in
  Item_func_convert_tz.
*/
class Time_zone;

723 724 725 726 727 728 729 730
/*
  This class represents CONVERT_TZ() function.
  The important fact about this function that it is handled in special way.
  When such function is met in expression time_zone system tables are added
  to global list of tables to open, so later those already opened and locked
  tables can be used during this function calculation for loading time zone
  descriptions.
*/
731
class Item_func_convert_tz :public Item_temporal_func
732
{
733 734
  /*
    If time zone parameters are constants we are caching objects that
735 736 737
    represent them (we use separate from_tz_cached/to_tz_cached members
    to indicate this fact, since NULL is legal value for from_tz/to_tz
    members.
738
  */
739
  bool from_tz_cached, to_tz_cached;
740 741 742
  Time_zone *from_tz, *to_tz;
 public:
  Item_func_convert_tz(Item *a, Item *b, Item *c):
743
    Item_temporal_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
744 745
  const char *func_name() const { return "convert_tz"; }
  void fix_length_and_dec();
746
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
747
  void cleanup();
unknown's avatar
unknown committed
748 749 750
};


751
class Item_func_sec_to_time :public Item_timefunc
unknown's avatar
unknown committed
752 753
{
public:
754
  Item_func_sec_to_time(Item *item) :Item_timefunc(item) {}
755
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
756
  void fix_length_and_dec()
Sergei Golubchik's avatar
Sergei Golubchik committed
757
  {
758 759
    decimals= args[0]->decimals;
    Item_timefunc::fix_length_and_dec();
760
  }
unknown's avatar
unknown committed
761 762 763
  const char *func_name() const { return "sec_to_time"; }
};

764

765
class Item_date_add_interval :public Item_temporal_func
unknown's avatar
unknown committed
766
{
767
  enum_field_types cached_field_type;
unknown's avatar
unknown committed
768
public:
769 770
  const interval_type int_type; // keep it public
  const bool date_sub_interval; // keep it public
unknown's avatar
unknown committed
771
  Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
772
    :Item_temporal_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
unknown's avatar
unknown committed
773
  const char *func_name() const { return "date_add_interval"; }
774 775
  void fix_length_and_dec();
  enum_field_types field_type() const { return cached_field_type; }
776
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
777
  bool eq(const Item *item, bool binary_cmp) const;
Sergei Golubchik's avatar
Sergei Golubchik committed
778
  void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
779 780
};

781

unknown's avatar
unknown committed
782 783 784 785
class Item_extract :public Item_int_func
{
  bool date_value;
 public:
786
  const interval_type int_type; // keep it public
unknown's avatar
unknown committed
787 788 789
  Item_extract(interval_type type_arg, Item *a)
    :Item_int_func(a), int_type(type_arg) {}
  longlong val_int();
790
  enum Functype functype() const { return EXTRACT_FUNC; }
unknown's avatar
unknown committed
791 792
  const char *func_name() const { return "extract"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
793
  bool eq(const Item *item, bool binary_cmp) const;
Sergei Golubchik's avatar
Sergei Golubchik committed
794
  void print(String *str, enum_query_type query_type);
795
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
796
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
797
  bool check_valid_arguments_processor(uchar *int_arg)
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
  {
    switch (int_type) {
    case INTERVAL_YEAR:
    case INTERVAL_YEAR_MONTH:
    case INTERVAL_QUARTER:
    case INTERVAL_MONTH:
    /* case INTERVAL_WEEK: Not allowed as partitioning function, bug#57071 */
    case INTERVAL_DAY:
      return !has_date_args();
    case INTERVAL_DAY_HOUR:
    case INTERVAL_DAY_MINUTE:
    case INTERVAL_DAY_SECOND:
    case INTERVAL_DAY_MICROSECOND:
      return !has_datetime_args();
    case INTERVAL_HOUR:
    case INTERVAL_HOUR_MINUTE:
    case INTERVAL_HOUR_SECOND:
    case INTERVAL_MINUTE:
    case INTERVAL_MINUTE_SECOND:
    case INTERVAL_SECOND:
    case INTERVAL_MICROSECOND:
    case INTERVAL_HOUR_MICROSECOND:
    case INTERVAL_MINUTE_MICROSECOND:
    case INTERVAL_SECOND_MICROSECOND:
      return !has_time_args();
    default:
      /*
        INTERVAL_LAST is only an end marker,
        INTERVAL_WEEK depends on default_week_format which is a session
        variable and cannot be used for partitioning. See bug#57071.
      */
      break;
    }
    return true;
  }
unknown's avatar
unknown committed
833
};
834

835

836
class Item_char_typecast :public Item_str_func
837
{
Sergei Golubchik's avatar
Sergei Golubchik committed
838
  uint cast_length;
839
  CHARSET_INFO *cast_cs, *from_cs;
840 841 842
  bool charset_conversion;
  String tmp_value;
public:
Sergei Golubchik's avatar
Sergei Golubchik committed
843
  Item_char_typecast(Item *a, uint length_arg, CHARSET_INFO *cs_arg)
844
    :Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {}
845
  enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
846 847
  bool eq(const Item *item, bool binary_cmp) const;
  const char *func_name() const { return "cast_as_char"; }
848 849
  String *val_str(String *a);
  void fix_length_and_dec();
850
  void print(String *str, enum_query_type query_type);
851 852 853
};


854
class Item_temporal_typecast: public Item_temporal_func
unknown's avatar
unknown committed
855 856
{
public:
857 858 859
  Item_temporal_typecast(Item *a) :Item_temporal_func(a) {}
  virtual const char *cast_type() const = 0;
  void print(String *str, enum_query_type query_type);
Sergei Golubchik's avatar
Sergei Golubchik committed
860 861 862 863 864 865
  void fix_length_and_dec()
  {
    if (decimals == NOT_FIXED_DEC)
      decimals= args[0]->decimals;
    Item_temporal_func::fix_length_and_dec();
  }
866 867 868
};

class Item_date_typecast :public Item_temporal_typecast
unknown's avatar
unknown committed
869 870
{
public:
871
  Item_date_typecast(Item *a) :Item_temporal_typecast(a) {}
872
  const char *func_name() const { return "cast_as_date"; }
873
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
874
  const char *cast_type() const { return "date"; }
875
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
876 877
};

878

879
class Item_time_typecast :public Item_temporal_typecast
880 881
{
public:
882 883
  Item_time_typecast(Item *a, uint dec_arg)
    :Item_temporal_typecast(a) { decimals= dec_arg; }
884
  const char *func_name() const { return "cast_as_time"; }
885
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
886
  const char *cast_type() const { return "time"; }
887
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
888 889
};

890

891
class Item_datetime_typecast :public Item_temporal_typecast
892 893
{
public:
894 895
  Item_datetime_typecast(Item *a, uint dec_arg)
    :Item_temporal_typecast(a) { decimals= dec_arg; }
896
  const char *func_name() const { return "cast_as_datetime"; }
897
  const char *cast_type() const { return "datetime"; }
898
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
899
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
900
};
unknown's avatar
unknown committed
901

902

903
class Item_func_makedate :public Item_temporal_func
unknown's avatar
unknown committed
904 905
{
public:
906
  Item_func_makedate(Item *a,Item *b) :Item_temporal_func(a,b) {}
unknown's avatar
unknown committed
907 908
  const char *func_name() const { return "makedate"; }
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
909
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
unknown's avatar
unknown committed
910 911
};

unknown's avatar
unknown committed
912

913
class Item_func_add_time :public Item_temporal_func
unknown's avatar
unknown committed
914
{
unknown's avatar
unknown committed
915
  const bool is_date;
unknown's avatar
unknown committed
916 917 918 919
  int sign;
  enum_field_types cached_field_type;

public:
unknown's avatar
unknown committed
920
  Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
921
    :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
unknown's avatar
unknown committed
922 923
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
924
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
Sergei Golubchik's avatar
Sergei Golubchik committed
925
  void print(String *str, enum_query_type query_type);
926
  const char *func_name() const { return "add_time"; }
unknown's avatar
unknown committed
927 928
};

929
class Item_func_timediff :public Item_timefunc
unknown's avatar
unknown committed
930 931 932
{
public:
  Item_func_timediff(Item *a, Item *b)
933
    :Item_timefunc(a, b) {}
unknown's avatar
unknown committed
934 935 936
  const char *func_name() const { return "timediff"; }
  void fix_length_and_dec()
  {
937
    decimals= max(args[0]->decimals, args[1]->decimals);
938
    Item_timefunc::fix_length_and_dec();
unknown's avatar
unknown committed
939
  }
940
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
unknown's avatar
unknown committed
941 942
};

943
class Item_func_maketime :public Item_timefunc
unknown's avatar
unknown committed
944 945 946
{
public:
  Item_func_maketime(Item *a, Item *b, Item *c)
947
    :Item_timefunc(a, b, c) 
948
  {}
unknown's avatar
unknown committed
949
  const char *func_name() const { return "maketime"; }
950
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
unknown's avatar
unknown committed
951 952
};

953

unknown's avatar
unknown committed
954 955 956 957 958 959 960 961 962
class Item_func_microsecond :public Item_int_func
{
public:
  Item_func_microsecond(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "microsecond"; }
  void fix_length_and_dec() 
  { 
    decimals=0;
963
    set_persist_maybe_null(1);
unknown's avatar
unknown committed
964
  }
965
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
966
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
967
  bool check_valid_arguments_processor(uchar *int_arg)
968 969 970
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
971
};
972 973


974 975 976 977 978 979
class Item_func_timestamp_diff :public Item_int_func
{
  const interval_type int_type;
public:
  Item_func_timestamp_diff(Item *a,Item *b,interval_type type_arg)
    :Item_int_func(a,b), int_type(type_arg) {}
980
  const char *func_name() const { return "timestampdiff"; }
981 982 983 984
  longlong val_int();
  void fix_length_and_dec()
  {
    decimals=0;
985
    set_persist_maybe_null(1);
986
  }
987
  virtual void print(String *str, enum_query_type query_type);
988
};
unknown's avatar
unknown committed
989 990


991
enum date_time_format
992 993 994 995
{
  USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};

996
class Item_func_get_format :public Item_str_ascii_func
997 998
{
public:
999
  const timestamp_type type; // keep it public
1000
  Item_func_get_format(timestamp_type type_arg, Item *a)
1001
    :Item_str_ascii_func(a), type(type_arg)
1002
  {}
1003
  String *val_str_ascii(String *str);
1004 1005 1006
  const char *func_name() const { return "get_format"; }
  void fix_length_and_dec()
  {
1007
    set_persist_maybe_null(1);
1008
    decimals=0;
1009
    fix_length_and_charset(17, default_charset());
1010
  }
1011
  virtual void print(String *str, enum_query_type query_type);
1012 1013 1014
};


1015
class Item_func_str_to_date :public Item_temporal_func
1016
{
1017 1018 1019
  enum_field_types cached_field_type;
  timestamp_type cached_timestamp_type;
  bool const_item;
1020 1021
public:
  Item_func_str_to_date(Item *a, Item *b)
1022
    :Item_temporal_func(a, b), const_item(false)
1023
  {}
1024
  bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
1025
  const char *func_name() const { return "str_to_date"; }
1026 1027
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
1028
};
unknown's avatar
unknown committed
1029

1030

1031
class Item_func_last_day :public Item_datefunc
unknown's avatar
unknown committed
1032 1033
{
public:
1034
  Item_func_last_day(Item *a) :Item_datefunc(a) {}
unknown's avatar
unknown committed
1035
  const char *func_name() const { return "last_day"; }
1036
  bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
unknown's avatar
unknown committed
1037
};
1038

1039 1040 1041 1042 1043 1044

/* Function prototypes */

bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
                    timestamp_type type, String *str);

1045
#endif /* ITEM_TIMEFUNC_INCLUDED */