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