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

unknown's avatar
unknown committed
4 5
   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
6
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
7

unknown's avatar
unknown committed
8 9 10 11
   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
12

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


/* Function items used by mysql */

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

25 26 27 28 29
enum date_time_format_types 
{ 
  TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
};

30 31 32
bool get_interval_value(Item *args,interval_type int_type,
			       String *str_value, INTERVAL *interval);

unknown's avatar
unknown committed
33 34 35 36 37 38
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"; }
39 40
  void fix_length_and_dec() 
  { 
41
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
42
  }
unknown's avatar
unknown committed
43 44 45 46 47 48 49 50 51
};


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"; }
52 53 54
  void fix_length_and_dec()
  { 
    decimals=0;
55
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
56
  }
unknown's avatar
unknown committed
57 58 59 60 61 62 63 64 65
};


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"; }
66 67 68
  void fix_length_and_dec() 
  { 
    decimals=0; 
69
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
70
    set_persist_maybe_null(1);
71
  }
unknown's avatar
unknown committed
72
  enum_monotonicity_info get_monotonicity_info() const;
73
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
74
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
75
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
76
  bool check_valid_arguments_processor(uchar *int_arg)
77 78 79
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
80 81 82 83 84 85 86 87 88
};


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"; }
89 90 91
  void fix_length_and_dec() 
  { 
    decimals=0; 
92
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
93
    set_persist_maybe_null(1);
94
  }
95
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
96
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
97
  bool check_valid_arguments_processor(uchar *int_arg)
98 99 100
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
101 102 103 104 105 106 107 108
};


class Item_func_month :public Item_func
{
public:
  Item_func_month(Item *a) :Item_func(a) {}
  longlong val_int();
109
  double val_real()
110
  { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
111 112
  String *val_str(String *str) 
  {
113 114 115 116 117
    longlong nr= val_int();
    if (null_value)
      return 0;
    str->set(nr, &my_charset_bin);
    return str;
118
  }
unknown's avatar
unknown committed
119 120
  const char *func_name() const { return "month"; }
  enum Item_result result_type () const { return INT_RESULT; }
121 122
  void fix_length_and_dec() 
  { 
123
    collation.set(&my_charset_bin);
124
    decimals=0;
125
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
126
    set_persist_maybe_null(1);
127
  }
128
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
129
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
130
  bool check_valid_arguments_processor(uchar *int_arg)
131 132 133
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
134 135
};

136

unknown's avatar
unknown committed
137 138
class Item_func_monthname :public Item_func_month
{
139
  MY_LOCALE *locale;
unknown's avatar
unknown committed
140 141 142 143 144
public:
  Item_func_monthname(Item *a) :Item_func_month(a) {}
  const char *func_name() const { return "monthname"; }
  String *val_str(String *str);
  enum Item_result result_type () const { return STRING_RESULT; }
145
  void fix_length_and_dec();
unknown's avatar
unknown committed
146
  bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
147
  bool check_vcol_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
148 149 150 151 152 153 154 155 156
};


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"; }
157 158 159
  void fix_length_and_dec() 
  { 
    decimals=0;
160
    max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
161
    set_persist_maybe_null(1);
162
  }
163
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
164
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
165
  bool check_valid_arguments_processor(uchar *int_arg)
166 167 168
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
169 170 171 172 173 174 175 176 177
};


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"; }
178 179 180
  void fix_length_and_dec()
  {
    decimals=0;
181
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
182
    set_persist_maybe_null(1);
183
  }
184
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
185
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
186
  bool check_valid_arguments_processor(uchar *int_arg)
187 188 189
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
190 191 192 193 194 195 196 197 198
};


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"; }
199 200 201
  void fix_length_and_dec()
  {
    decimals=0;
202
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
203
    set_persist_maybe_null(1);
204
  }
205
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
206
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
207
  bool check_valid_arguments_processor(uchar *int_arg)
208 209 210
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
211 212 213 214 215 216 217 218 219
};


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"; }
220 221 222
  void fix_length_and_dec()
  { 
     decimals=0;
223
     max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
224
     set_persist_maybe_null(1);
225
  }
226
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
227
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
228
  bool check_valid_arguments_processor(uchar *int_arg)
229 230 231
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
232 233 234 235 236 237 238 239 240
};


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"; }
241 242 243
  void fix_length_and_dec() 
  { 
    decimals=0;
244
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
245
    set_persist_maybe_null(1);
246
  }
