MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_time.h
1 /* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #ifndef SQL_TIME_INCLUDED
17 #define SQL_TIME_INCLUDED
18 
19 #include "my_global.h" /* ulong */
20 #include "my_time.h"
21 #include "mysql_time.h" /* timestamp_type */
22 #include "sql_error.h" /* Sql_condition */
23 #include "structs.h" /* INTERVAL */
24 
25 typedef enum enum_mysql_timestamp_type timestamp_type;
28 
29 /* Flags for calc_week() function. */
30 #define WEEK_MONDAY_FIRST 1
31 #define WEEK_YEAR 2
32 #define WEEK_FIRST_WEEKDAY 4
33 
34 ulong convert_period_to_month(ulong period);
35 ulong convert_month_to_period(ulong month);
36 void mix_date_and_time(MYSQL_TIME *ldate, const MYSQL_TIME *ltime);
37 void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
38 my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist);
39 bool datetime_with_no_zero_in_date_to_timeval(THD *thd, const MYSQL_TIME *t,
40  struct timeval *tm,
41  int *warnings);
42 bool datetime_to_timeval(THD *thd, const MYSQL_TIME *t,
43  struct timeval *tm, int *warnings);
44 bool str_to_datetime_with_warn(String *str, MYSQL_TIME *l_time, uint flags);
45 bool my_decimal_to_datetime_with_warn(const my_decimal *decimal,
46  MYSQL_TIME *ltime, uint flags);
47 bool my_double_to_datetime_with_warn(double nr, MYSQL_TIME *ltime, uint flags);
48 bool my_longlong_to_datetime_with_warn(longlong nr,
49  MYSQL_TIME *ltime, uint flags);
50 bool my_decimal_to_time_with_warn(const my_decimal *decimal,
51  MYSQL_TIME *ltime);
52 bool my_double_to_time_with_warn(double nr, MYSQL_TIME *ltime);
53 bool my_longlong_to_time_with_warn(longlong nr, MYSQL_TIME *ltime);
54 bool str_to_time_with_warn(String *str, MYSQL_TIME *l_time);
55 void time_to_datetime(THD *thd, const MYSQL_TIME *tm, MYSQL_TIME *dt);
56 inline void datetime_to_time(MYSQL_TIME *ltime)
57 {
58  ltime->year= ltime->month= ltime->day= 0;
59  ltime->time_type= MYSQL_TIMESTAMP_TIME;
60 }
61 inline void datetime_to_date(MYSQL_TIME *ltime)
62 {
63  ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
64  ltime->time_type= MYSQL_TIMESTAMP_DATE;
65 }
66 inline void date_to_datetime(MYSQL_TIME *ltime)
67 {
68  ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
69 }
70 void make_truncated_value_warning(THD *thd,
71  Sql_condition::enum_warning_level level,
72  ErrConvString val,
73  timestamp_type time_type,
74  const char *field_name);
75 inline void make_truncated_value_warning(ErrConvString val,
76  timestamp_type time_type)
77 {
78  make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
79  val, time_type, NullS);
80 }
81 extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
82  const char *format_str,
83  uint format_length);
84 extern DATE_TIME_FORMAT *date_time_format_copy(THD *thd,
85  DATE_TIME_FORMAT *format);
86 const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
87  timestamp_type type);
88 void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
89  String *str);
90 void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
91  String *str, uint dec);
92 void make_datetime(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
93  String *str, uint dec);
94 bool my_TIME_to_str(const MYSQL_TIME *ltime, String *str, uint dec);
95 
96 /* MYSQL_TIME operations */
97 bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
98  INTERVAL interval);
99 bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2,
100  int l_sign, longlong *seconds_out, long *microseconds_out);
101 int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
102 void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
103 void calc_time_from_sec(MYSQL_TIME *to, longlong seconds, long microseconds);
104 uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
105 
106 int calc_weekday(long daynr,bool sunday_first_day_of_week);
107 bool parse_date_time_format(timestamp_type format_type,
108  const char *format, uint format_length,
109  DATE_TIME_FORMAT *date_time_format);
110 /* Character set-aware version of str_to_time() */
111 bool str_to_time(const CHARSET_INFO *cs, const char *str, uint length,
112  MYSQL_TIME *l_time, uint flags, MYSQL_TIME_STATUS *status);
113 static inline bool
114 str_to_time(const String *str, MYSQL_TIME *ltime, uint flags,
115  MYSQL_TIME_STATUS *status)
116 {
117  return str_to_time(str->charset(), str->ptr(), str->length(),
118  ltime, flags, status);
119 }
120 
121 bool time_add_nanoseconds_with_round(MYSQL_TIME *ltime, uint nanoseconds,
122  int *warnings);
123 /* Character set-aware version of str_to_datetime() */
124 bool str_to_datetime(const CHARSET_INFO *cs,
125  const char *str, uint length,
126  MYSQL_TIME *l_time, uint flags,
127  MYSQL_TIME_STATUS *status);
128 static inline bool
129 str_to_datetime(const String *str, MYSQL_TIME *ltime, uint flags,
130  MYSQL_TIME_STATUS *status)
131 {
132  return str_to_datetime(str->charset(), str->ptr(), str->length(),
133  ltime, flags, status);
134 }
135 
136 bool datetime_add_nanoseconds_with_round(MYSQL_TIME *ltime,
137  uint nanoseconds, int *warnings);
138 
139 /* convenience wrapper */
140 inline bool parse_date_time_format(timestamp_type format_type,
141  DATE_TIME_FORMAT *date_time_format)
142 {
143  return parse_date_time_format(format_type,
144  date_time_format->format.str,
145  date_time_format->format.length,
146  date_time_format);
147 }
148 
149 
150 extern DATE_TIME_FORMAT global_date_format;
151 extern DATE_TIME_FORMAT global_datetime_format;
152 extern DATE_TIME_FORMAT global_time_format;
153 extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
154 extern LEX_STRING interval_type_to_name[];
155 
156 /* Date/time rounding and truncation functions */
157 inline long my_time_fraction_remainder(long nr, uint decimals)
158 {
159  DBUG_ASSERT(decimals <= DATETIME_MAX_DECIMALS);
160  return nr % (long) log_10_int[DATETIME_MAX_DECIMALS - decimals];
161 }
162 inline void my_time_trunc(MYSQL_TIME *ltime, uint decimals)
163 {
164  ltime->second_part-= my_time_fraction_remainder(ltime->second_part, decimals);
165 }
166 inline void my_datetime_trunc(MYSQL_TIME *ltime, uint decimals)
167 {
168  return my_time_trunc(ltime, decimals);
169 }
170 inline void my_timeval_trunc(struct timeval *tv, uint decimals)
171 {
172  tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals);
173 }
174 bool my_time_round(MYSQL_TIME *ltime, uint decimals);
175 bool my_datetime_round(MYSQL_TIME *ltime, uint decimals, int *warnings);
176 bool my_timeval_round(struct timeval *tv, uint decimals);
177 
178 
179 inline ulonglong TIME_to_ulonglong_datetime_round(const MYSQL_TIME *ltime)
180 {
181  // Catch simple cases
182  if (ltime->second_part < 500000)
183  return TIME_to_ulonglong_datetime(ltime);
184  if (ltime->second < 59)
185  return TIME_to_ulonglong_datetime(ltime) + 1;
186  // Corner case e.g. 'YYYY-MM-DD hh:mm:59.5'. Proceed with slower method.
187  int warnings= 0;
188  MYSQL_TIME tmp= *ltime;
189  my_datetime_round(&tmp, 0, &warnings);
190  return TIME_to_ulonglong_datetime(&tmp);// + TIME_microseconds_round(ltime);
191 }
192 
193 
194 inline ulonglong TIME_to_ulonglong_time_round(const MYSQL_TIME *ltime)
195 {
196  if (ltime->second_part < 500000)
197  return TIME_to_ulonglong_time(ltime);
198  if (ltime->second < 59)
199  return TIME_to_ulonglong_time(ltime) + 1;
200  // Corner case e.g. 'hh:mm:59.5'. Proceed with slower method.
201  MYSQL_TIME tmp= *ltime;
202  my_time_round(&tmp, 0);
203  return TIME_to_ulonglong_time(&tmp);
204 }
205 
206 
207 inline ulonglong TIME_to_ulonglong_round(const MYSQL_TIME *ltime)
208 {
209  switch (ltime->time_type)
210  {
211  case MYSQL_TIMESTAMP_TIME:
212  return TIME_to_ulonglong_time_round(ltime);
213  case MYSQL_TIMESTAMP_DATETIME:
214  return TIME_to_ulonglong_datetime_round(ltime);
215  case MYSQL_TIMESTAMP_DATE:
216  return TIME_to_ulonglong_date(ltime);
217  default:
218  DBUG_ASSERT(0);
219  return 0;
220  }
221 }
222 
223 
224 inline double TIME_microseconds(const MYSQL_TIME *ltime)
225 {
226  return (double) ltime->second_part / 1000000;
227 }
228 
229 inline double TIME_to_double_datetime(const MYSQL_TIME *ltime)
230 {
231  return (double) TIME_to_ulonglong_datetime(ltime) + TIME_microseconds(ltime);
232 }
233 
234 
235 inline double TIME_to_double_time(const MYSQL_TIME *ltime)
236 {
237  return (double) TIME_to_ulonglong_time(ltime) + TIME_microseconds(ltime);
238 }
239 
240 
241 inline double TIME_to_double(const MYSQL_TIME *ltime)
242 {
243  return (double) TIME_to_ulonglong(ltime) + TIME_microseconds(ltime);
244 }
245 
246 
247 static inline bool
248 check_fuzzy_date(const MYSQL_TIME *ltime, uint fuzzydate)
249 {
250  return !(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day);
251 }
252 
253 static inline bool
254 non_zero_date(const MYSQL_TIME *ltime)
255 {
256  return ltime->year || ltime->month || ltime->day;
257 }
258 
259 static inline bool
260 non_zero_time(const MYSQL_TIME *ltime)
261 {
262  return ltime->hour || ltime->minute || ltime->second || ltime->second_part;
263 }
264 
265 longlong TIME_to_longlong_packed(const MYSQL_TIME *tm,
266  enum enum_field_types type);
267 void TIME_from_longlong_packed(MYSQL_TIME *ltime,
268  enum enum_field_types type,
269  longlong packed_value);
270 my_decimal *my_decimal_from_datetime_packed(my_decimal *dec,
271  enum enum_field_types type,
272  longlong packed_value);
273 
274 longlong longlong_from_datetime_packed(enum enum_field_types type,
275  longlong packed_value);
276 
277 double double_from_datetime_packed(enum enum_field_types type,
278  longlong packed_value);
279 
280 static inline
281 timestamp_type field_type_to_timestamp_type(enum enum_field_types type)
282 {
283  switch (type)
284  {
285  case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
286  case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
287  case MYSQL_TYPE_TIMESTAMP:
288  case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
289  default: return MYSQL_TIMESTAMP_NONE;
290  }
291 }
292 #endif /* SQL_TIME_INCLUDED */