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