247
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
248
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
249
  bool check_valid_arguments_processor(uchar *int_arg)
250 251 252
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
253 254 255 256 257 258 259 260 261
};


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"; }
262 263 264
  void fix_length_and_dec()
  { 
    decimals=0;
265
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
266
    set_persist_maybe_null(1);
267
  }
unknown's avatar
unknown committed
268 269 270 271 272 273 274 275
};

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"; }
276 277 278
  void fix_length_and_dec()
  { 
    decimals=0;
279
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
280
    set_persist_maybe_null(1);
281
  }
282
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
283
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
284
  bool check_valid_arguments_processor(uchar *int_arg)
285 286 287
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
288 289 290 291 292 293 294 295 296
};


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
297
  enum_monotonicity_info get_monotonicity_info() const;
298
  longlong val_int_endpoint(bool left_endp, bool *incl_endp);
299 300 301
  void fix_length_and_dec()
  { 
    decimals=0;
302
    max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
303
    set_persist_maybe_null(1);
304
  }
305
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
306
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
307
  bool check_valid_arguments_processor(uchar *int_arg)
308 309 310
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
311 312 313 314 315 316 317 318 319 320
};


class Item_func_weekday :public Item_func
{
  bool odbc_type;
public:
  Item_func_weekday(Item *a,bool type_arg)
    :Item_func(a), odbc_type(type_arg) {}
  longlong val_int();
321
  double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
322
  String *val_str(String *str)
323 324
  {
    DBUG_ASSERT(fixed == 1);
325
    str->set(val_int(), &my_charset_bin);
326 327
    return null_value ? 0 : str;
  }
328 329 330 331
  const char *func_name() const
  {
     return (odbc_type ? "dayofweek" : "weekday");
  }
unknown's avatar
unknown committed
332
  enum Item_result result_type () const { return INT_RESULT; }
333 334
  void fix_length_and_dec()
  {
335
    collation.set(&my_charset_bin);
336
    decimals=0;
337
    max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
338
    set_persist_maybe_null(1);
339
  }
340
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
341
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
342
  bool check_valid_arguments_processor(uchar *int_arg)
343 344 345
  {
    return !has_date_args();
  }
unknown's avatar
unknown committed
346 347 348 349
};

class Item_func_dayname :public Item_func_weekday
{
350
  MY_LOCALE *locale;
unknown's avatar
unknown committed
351 352 353 354 355
 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; }
356
  void fix_length_and_dec();
unknown's avatar
unknown committed
357
  bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
358
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
unknown's avatar
unknown committed
359 360 361
};


362
class Item_func_seconds_hybrid: public Item_func_numhybrid
unknown's avatar
unknown committed
363
{
364 365
protected:
  virtual enum_field_types arg0_expected_type() const = 0;
unknown's avatar
unknown committed
366
public:
367 368 369 370 371
  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)
372
      decimals= args[0]->temporal_precision(arg0_expected_type());
373
    set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
374
    max_length=17 + (decimals ? decimals + 1 : 0);
375
    set_persist_maybe_null(1);
376
  }
377 378
  void find_num_type()
  { cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
379
  double real_op() { DBUG_ASSERT(0); return 0; }
380
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
381
  bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
382 383
};

384

385 386 387
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
{
  bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
388 389
protected:
  enum_field_types arg0_expected_type() const { return MYSQL_TYPE_DATETIME; }
390 391 392
public:
  Item_func_unix_timestamp() :Item_func_seconds_hybrid() {}
  Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {}
393
  const char *func_name() const { return "unix_timestamp"; }
394 395 396 397 398 399
  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.
  */
400
  bool check_valid_arguments_processor(uchar *int_arg)
401 402 403
  {
    return !has_timestamp_args();
  }
404 405 406 407 408 409 410 411
  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());
  }
412
  longlong int_op();
413
  my_decimal *decimal_op(my_decimal* buf);
unknown's avatar
unknown committed
414 415 416
};


417
  
418
class Item_func_time_to_sec :public Item_func_seconds_hybrid
unknown's avatar
unknown committed
419
{
420 421
protected:
  enum_field_types arg0_expected_type() const { return MYSQL_TYPE_TIME; }
unknown's avatar
unknown committed
422
public:
423
  Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {}
unknown's avatar
unknown committed
424
  const char *func_name() const { return "time_to_sec"; }
425
  void fix_num_length_and_dec()
unknown's avatar
unknown committed
426
  {
427
    set_persist_maybe_null(1);
428
    Item_func_seconds_hybrid::fix_num_length_and_dec();
unknown's avatar
unknown committed
429
  }
430
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
431
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
432
  bool check_valid_arguments_processor(uchar *int_arg)
433 434 435
  {
    return !has_time_args();
  }
436
  longlong int_op();
437
  my_decimal *decimal_op(my_decimal* buf);
unknown's avatar
unknown committed
438 439 440
};


