item_timefunc.h 23.3 KB
Newer Older
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
2

bk@work.mysql.com's avatar
bk@work.mysql.com committed
3 4 5 6
   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
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
7

bk@work.mysql.com's avatar
bk@work.mysql.com 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.
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
12

bk@work.mysql.com's avatar
bk@work.mysql.com committed
13 14 15 16 17 18 19 20 21 22 23
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* Function items used by mysql */

#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

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

bk@work.mysql.com's avatar
bk@work.mysql.com committed
29 30 31 32 33 34
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"; }
35 36
  void fix_length_and_dec() 
  { 
37
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
38
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
39 40 41 42 43 44 45 46 47
};


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"; }
48 49 50
  void fix_length_and_dec()
  { 
    decimals=0;
51
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
52
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
53 54 55 56 57 58 59 60 61
};


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"; }
62 63 64
  void fix_length_and_dec() 
  { 
    decimals=0; 
65
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
66 67
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
68 69 70 71 72 73 74 75 76
};


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"; }
77 78 79
  void fix_length_and_dec() 
  { 
    decimals=0; 
80
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
81 82
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
83 84 85 86 87 88 89 90
};


class Item_func_month :public Item_func
{
public:
  Item_func_month(Item *a) :Item_func(a) {}
  longlong val_int();
91 92
  double val()
  { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
93 94
  String *val_str(String *str) 
  {
95
    str->set(val_int(), &my_charset_bin);
96 97
    return null_value ? 0 : str;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
98 99
  const char *func_name() const { return "month"; }
  enum Item_result result_type () const { return INT_RESULT; }
100 101
  void fix_length_and_dec() 
  { 
102
    collation.set(&my_charset_bin);
103
    decimals=0;
104
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
105 106
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
107 108
};

109

bk@work.mysql.com's avatar
bk@work.mysql.com committed
110 111 112 113 114 115 116
class Item_func_monthname :public Item_func_month
{
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; }
117
  void fix_length_and_dec() 
118
  {
119
    collation.set(&my_charset_bin);
120
    decimals=0;
121
    max_length=10*my_charset_bin.mbmaxlen;
122 123
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
124 125 126 127 128 129 130 131 132
};


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"; }
133 134 135
  void fix_length_and_dec() 
  { 
    decimals=0;
136
    max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
137 138
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
139 140 141 142 143 144 145 146 147
};


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"; }
148 149 150
  void fix_length_and_dec()
  {
    decimals=0;
151
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
152 153
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
154 155 156 157 158 159 160 161 162
};


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"; }
163 164 165
  void fix_length_and_dec()
  {
    decimals=0;
166
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
167 168
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
169 170 171 172 173 174 175 176 177
};


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"; }
178 179 180
  void fix_length_and_dec()
  { 
     decimals=0;
181
     max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
182 183
     maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
184 185 186 187 188 189 190 191 192
};


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"; }
193 194 195
  void fix_length_and_dec() 
  { 
    decimals=0;
196
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
197 198
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
199 200 201 202 203 204 205 206 207
};


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"; }
208 209 210
  void fix_length_and_dec()
  { 
    decimals=0;
211
    max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
212 213
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
214 215 216 217 218 219 220 221
};

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"; }
222 223 224
  void fix_length_and_dec()
  { 
    decimals=0;
225
    max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
226 227
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
228 229 230 231 232 233 234 235 236
};


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"; }
237 238 239
  void fix_length_and_dec()
  { 
    decimals=0;
240
    max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
241 242
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
243 244 245 246 247 248 249 250 251 252
};


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();
253
  double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
254
  String *val_str(String *str)
255 256
  {
    DBUG_ASSERT(fixed == 1);
257
    str->set(val_int(), &my_charset_bin);
258 259
    return null_value ? 0 : str;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
260 261
  const char *func_name() const { return "weekday"; }
  enum Item_result result_type () const { return INT_RESULT; }
262 263
  void fix_length_and_dec()
  {
264
    collation.set(&my_charset_bin);
265
    decimals=0;
266
    max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
267 268
    maybe_null=1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
269 270 271 272 273 274 275 276 277
};

class Item_func_dayname :public Item_func_weekday
{
 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; }
278 279
  void fix_length_and_dec() 
  { 
280
    collation.set(&my_charset_bin);
281
    decimals=0; 
282
    max_length=9*MY_CHARSET_BIN_MB_MAXLEN;
283 284
    maybe_null=1; 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
285 286 287 288 289 290 291 292 293 294
};


class Item_func_unix_timestamp :public Item_int_func
{
  String value;
public:
  Item_func_unix_timestamp() :Item_int_func() {}
  Item_func_unix_timestamp(Item *a) :Item_int_func(a) {}
  longlong val_int();
295
  const char *func_name() const { return "unix_timestamp"; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
296 297
  void fix_length_and_dec()
  {
298
    decimals=0;
299
    max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
300 301 302 303 304 305 306 307 308 309 310 311
  }
};


class Item_func_time_to_sec :public Item_int_func
{
public:
  Item_func_time_to_sec(Item *item) :Item_int_func(item) {}
  longlong val_int();
  const char *func_name() const { return "time_to_sec"; }
  void fix_length_and_dec()
  {
312
    decimals=0;
313
    max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
314 315 316 317 318 319 320 321 322 323 324 325
  }
};


/* This can't be a Item_str_func, because the val() functions are special */

class Item_date :public Item_func
{
public:
  Item_date() :Item_func() {}
  Item_date(Item *a) :Item_func(a) {}
  enum Item_result result_type () const { return STRING_RESULT; }
326
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
327
  String *val_str(String *str);
328
  longlong val_int();
329
  double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
330
  const char *func_name() const { return "date"; }
331 332
  void fix_length_and_dec()
  { 
333
    collation.set(&my_charset_bin);
334
    decimals=0;
335
    max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
336
  }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
337
  int save_in_field(Field *to, bool no_conversions);
338 339
  Field *tmp_table_field(TABLE *t_arg)
  {
340
    return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
341
  }  
342 343 344 345 346 347 348 349 350
};


class Item_date_func :public Item_str_func
{
public:
  Item_date_func() :Item_str_func() {}
  Item_date_func(Item *a) :Item_str_func(a) {}
  Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
351
  Item_date_func(Item *a,Item *b, Item *c) :Item_str_func(a,b,c) {}
352
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
353 354
  Field *tmp_table_field(TABLE *t_arg)
  {
355
    return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
356
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
357 358 359
};


360
/* Abstract CURTIME function. Children should define what time zone is used */
361

bk@work.mysql.com's avatar
bk@work.mysql.com committed
362 363 364
class Item_func_curtime :public Item_func
{
  longlong value;
365
  char buff[9*2+32];
bk@work.mysql.com's avatar
bk@work.mysql.com committed
366 367 368 369 370
  uint buff_length;
public:
  Item_func_curtime() :Item_func() {}
  Item_func_curtime(Item *a) :Item_func(a) {}
  enum Item_result result_type () const { return STRING_RESULT; }
371
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
372 373
  double val() { DBUG_ASSERT(fixed == 1); return (double) value; }
  longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
374
  String *val_str(String *str);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
375
  void fix_length_and_dec();
376 377
  Field *tmp_table_field(TABLE *t_arg)
  {
378
    return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
379 380 381
  }
  /* 
    Abstract method that defines which time zone is used for conversion.
382 383
    Converts time current time in my_time_t representation to broken-down
    TIME representation using UTC-SYSTEM or per-thread time zone.
384
  */
385
  virtual void store_now_in_TIME(TIME *now_time)=0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
386 387 388
};


389 390 391 392 393 394
class Item_func_curtime_local :public Item_func_curtime
{
public:
  Item_func_curtime_local() :Item_func_curtime() {}
  Item_func_curtime_local(Item *a) :Item_func_curtime(a) {}
  const char *func_name() const { return "curtime"; }
395
  virtual void store_now_in_TIME(TIME *now_time);
396 397 398 399 400 401 402 403 404
};


class Item_func_curtime_utc :public Item_func_curtime
{
public:
  Item_func_curtime_utc() :Item_func_curtime() {}
  Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {}
  const char *func_name() const { return "utc_time"; }
405
  virtual void store_now_in_TIME(TIME *now_time);
406 407 408 409 410
};


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

bk@work.mysql.com's avatar
bk@work.mysql.com committed
411 412 413 414 415 416
class Item_func_curdate :public Item_date
{
  longlong value;
  TIME ltime;
public:
  Item_func_curdate() :Item_date() {}
417
  longlong val_int() { DBUG_ASSERT(fixed == 1); return (value) ; }
418
  String *val_str(String *str);
419
  void fix_length_and_dec();
420
  bool get_date(TIME *res, uint fuzzy_date);
421
  virtual void store_now_in_TIME(TIME *now_time)=0;
422 423 424 425 426 427 428 429
};


class Item_func_curdate_local :public Item_func_curdate
{
public:
  Item_func_curdate_local() :Item_func_curdate() {}
  const char *func_name() const { return "curdate"; }
430
  void store_now_in_TIME(TIME *now_time);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
431 432 433
};


434 435 436 437 438
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"; }
439
  void store_now_in_TIME(TIME *now_time);
440 441 442 443 444
};


/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */

445
class Item_func_now :public Item_date_func
bk@work.mysql.com's avatar
bk@work.mysql.com committed
446 447
{
  longlong value;
448
  char buff[20*2+32];	// +32 to make my_snprintf_{8bit|ucs2} happy
bk@work.mysql.com's avatar
bk@work.mysql.com committed
449 450 451
  uint buff_length;
  TIME ltime;
public:
452 453
  Item_func_now() :Item_date_func() {}
  Item_func_now(Item *a) :Item_date_func(a) {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
454
  enum Item_result result_type () const { return STRING_RESULT; }
455 456
  double val()	     { DBUG_ASSERT(fixed == 1); return (double) value; }
  longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
457
  int save_in_field(Field *to, bool no_conversions);
458
  String *val_str(String *str);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
459
  void fix_length_and_dec();
460
  bool get_date(TIME *res, uint fuzzy_date);
461
  virtual void store_now_in_TIME(TIME *now_time)=0;
462 463 464 465 466 467 468 469 470
};


class Item_func_now_local :public Item_func_now
{
public:
  Item_func_now_local() :Item_func_now() {}
  Item_func_now_local(Item *a) :Item_func_now(a) {}
  const char *func_name() const { return "now"; }
471
  virtual void store_now_in_TIME(TIME *now_time);
472
  virtual enum Functype functype() const { return NOW_FUNC; }
473 474 475 476 477 478 479 480 481
};


class Item_func_now_utc :public Item_func_now
{
public:
  Item_func_now_utc() :Item_func_now() {}
  Item_func_now_utc(Item *a) :Item_func_now(a) {}
  const char *func_name() const { return "utc_timestamp"; }
482
  virtual void store_now_in_TIME(TIME *now_time);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
483 484 485 486 487 488 489 490
};


class Item_func_from_days :public Item_date
{
public:
  Item_func_from_days(Item *a) :Item_date(a) {}
  const char *func_name() const { return "from_days"; }
491
  bool get_date(TIME *res, uint fuzzy_date);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
492 493 494 495 496 497
};


class Item_func_date_format :public Item_str_func
{
  int fixed_length;
498
  const bool is_time_format;
499
  String value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
500
public:
501 502
  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) {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
503 504 505 506 507 508 509
  String *val_str(String *str);
  const char *func_name() const { return "date_format"; }
  void fix_length_and_dec();
  uint format_length(const String *format);
};


510
class Item_func_from_unixtime :public Item_date_func
bk@work.mysql.com's avatar
bk@work.mysql.com committed
511
{
512
  THD *thd;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
513
 public:
514
  Item_func_from_unixtime(Item *a) :Item_date_func(a) {}
515 516 517 518 519
  double val()
  {
    DBUG_ASSERT(fixed == 1);
    return (double) Item_func_from_unixtime::val_int();
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
520 521 522
  longlong val_int();
  String *val_str(String *str);
  const char *func_name() const { return "from_unixtime"; }
523 524 525 526 527 528 529 530 531 532 533
  void fix_length_and_dec();
  bool get_date(TIME *res, uint fuzzy_date);
};


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

534 535 536 537 538 539 540 541
/*
  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.
*/
542 543
class Item_func_convert_tz :public Item_date_func
{
544 545 546 547
  /* Cached pointer to list of pre-opened time zone tables. */
  TABLE_LIST *tz_tables;
  /*
    If time zone parameters are constants we are caching objects that
548 549 550
    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.
551
  */
552
  bool from_tz_cached, to_tz_cached;
553 554 555
  Time_zone *from_tz, *to_tz;
 public:
  Item_func_convert_tz(Item *a, Item *b, Item *c):
556
    Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
557 558 559 560
  longlong val_int();
  double val() { return (double) val_int(); }
  String *val_str(String *str);
  const char *func_name() const { return "convert_tz"; }
561
  bool fix_fields(THD *, struct st_table_list *, Item **);
562
  void fix_length_and_dec();
563
  bool get_date(TIME *res, uint fuzzy_date);
564
  void cleanup();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
565 566 567 568 569 570 571
};


class Item_func_sec_to_time :public Item_str_func
{
public:
  Item_func_sec_to_time(Item *item) :Item_str_func(item) {}
572 573 574 575 576
  double val()
  {
    DBUG_ASSERT(fixed == 1);
    return (double) Item_func_sec_to_time::val_int();
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
577 578
  longlong val_int();
  String *val_str(String *);
579 580
  void fix_length_and_dec()
  { 
581
    collation.set(&my_charset_bin);
582
    maybe_null=1;
583
    max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
584
  }
585
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
586
  const char *func_name() const { return "sec_to_time"; }
587 588
  Field *tmp_table_field(TABLE *t_arg)
  {
589
    return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
590
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
591 592
};

593 594 595 596 597 598 599 600
/*
  The following must be sorted so that simple intervals comes first.
  (get_interval_value() depends on this)
*/

enum interval_type
{
  INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE,
601 602 603 604 605
  INTERVAL_SECOND, INTERVAL_MICROSECOND ,INTERVAL_YEAR_MONTH,
  INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND,
  INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND,
  INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
  INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND
606
};
607

608
class Item_date_add_interval :public Item_date_func
bk@work.mysql.com's avatar
bk@work.mysql.com committed
609 610 611 612
{
  const interval_type int_type;
  String value;
  const bool date_sub_interval;
613
  enum_field_types cached_field_type;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
614 615 616

public:
  Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
617
    :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
618 619
  String *val_str(String *);
  const char *func_name() const { return "date_add_interval"; }
620 621
  void fix_length_and_dec();
  enum_field_types field_type() const { return cached_field_type; }
622
  double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
623
  longlong val_int();
624
  bool get_date(TIME *res, uint fuzzy_date);
625
  void print(String *str);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
626 627
};

628

bk@work.mysql.com's avatar
bk@work.mysql.com committed
629 630 631 632 633 634 635 636 637 638 639
class Item_extract :public Item_int_func
{
  const interval_type int_type;
  String value;
  bool date_value;
 public:
  Item_extract(interval_type type_arg, Item *a)
    :Item_int_func(a), int_type(type_arg) {}
  longlong val_int();
  const char *func_name() const { return "extract"; }
  void fix_length_and_dec();
hf@deer.(none)'s avatar
hf@deer.(none) committed
640
  bool eq(const Item *item, bool binary_cmp) const;
641
  void print(String *str);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
642
};
643

644

monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
645
class Item_typecast :public Item_str_func
646 647
{
public:
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
648
  Item_typecast(Item *a) :Item_str_func(a) {}
649
  String *val_str(String *a)
650
  {
651
    DBUG_ASSERT(fixed == 1);
652 653
    String *tmp=args[0]->val_str(a);
    null_value=args[0]->null_value;
654
    if (tmp)
655
      tmp->set_charset(collation.collation);
656 657 658 659
    return tmp;
  }
  void fix_length_and_dec()
  {
660
    collation.set(&my_charset_bin);
661 662
    max_length=args[0]->max_length;
  }
663
  virtual const char* cast_type() const= 0;
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
664 665 666 667
  void print(String *str);
};


668 669 670 671 672 673 674 675 676 677 678 679 680
class Item_typecast_maybe_null :public Item_typecast
{
public:
  Item_typecast_maybe_null(Item *a) :Item_typecast(a) {}
  void fix_length_and_dec()
  {
    collation.set(&my_charset_bin);
    max_length=args[0]->max_length;
    maybe_null= 1;
  }
};


681 682
class Item_char_typecast :public Item_typecast
{
683 684 685 686 687 688 689
  int cast_length;
  CHARSET_INFO *cast_cs;
  bool charset_conversion;
  String tmp_value;
public:
  Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
    :Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
690 691
  bool eq(const Item *item, bool binary_cmp) const;
  const char *func_name() const { return "cast_as_char"; }
692
  const char* cast_type() const { return "char"; };
693 694
  String *val_str(String *a);
  void fix_length_and_dec();
695
  void print(String *str);
696 697 698
};


699
class Item_date_typecast :public Item_typecast_maybe_null
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
700 701
{
public:
702
  Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
703
  const char *func_name() const { return "cast_as_date"; }
704
  String *val_str(String *str);
705
  bool get_date(TIME *ltime, uint fuzzy_date);
706
  const char *cast_type() const { return "date"; }
707
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
708 709
  Field *tmp_table_field(TABLE *t_arg)
  {
710
    return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
711 712 713
  }  
};

714

715
class Item_time_typecast :public Item_typecast_maybe_null
716 717
{
public:
718
  Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
719
  const char *func_name() const { return "cast_as_time"; }
720 721
  String *val_str(String *str);
  bool get_time(TIME *ltime);
722
  const char *cast_type() const { return "time"; }
723
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
724 725
  Field *tmp_table_field(TABLE *t_arg)
  {
726
    return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
727
  }
728 729
};

730

731
class Item_datetime_typecast :public Item_typecast_maybe_null
732 733
{
public:
734
  Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {}
735
  const char *func_name() const { return "cast_as_datetime"; }
736
  String *val_str(String *str);
737
  const char *cast_type() const { return "datetime"; }
738
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
739 740
  Field *tmp_table_field(TABLE *t_arg)
  {
741
    return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
742
  }
743
};
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
744 745 746 747 748 749 750 751 752 753 754

class Item_func_makedate :public Item_str_func
{
public:
  Item_func_makedate(Item *a,Item *b) :Item_str_func(a,b) {}
  String *val_str(String *str);
  const char *func_name() const { return "makedate"; }
  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
  void fix_length_and_dec()
  { 
    decimals=0;
755
    max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
756 757 758 759 760 761 762
  }
  Field *tmp_table_field(TABLE *t_arg)
  {
    return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
  }
};

763

gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
764 765
class Item_func_add_time :public Item_str_func
{
766
  const bool is_date;
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
767 768 769 770
  int sign;
  enum_field_types cached_field_type;

public:
771 772
  Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
    :Item_str_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
773 774 775
  String *val_str(String *str);
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
776 777 778 779 780 781

/*
  TODO:
       Change this when we support 
       microseconds in TIME/DATETIME
*/
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
782 783 784 785 786 787 788 789
  Field *tmp_table_field(TABLE *t_arg)
  {
    if (cached_field_type == MYSQL_TYPE_TIME)
      return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
    else if (cached_field_type == MYSQL_TYPE_DATETIME)
      return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
    return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
  }
790
  void print(String *str);
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
791 792 793 794 795 796 797 798 799 800 801 802 803
};

class Item_func_timediff :public Item_str_func
{
public:
  Item_func_timediff(Item *a, Item *b)
    :Item_str_func(a, b) {}
  String *val_str(String *str);
  const char *func_name() const { return "timediff"; }
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
  void fix_length_and_dec()
  {
    decimals=0;
804
    max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
  }
  Field *tmp_table_field(TABLE *t_arg)
  {
      return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
  }
};

class Item_func_maketime :public Item_str_func
{
public:
  Item_func_maketime(Item *a, Item *b, Item *c)
    :Item_str_func(a, b ,c) {}
  String *val_str(String *str);
  const char *func_name() const { return "maketime"; }
  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
  void fix_length_and_dec()
  {
    decimals=0;
823
    max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
824 825 826
  }
  Field *tmp_table_field(TABLE *t_arg)
  {
827
    return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
  }
};

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;
    maybe_null=1;
  }
};
843 844


845
enum date_time_format
846 847 848 849 850 851
{
  USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};

class Item_func_get_format :public Item_str_func
{
852
  const timestamp_type type;
853
public:
854 855 856
  Item_func_get_format(timestamp_type type_arg, Item *a)
    :Item_str_func(a), type(type_arg)
  {}
857 858 859 860
  String *val_str(String *str);
  const char *func_name() const { return "get_format"; }
  void fix_length_and_dec()
  {
861
    maybe_null= 1;
862 863 864
    decimals=0;
    max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
  }
865
  void print(String *str);
866 867 868
};


869
class Item_func_str_to_date :public Item_str_func
870
{
871 872 873 874
  enum_field_types cached_field_type;
  date_time_format_types cached_format_type;
  timestamp_type cached_timestamp_type;
  bool const_item;
875 876
public:
  Item_func_str_to_date(Item *a, Item *b)
877
    :Item_str_func(a, b)
878
  {}
879
  String *val_str(String *str);
880
  bool get_date(TIME *ltime, uint fuzzy_date);
881
  const char *func_name() const { return "str_to_date"; }
882 883 884
  enum_field_types field_type() const { return cached_field_type; }
  void fix_length_and_dec();
  Field *tmp_table_field(TABLE *t_arg);
885
};
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
886

887 888

class Item_func_last_day :public Item_date
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
889 890
{
public:
891
  Item_func_last_day(Item *a) :Item_date(a) {}
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
892
  const char *func_name() const { return "last_day"; }
893
  bool get_date(TIME *res, uint fuzzy_date);
gluh@gluh.mysql.r18.ru's avatar
gluh@gluh.mysql.r18.ru committed
894
};