441
class Item_temporal_func: public Item_func
unknown's avatar
unknown committed
442 443
{
public:
444 445 446 447
  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
448
  enum Item_result result_type () const { return STRING_RESULT; }
449
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
unknown's avatar
unknown committed
450
  String *val_str(String *str);
451
  longlong val_int();
452 453
  double val_real();
  bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; }
454
  my_decimal *val_decimal(my_decimal *decimal_value)
455 456 457
  { return  val_decimal_from_date(decimal_value); }
  Field *tmp_table_field(TABLE *table)
  { return tmp_table_field_from_field_type(table, 0); }
458
  int save_in_field(Field *field, bool no_conversions)
459
  { return save_date_in_field(field); }
Sergei Golubchik's avatar
Sergei Golubchik committed
460 461
  void fix_length_and_dec()
  { 
462
    set_persist_maybe_null(1);
463
    max_length= mysql_temporal_int_part_length(field_type());
Sergei Golubchik's avatar
Sergei Golubchik committed
464 465 466 467 468 469 470 471 472 473
    if (decimals)
    {
      if (decimals == NOT_FIXED_DEC)
        max_length+= TIME_SECOND_PART_DIGITS + 1;
      else
      {
        set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
        max_length+= decimals + 1;
      }
    }
474 475 476 477
    /*
      We set maybe_null to 1 as default as any bad argument with date or
      time can get us to return NULL.
    */ 
478
    set_persist_maybe_null(1);
479
  }
480 481 482
};


483
class Item_datefunc :public Item_temporal_func
484 485
{
public:
Sergei Golubchik's avatar
Sergei Golubchik committed
486 487
  Item_datefunc() :Item_temporal_func() { }
  Item_datefunc(Item *a) :Item_temporal_func(a) { }
488
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
489 490 491
};


492
class Item_timefunc :public Item_temporal_func
493 494
{
public:
495 496 497 498
  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) {}
499
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
unknown's avatar
unknown committed
500 501 502
};


503
/* Abstract CURTIME function. Children should define what time zone is used */
504

505
class Item_func_curtime :public Item_timefunc
unknown's avatar
unknown committed
506
{
507
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
508
public:
509 510
  Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; }
  bool fix_fields(THD *, Item **);
Sergei Golubchik's avatar
Sergei Golubchik committed
511 512 513 514
  void fix_length_and_dec()
  {
    store_now_in_TIME(&ltime);
    Item_timefunc::fix_length_and_dec();
515
    set_persist_maybe_null(0);
Sergei Golubchik's avatar
Sergei Golubchik committed
516
  }
517
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
518 519
  /* 
    Abstract method that defines which time zone is used for conversion.
520
    Converts time current time in my_time_t representation to broken-down
521
    MYSQL_TIME representation using UTC-SYSTEM or per-thread time zone.
522
  */
523
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
524 525 526 527
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
unknown's avatar
unknown committed
528 529 530
};


531 532 533
class Item_func_curtime_local :public Item_func_curtime
{
public:
534
  Item_func_curtime_local(uint dec) :Item_func_curtime(dec) {}
535
  const char *func_name() const { return "curtime"; }
536
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
537 538 539 540 541 542
};


class Item_func_curtime_utc :public Item_func_curtime
{
public:
543
  Item_func_curtime_utc(uint dec) :Item_func_curtime(dec) {}
544
  const char *func_name() const { return "utc_time"; }
545
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
546 547 548 549 550
};


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

551
class Item_func_curdate :public Item_datefunc
unknown's avatar
unknown committed
552
{
553
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
554
public:
555
  Item_func_curdate() :Item_datefunc() {}
556
  void fix_length_and_dec();
557 558
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
559 560 561 562
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
563 564 565 566 567 568 569 570
};


class Item_func_curdate_local :public Item_func_curdate
{
public:
  Item_func_curdate_local() :Item_func_curdate() {}
  const char *func_name() const { return "curdate"; }
571
  void store_now_in_TIME(MYSQL_TIME *now_time);
unknown's avatar
unknown committed
572 573 574
};


575 576 577 578 579
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"; }
580
  void store_now_in_TIME(MYSQL_TIME *now_time);
581 582 583 584 585
};


/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */

586

587
class Item_func_now :public Item_temporal_func
unknown's avatar
unknown committed
588
{
589
  MYSQL_TIME ltime;
unknown's avatar
unknown committed
590
public:
591 592
  Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; }
  bool fix_fields(THD *, Item **);
Sergei Golubchik's avatar
Sergei Golubchik committed
593 594 595 596
  void fix_length_and_dec()
  {
    store_now_in_TIME(&ltime);
    Item_temporal_func::fix_length_and_dec();
597
    set_persist_maybe_null(0);
Sergei Golubchik's avatar
Sergei Golubchik committed
598
  }
599 600
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
  virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
601 602 603 604
  bool check_vcol_func_processor(uchar *int_arg) 
  {
    return trace_unsupported_by_check_vcol_func_processor(func_name());
  }
605 606 607 608 609 610
};


class Item_func_now_local :public Item_func_now
{
public:
611
  Item_func_now_local(uint dec) :Item_func_now(dec) {}
612
  const char *func_name() const { return "now"; }
613
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
614
  virtual enum Functype functype() const { return NOW_FUNC; }
615 616 617 618 619 620
};


class Item_func_now_utc :public Item_func_now
{
public:
621
  Item_func_now_utc(uint dec) :Item_func_now(dec) {}
622
  const char *func_name() const { return "utc_timestamp"; }
623
  virtual void store_now_in_TIME(MYSQL_TIME *now_time);
unknown's avatar
unknown committed
624 625 626
};


627 628 629 630 631 632 633
/*
  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:
634
  Item_func_sysdate_local(uint dec) :Item_func_now(dec) {}
635 636
  bool const_item() const { return 0; }
  const char *func_name() const { return "sysdate"; }
637 638
  void store_now_in_TIME(MYSQL_TIME *now_time);
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
639 640 641 642 643 644 645 646
  void update_used_tables()
  {
    Item_func_now::update_used_tables();
    used_tables_cache|= RAND_TABLE_BIT;
  }
};


647
class Item_func_from_days :public Item_datefunc
unknown's avatar
unknown committed
648 649
{
public:
650
  Item_func_from_days(Item *a) :Item_datefunc(a) {}
unknown's avatar
unknown committed
651
  const char *func_name() const { return "from_days"; }
652
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
653
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
654
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
655
  bool check_valid_arguments_processor(uchar *int_arg)
656 657 658
  {
    return has_date_args() || has_time_args();
  }
unknown's avatar
unknown committed
659 660 661 662 663 664
};


class Item_func_date_format :public Item_str_func
{
  int fixed_length;
665
  const bool is_time_format;
666
  String value;
unknown's avatar
unknown committed
667
public:
668 669
  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
670
  String *val_str(String *str);
671 672
  const char *func_name() const
    { return is_time_format ? "time_format" : "date_format"; }
unknown's avatar
unknown committed
673 674
  void fix_length_and_dec();
  uint format_length(const String *format);
unknown's avatar
unknown committed
675
  bool eq(const Item *item, bool binary_cmp) const;
unknown's avatar
unknown committed
676 677 678
};


679
class Item_func_from_unixtime :public Item_temporal_func
unknown's avatar
unknown committed
680
{
681
  THD *thd;
unknown's avatar
unknown committed
682
 public:
683
  Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
unknown's avatar
unknown committed
684
  const char *func_name() const { return "from_unixtime"; }
685
  void fix_length_and_dec();
686
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
687 688 689 690 691 692 693 694 695
};


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

696 697 698 699 700 701 702 703
/*
  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.
*/
704
class Item_func_convert_tz :public Item_temporal_func
705
{
706 707
  /*
    If time zone parameters are constants we are caching objects that
708 709 710
    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.
711
  */
712
  bool from_tz_cached, to_tz_cached;
713 714 715
  Time_zone *from_tz, *to_tz;
 public:
  Item_func_convert_tz(Item *a, Item *b, Item *c):
716
    Item_temporal_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
717 718
  const char *func_name() const { return "convert_tz"; }
  void fix_length_and_dec();
719
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
720
  void cleanup();
unknown's avatar
unknown committed
721 722 723
};


724
class Item_func_sec_to_time :public Item_timefunc
unknown's avatar
unknown committed
725 726
{
public:
727 728
  Item_func_sec_to_time(Item *item) :Item_timefunc(item) {}
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
729
  void fix_length_and_dec()
Sergei Golubchik's avatar
Sergei Golubchik committed
730
  {
731 732
    decimals= args[0]->decimals;
    Item_timefunc::fix_length_and_dec();
733
  }
unknown's avatar
unknown committed
734 735 736
  const char *func_name() const { return "sec_to_time"; }
};

737

738
class Item_date_add_interval :public Item_temporal_func
unknown's avatar
unknown committed
739 740
{
  String value;
741
  enum_field_types cached_field_type;
unknown's avatar
unknown committed
742 743

public:
744 745
  const interval_type int_type; // keep it public
  const bool date_sub_interval; // keep it public
unknown's avatar
unknown committed
746
  Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
747
    :Item_temporal_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
unknown's avatar
unknown committed
748
  const char *func_name() const { return "date_add_interval"; }
749 750
  void fix_length_and_dec();
  enum_field_types field_type() const { return cached_field_type; }
751
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
752
  bool eq(const Item *item, bool binary_cmp) const;
753
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
754 755
};

756

unknown's avatar
unknown committed
757 758 759 760
class Item_extract :public Item_int_func
{
  bool date_value;
 public:
761
  const interval_type int_type; // keep it public
unknown's avatar
unknown committed
762 763 764
  Item_extract(interval_type type_arg, Item *a)
    :Item_int_func(a), int_type(type_arg) {}
  longlong val_int();
765
  enum Functype functype() const { return EXTRACT_FUNC; }
unknown's avatar
unknown committed
766 767
  const char *func_name() const { return "extract"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
768
  bool eq(const Item *item, bool binary_cmp) const;
769
  virtual void print(String *str, enum_query_type query_type);
770
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
771
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
772
  bool check_valid_arguments_processor(uchar *int_arg)
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
  {
    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
808
};
809

810

811
class Item_char_typecast :public Item_str_func
812
{
Sergei Golubchik's avatar
Sergei Golubchik committed
813
  uint cast_length;
814
  CHARSET_INFO *cast_cs, *from_cs;
815 816 817
  bool charset_conversion;
  String tmp_value;
public:
Sergei Golubchik's avatar
Sergei Golubchik committed
818
  Item_char_typecast(Item *a, uint length_arg, CHARSET_INFO *cs_arg)
819
    :Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {}
820
  enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
821 822
  bool eq(const Item *item, bool binary_cmp) const;
  const char *func_name() const { return "cast_as_char"; }
823 824
  String *val_str(String *a);
  void fix_length_and_dec();
825
  void print(String *str, enum_query_type query_type);
826 827 828
};


829
class Item_temporal_typecast: public Item_temporal_func
unknown's avatar
unknown committed
830 831
{
public:
832 833 834
  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
835 836 837
  void fix_length_and_dec()
  {
    if (decimals == NOT_FIXED_DEC)
838
      decimals= args[0]->temporal_precision(field_type());
Sergei Golubchik's avatar
Sergei Golubchik committed
839 840
    Item_temporal_func::fix_length_and_dec();
  }
841 842 843
};

class Item_date_typecast :public Item_temporal_typecast
unknown's avatar
unknown committed
844 845
{
public:
846
  Item_date_typecast(Item *a) :Item_temporal_typecast(a) {}
847
  const char *func_name() const { return "cast_as_date"; }
848
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
849
  const char *cast_type() const { return "date"; }
850
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
851 852
};

853

854
class Item_time_typecast :public Item_temporal_typecast
855 856
{
public:
857 858
  Item_time_typecast(Item *a, uint dec_arg)
    :Item_temporal_typecast(a) { decimals= dec_arg; }
859
  const char *func_name() const { return "cast_as_time"; }
860
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
861
  const char *cast_type() const { return "time"; }
862
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
863 864
};

865

866
class Item_datetime_typecast :public Item_temporal_typecast
867 868
{
public:
869 870
  Item_datetime_typecast(Item *a, uint dec_arg)
    :Item_temporal_typecast(a) { decimals= dec_arg; }
871
  const char *func_name() const { return "cast_as_datetime"; }
872
  const char *cast_type() const { return "datetime"; }
873
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
874
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
875
};
unknown's avatar
unknown committed
876

877

878
class Item_func_makedate :public Item_temporal_func
unknown's avatar
unknown committed
879 880
{
public:
881
  Item_func_makedate(Item *a,Item *b) :Item_temporal_func(a,b) {}
unknown's avatar
unknown committed
882 883
  const char *func_name() const { return "makedate"; }
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
884
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
unknown's avatar
unknown committed
885 886
};

unknown's avatar
unknown committed
887

888
class Item_func_add_time :public Item_temporal_func
unknown's avatar
unknown committed
889
{
unknown's avatar
unknown committed
890
  const bool is_date;
unknown's avatar
unknown committed
891 892 893 894
  int sign;
  enum_field_types cached_field_type;

public:
unknown's avatar
unknown committed
895
  Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
896
    :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
unknown's avatar
unknown committed
897 898
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
899
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
900
  virtual void print(String *str, enum_query_type query_type);
901
  const char *func_name() const { return "add_time"; }
unknown's avatar
unknown committed
902 903
};

904
class Item_func_timediff :public Item_timefunc
unknown's avatar
unknown committed
905 906 907
{
public:
  Item_func_timediff(Item *a, Item *b)
908
    :Item_timefunc(a, b) {}
unknown's avatar
unknown committed
909 910 911
  const char *func_name() const { return "timediff"; }
  void fix_length_and_dec()
  {
912 913
    decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME),
                  args[1]->temporal_precision(MYSQL_TYPE_TIME));
914
    Item_timefunc::fix_length_and_dec();
unknown's avatar
unknown committed
915
  }
916
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
unknown's avatar
unknown committed
917 918
};

919
class Item_func_maketime :public Item_timefunc
unknown's avatar
unknown committed
920 921 922
{
public:
  Item_func_maketime(Item *a, Item *b, Item *c)
923
    :Item_timefunc(a, b, c) 
924
  {}
925 926 927 928 929
  void fix_length_and_dec()
  {
    decimals= min(args[2]->decimals, TIME_SECOND_PART_DIGITS);
    Item_timefunc::fix_length_and_dec();
  }
unknown's avatar
unknown committed
930
  const char *func_name() const { return "maketime"; }
931
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
unknown's avatar
unknown committed
932 933
};

934

unknown's avatar
unknown committed
935 936 937 938 939 940 941 942 943
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;
944
    set_persist_maybe_null(1);
unknown's avatar
unknown committed
945
  }
946
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
947
  bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
948
  bool check_valid_arguments_processor(uchar *int_arg)
949 950 951
  {
    return !has_time_args();
  }
unknown's avatar
unknown committed
952
};
953 954


955 956 957 958 959 960
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) {}
961
  const char *func_name() const { return "timestampdiff"; }
962 963 964 965
  longlong val_int();
  void fix_length_and_dec()
  {
    decimals=0;
966
    set_persist_maybe_null(1);
967
  }
968
  virtual void print(String *str, enum_query_type query_type);
969
};
unknown's avatar
unknown committed
970 971


972
enum date_time_format
973 974 975 976 977 978 979
{
  USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};

class Item_func_get_format :public Item_str_func
{
public:
980
  const timestamp_type type; // keep it public
981 982 983
  Item_func_get_format(timestamp_type type_arg, Item *a)
    :Item_str_func(a), type(type_arg)
  {}
984 985 986 987
  String *val_str(String *str);
  const char *func_name() const { return "get_format"; }
  void fix_length_and_dec()
  {
988
    set_persist_maybe_null(1);
989 990 991
    decimals=0;
    max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
  }
992
  virtual void print(String *str, enum_query_type query_type);
993 994 995
};


996
class Item_func_str_to_date :public Item_temporal_func
997
{
998 999 1000
  enum_field_types cached_field_type;
  timestamp_type cached_timestamp_type;
  bool const_item;
1001 1002
public:
  Item_func_str_to_date(Item *a, Item *b)
1003
    :Item_temporal_func(a, b), const_item(false)
1004
  {}
1005
  bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
1006
  const char *func_name() const { return "str_to_date"; }
1007 1008
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
1009
};
unknown's avatar
unknown committed
1010

1011

1012
class Item_func_last_day :public Item_datefunc
unknown's avatar
unknown committed
1013 1014
{
public:
1015
  Item_func_last_day(Item *a) :Item_datefunc(a) {}
unknown's avatar
unknown committed
1016
  const char *func_name() const { return "last_day"; }
1017
  bool get_date(MYSQL_TIME *res, uint fuzzy_date);
unknown's avatar
unknown committed
1018
};