24
24
Move month and days to language files
26
#include <drizzled/server_includes.h>
27
#ifdef USE_PRAGMA_IMPLEMENTATION
28
#pragma implementation // gcc: Class implementation
31
#include "mysql_priv.h"
28
#include <drizzled/drizzled_error_messages.h>
30
35
/** Day number for Dec 31st, 9999. */
31
36
#define MAX_DAY_NUMBER 3652424L
48
53
the microseconds twice.
51
static bool make_datetime(date_time_format_types format, DRIZZLE_TIME *ltime,
56
static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
55
const CHARSET_INFO * const cs= &my_charset_bin;
56
uint32_t length= MAX_DATE_STRING_REP_LENGTH;
60
CHARSET_INFO *cs= &my_charset_bin;
61
uint length= MAX_DATE_STRING_REP_LENGTH;
58
63
if (str->alloc(length))
122
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
127
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
123
128
str->ptr(), str->length(),
124
DRIZZLE_TIMESTAMP_TIME, NULL);
129
MYSQL_TIMESTAMP_TIME, NullS);
125
130
return make_datetime(format, ltime, str);
130
Wrapper over make_time() with validation of the input DRIZZLE_TIME value
135
Wrapper over make_time() with validation of the input MYSQL_TIME value
133
138
see make_time() for more info
140
145
static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
141
DRIZZLE_TIME *l_time, String *str)
146
MYSQL_TIME *l_time, String *str)
144
149
make_time(format, l_time, str);
149
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
154
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
150
155
str->ptr(), str->length(),
151
DRIZZLE_TIMESTAMP_TIME, NULL);
156
MYSQL_TIMESTAMP_TIME, NullS);
152
157
make_time(format, l_time, str);
160
Convert seconds to DRIZZLE_TIME value with overflow checking
165
Convert seconds to MYSQL_TIME value with overflow checking
164
169
seconds number of seconds
165
170
unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
166
ltime output DRIZZLE_TIME value
171
ltime output MYSQL_TIME value
169
If the 'seconds' argument is inside DRIZZLE_TIME data range, convert it to a
174
If the 'seconds' argument is inside MYSQL_TIME data range, convert it to a
170
175
corresponding value.
171
176
Otherwise, truncate the resulting value to the nearest endpoint, and
172
177
produce a warning message.
179
static bool sec_to_time(int64_t seconds, bool unsigned_flag, DRIZZLE_TIME *ltime)
184
static bool sec_to_time(int64_t seconds, bool unsigned_flag, MYSQL_TIME *ltime)
183
memset(ltime, 0, sizeof(*ltime));
188
bzero((char *)ltime, sizeof(*ltime));
188
195
if (seconds < -3020399)
208
215
int len= (int)(int64_t10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
210
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
211
buf, len, DRIZZLE_TIMESTAMP_TIME,
217
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
218
buf, len, MYSQL_TIMESTAMP_TIME,
227
234
{(char *)"%H:%i:%S", 8}};
230
Extract datetime value to DRIZZLE_TIME struct from string value
237
Extract datetime value to MYSQL_TIME struct from string value
231
238
according to format string.
233
240
@param format date/time format specification
262
269
static bool extract_date_time(DATE_TIME_FORMAT *format,
263
const char *val, uint32_t length, DRIZZLE_TIME *l_time,
264
enum enum_drizzle_timestamp_type cached_timestamp_type,
270
const char *val, uint length, MYSQL_TIME *l_time,
271
timestamp_type cached_timestamp_type,
265
272
const char **sub_pattern_end,
266
273
const char *date_time_type)
278
285
const char *val_end= val + length;
279
286
const char *ptr= format->format.str;
280
287
const char *end= ptr + format->format.length;
281
const CHARSET_INFO * const cs= &my_charset_bin;
288
CHARSET_INFO *cs= &my_charset_bin;
283
290
if (!sub_pattern_end)
284
memset(l_time, 0, sizeof(*l_time));
291
bzero((char*) l_time, sizeof(*l_time));
286
293
for (; ptr != end && val != val_end; ptr++)
300
307
switch (*++ptr) {
303
tmp= (char*) val + cmin(4, val_len);
310
tmp= (char*) val + min(4, val_len);
304
311
l_time->year= (int) my_strtoll10(val, &tmp, &error);
305
312
if ((int) (tmp-val) <= 2)
306
313
l_time->year= year_2000_handling(l_time->year);
310
tmp= (char*) val + cmin(2, val_len);
317
tmp= (char*) val + min(2, val_len);
311
318
l_time->year= (int) my_strtoll10(val, &tmp, &error);
313
320
l_time->year= year_2000_handling(l_time->year);
319
tmp= (char*) val + cmin(2, val_len);
326
tmp= (char*) val + min(2, val_len);
320
327
l_time->month= (int) my_strtoll10(val, &tmp, &error);
336
tmp= (char*) val + cmin(2, val_len);
343
tmp= (char*) val + min(2, val_len);
337
344
l_time->day= (int) my_strtoll10(val, &tmp, &error);
341
tmp= (char*) val + cmin(2, val_len);
348
tmp= (char*) val + min(2, val_len);
342
349
l_time->day= (int) my_strtoll10(val, &tmp, &error);
343
350
/* Skip 'st, 'nd, 'th .. */
344
val= tmp + cmin((int) (val_end-tmp), 2);
351
val= tmp + min((int) (val_end-tmp), 2);
352
359
/* fall through */
355
tmp= (char*) val + cmin(2, val_len);
362
tmp= (char*) val + min(2, val_len);
356
363
l_time->hour= (int) my_strtoll10(val, &tmp, &error);
362
tmp= (char*) val + cmin(2, val_len);
369
tmp= (char*) val + min(2, val_len);
363
370
l_time->minute= (int) my_strtoll10(val, &tmp, &error);
370
tmp= (char*) val + cmin(2, val_len);
377
tmp= (char*) val + min(2, val_len);
371
378
l_time->second= (int) my_strtoll10(val, &tmp, &error);
389
396
if (val_len < 2 || ! usa_time)
391
if (!my_strnncoll(&my_charset_utf8_general_ci,
392
(const unsigned char *) val, 2,
393
(const unsigned char *) "PM", 2))
398
if (!my_strnncoll(&my_charset_latin1,
399
(const uchar *) val, 2,
400
(const uchar *) "PM", 2))
395
else if (my_strnncoll(&my_charset_utf8_general_ci,
396
(const unsigned char *) val, 2,
397
(const unsigned char *) "AM", 2))
402
else if (my_strnncoll(&my_charset_latin1,
403
(const uchar *) val, 2,
404
(const uchar *) "AM", 2))
422
tmp= (char*) val + cmin(val_len, 3);
429
tmp= (char*) val + min(val_len, 3);
423
430
yearday= (int) my_strtoll10(val, &tmp, &error);
432
439
sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
433
440
strict_week_number= (*ptr=='V' || *ptr=='v');
434
tmp= (char*) val + cmin(val_len, 2);
441
tmp= (char*) val + min(val_len, 2);
435
442
if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
436
443
(strict_week_number && !week_number) ||
437
444
week_number > 53)
445
452
strict_week_number_year_type= (*ptr=='X');
446
tmp= (char*) val + cmin(4, val_len);
453
tmp= (char*) val + min(4, val_len);
447
454
strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
576
if (!my_isspace(&my_charset_utf8_general_ci,*val))
583
if (!my_isspace(&my_charset_latin1,*val))
578
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
585
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
579
586
val_begin, length,
580
cached_timestamp_type, NULL);
587
cached_timestamp_type, NullS);
583
590
} while (++val != val_end);
590
strmake(buff, val_begin, cmin(length, (uint)sizeof(buff)-1));
591
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
597
strmake(buff, val_begin, min(length, sizeof(buff)-1));
598
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
592
599
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
593
600
date_time_type, buff, "str_to_date");
600
607
Create a formated date/time value in a string.
603
bool make_date_time(DATE_TIME_FORMAT *format, DRIZZLE_TIME *l_time,
604
enum enum_drizzle_timestamp_type type, String *str)
610
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
611
timestamp_type type, String *str)
606
613
char intbuff[15];
610
617
const char *ptr, *end;
611
618
THD *thd= current_thd;
657
664
system_charset_info);
660
if (type == DRIZZLE_TIMESTAMP_TIME)
667
if (type == MYSQL_TIMESTAMP_TIME)
662
669
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
663
670
str->append_with_prefill(intbuff, length, 1, '0');
724
731
str->append_with_prefill(intbuff, length, 2, '0');
727
if (type == DRIZZLE_TIMESTAMP_TIME)
734
if (type == MYSQL_TIMESTAMP_TIME)
729
736
length= int10_to_str(calc_daynr(l_time->year,l_time->month,
848
855
For example, '1.1' -> '1.100000'
851
static bool get_interval_info(const char *str,uint32_t length, const CHARSET_INFO * const cs,
852
uint32_t count, uint64_t *values,
858
static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
859
uint count, uint64_t *values,
853
860
bool transform_msec)
855
862
const char *end=str+length;
857
864
while (str != end && !my_isdigit(cs,*str))
863
870
const char *start= str;
864
871
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
865
value= value * 10L + (int64_t) (*str - '0');
872
value= value * 10LL + (int64_t) (*str - '0');
866
873
if (transform_msec && i == count - 1) // microseconds always last
868
875
long msec_length= 6 - (str - start);
878
885
/* Change values[0...i-1] -> values[0...count-1] */
879
bmove_upp((unsigned char*) (values+count), (unsigned char*) (values+i),
886
bmove_upp((uchar*) (values+count), (uchar*) (values+i),
880
887
sizeof(*values)*i);
881
memset(values, 0, sizeof(*values)*(count-i));
888
bzero((uchar*) values, sizeof(*values)*(count-i));
918
925
int64_t Item_func_to_days::val_int()
920
927
assert(fixed == 1);
922
929
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
924
931
return (int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
944
951
if (args[0]->type() == Item::FIELD_ITEM)
946
if (args[0]->field_type() == DRIZZLE_TYPE_NEWDATE)
953
if (args[0]->field_type() == MYSQL_TYPE_NEWDATE)
947
954
return MONOTONIC_STRICT_INCREASING;
948
if (args[0]->field_type() == DRIZZLE_TYPE_DATETIME)
955
if (args[0]->field_type() == MYSQL_TYPE_DATETIME)
949
956
return MONOTONIC_INCREASING;
951
958
return NON_MONOTONIC;
965
972
res=(int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
967
if (args[0]->field_type() == DRIZZLE_TYPE_NEWDATE)
974
if (args[0]->field_type() == MYSQL_TYPE_NEWDATE)
969
976
// TO_DAYS() is strictly monotonic for dates, leave incl_endp intact
993
1000
int64_t Item_func_dayofyear::val_int()
995
1002
assert(fixed == 1);
997
1004
if (get_arg0_date(<ime,TIME_NO_ZERO_DATE))
999
1006
return (int64_t) calc_daynr(ltime.year,ltime.month,ltime.day) -
1071
1078
int64_t Item_func_second::val_int()
1073
1080
assert(fixed == 1);
1075
1082
(void) get_arg0_time(<ime);
1076
1083
return ltime.second;
1080
uint32_t week_mode(uint32_t mode)
1087
uint week_mode(uint mode)
1082
uint32_t week_format= (mode & 7);
1089
uint week_format= (mode & 7);
1083
1090
if (!(week_format & WEEK_MONDAY_FIRST))
1084
1091
week_format^= WEEK_FIRST_WEEKDAY;
1085
1092
return week_format;
1199
1206
enum_monotonicity_info Item_func_year::get_monotonicity_info() const
1201
1208
if (args[0]->type() == Item::FIELD_ITEM &&
1202
(args[0]->field_type() == DRIZZLE_TYPE_NEWDATE ||
1203
args[0]->field_type() == DRIZZLE_TYPE_DATETIME))
1209
(args[0]->field_type() == MYSQL_TYPE_NEWDATE ||
1210
args[0]->field_type() == MYSQL_TYPE_DATETIME))
1204
1211
return MONOTONIC_INCREASING;
1205
1212
return NON_MONOTONIC;
1209
1216
int64_t Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
1211
1218
assert(fixed == 1);
1213
1220
if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1215
1222
/* got NULL, leave the incl_endp intact */
1247
1254
if (args[0]->type() == FIELD_ITEM)
1248
1255
{ // Optimize timestamp field
1249
1256
Field *field=((Item_field*) args[0])->field;
1250
if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
1257
if (field->type() == MYSQL_TYPE_TIMESTAMP)
1251
1258
return ((Field_timestamp*) field)->get_timestamp(&null_value);
1290
1297
int64_t value= 0;
1291
1298
const char *str= NULL;
1292
1299
size_t length= 0;
1293
const CHARSET_INFO * const cs= str_value->charset();
1300
CHARSET_INFO *cs=str_value->charset();
1295
memset(interval, 0, sizeof(*interval));
1302
bzero((char*) interval,sizeof(*interval));
1296
1303
if ((int) int_type <= INTERVAL_MICROSECOND)
1298
1305
value= args->val_int();
1454
1461
int64_t Item_date::val_int()
1456
1463
assert(fixed == 1);
1458
1465
if (get_date(<ime, TIME_FUZZY_DATE))
1460
1467
return (int64_t) (ltime.year*10000L+ltime.month*100+ltime.day);
1464
bool Item_func_from_days::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
1471
bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date __attribute__((__unused__)))
1466
1473
int64_t value=args[0]->val_int();
1467
1474
if ((null_value=args[0]->null_value))
1469
memset(ltime, 0, sizeof(DRIZZLE_TIME));
1476
bzero(ltime, sizeof(MYSQL_TIME));
1470
1477
get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day);
1471
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
1478
ltime->time_type= MYSQL_TIMESTAMP_DATE;
1484
1491
/* We don't need to set second_part and neg because they already 0 */
1485
1492
ltime.hour= ltime.minute= ltime.second= 0;
1486
ltime.time_type= DRIZZLE_TIMESTAMP_DATE;
1493
ltime.time_type= MYSQL_TIMESTAMP_DATE;
1487
1494
value= (int64_t) TIME_to_uint64_t_date(<ime);
1503
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1510
Converts current time in my_time_t to MYSQL_TIME represenatation for local
1504
1511
time zone. Defines time zone (local) used for whole CURDATE function.
1506
void Item_func_curdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1513
void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
1508
1515
THD *thd= current_thd;
1509
1516
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1516
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1523
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
1517
1524
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
1519
void Item_func_curdate_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1526
void Item_func_curdate_utc::store_now_in_TIME(MYSQL_TIME *now_time)
1521
1528
my_tz_UTC->gmt_sec_to_TIME(now_time,
1522
1529
(my_time_t)(current_thd->query_start()));
1530
bool Item_func_curdate::get_date(DRIZZLE_TIME *res,
1531
uint32_t fuzzy_date __attribute__((unused)))
1537
bool Item_func_curdate::get_date(MYSQL_TIME *res,
1538
uint fuzzy_date __attribute__((unused)))
1538
String *Item_func_curtime::val_str(String *str __attribute__((unused)))
1545
String *Item_func_curtime::val_str(String *str __attribute__((__unused__)))
1540
1547
assert(fixed == 1);
1541
1548
str_value.set(buff, buff_length, &my_charset_bin);
1560
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1567
Converts current time in my_time_t to MYSQL_TIME represenatation for local
1561
1568
time zone. Defines time zone (local) used for whole CURTIME function.
1563
void Item_func_curtime_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1570
void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
1565
1572
THD *thd= current_thd;
1566
1573
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1573
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1580
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
1574
1581
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
1576
void Item_func_curtime_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1583
void Item_func_curtime_utc::store_now_in_TIME(MYSQL_TIME *now_time)
1578
1585
my_tz_UTC->gmt_sec_to_TIME(now_time,
1579
1586
(my_time_t)(current_thd->query_start()));
1609
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1616
Converts current time in my_time_t to MYSQL_TIME represenatation for local
1610
1617
time zone. Defines time zone (local) used for whole NOW function.
1612
void Item_func_now_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1619
void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
1614
1621
THD *thd= current_thd;
1615
1622
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1622
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1629
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
1623
1630
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
1625
void Item_func_now_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1632
void Item_func_now_utc::store_now_in_TIME(MYSQL_TIME *now_time)
1627
1634
my_tz_UTC->gmt_sec_to_TIME(now_time,
1628
1635
(my_time_t)(current_thd->query_start()));
1636
bool Item_func_now::get_date(DRIZZLE_TIME *res,
1637
uint32_t fuzzy_date __attribute__((unused)))
1643
bool Item_func_now::get_date(MYSQL_TIME *res,
1644
uint fuzzy_date __attribute__((unused)))
1644
int Item_func_now::save_in_field(Field *to, bool no_conversions __attribute__((unused)))
1651
int Item_func_now::save_in_field(Field *to, bool no_conversions __attribute__((__unused__)))
1646
1653
to->set_notnull();
1647
return to->store_time(<ime, DRIZZLE_TIMESTAMP_DATETIME);
1654
return to->store_time(<ime, MYSQL_TIMESTAMP_DATETIME);
1652
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1659
Converts current time in my_time_t to MYSQL_TIME represenatation for local
1653
1660
time zone. Defines time zone (local) used for whole SYSDATE function.
1655
void Item_func_sysdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1662
void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
1657
1664
THD *thd= current_thd;
1658
1665
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
1697
bool Item_func_sysdate_local::get_date(DRIZZLE_TIME *res,
1698
uint32_t fuzzy_date __attribute__((unused)))
1704
bool Item_func_sysdate_local::get_date(MYSQL_TIME *res,
1705
uint fuzzy_date __attribute__((unused)))
1700
1707
store_now_in_TIME(<ime);
1706
int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions __attribute__((unused)))
1713
int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions __attribute__((__unused__)))
1708
1715
store_now_in_TIME(<ime);
1709
1716
to->set_notnull();
1710
to->store_time(<ime, DRIZZLE_TIMESTAMP_DATETIME);
1717
to->store_time(<ime, MYSQL_TIMESTAMP_DATETIME);
1758
1765
Item *arg1= args[1]->this_item();
1761
const CHARSET_INFO * const cs= thd->variables.collation_connection;
1762
uint32_t repertoire= arg1->collation.repertoire;
1768
CHARSET_INFO *cs= thd->variables.collation_connection;
1769
uint32 repertoire= arg1->collation.repertoire;
1763
1770
if (!thd->variables.lc_time_names->is_ascii)
1764
1771
repertoire|= MY_REPERTOIRE_EXTENDED;
1765
1772
collation.set(cs, arg1->collation.derivation, repertoire);
1774
1781
fixed_length=0;
1775
max_length=cmin(arg1->max_length,(uint32_t) MAX_BLOB_WIDTH) * 10 *
1782
max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
1776
1783
collation.collation->mbmaxlen;
1777
1784
set_if_smaller(max_length,MAX_BLOB_WIDTH);
1924
1931
/* Create the result string */
1925
1932
str->set_charset(collation.collation);
1926
1933
if (!make_date_time(&date_time_format, &l_time,
1927
is_time_format ? DRIZZLE_TIMESTAMP_TIME :
1928
DRIZZLE_TIMESTAMP_DATE,
1934
is_time_format ? MYSQL_TIMESTAMP_TIME :
1935
MYSQL_TIMESTAMP_DATE,
1979
1986
return (int64_t) TIME_to_uint64_t_datetime(&time_tmp);
1982
bool Item_func_from_unixtime::get_date(DRIZZLE_TIME *ltime,
1983
uint32_t fuzzy_date __attribute__((unused)))
1989
bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
1990
uint fuzzy_date __attribute__((unused)))
1985
1992
uint64_t tmp= (uint64_t)(args[0]->val_int());
2009
2016
The field type for the result of an Item_date function is defined as
2012
- If first arg is a DRIZZLE_TYPE_DATETIME result is DRIZZLE_TYPE_DATETIME
2013
- If first arg is a DRIZZLE_TYPE_NEWDATE and the interval type uses hours,
2014
minutes or seconds then type is DRIZZLE_TYPE_DATETIME.
2015
- Otherwise the result is DRIZZLE_TYPE_VARCHAR
2016
(This is because you can't know if the string contains a DATE, DRIZZLE_TIME or
2019
- If first arg is a MYSQL_TYPE_DATETIME result is MYSQL_TYPE_DATETIME
2020
- If first arg is a MYSQL_TYPE_NEWDATE and the interval type uses hours,
2021
minutes or seconds then type is MYSQL_TYPE_DATETIME.
2022
- Otherwise the result is MYSQL_TYPE_STRING
2023
(This is because you can't know if the string contains a DATE, MYSQL_TIME or
2017
2024
DATETIME argument)
2019
cached_field_type= DRIZZLE_TYPE_VARCHAR;
2026
cached_field_type= MYSQL_TYPE_STRING;
2020
2027
arg0_field_type= args[0]->field_type();
2021
if (arg0_field_type == DRIZZLE_TYPE_DATETIME ||
2022
arg0_field_type == DRIZZLE_TYPE_TIMESTAMP)
2023
cached_field_type= DRIZZLE_TYPE_DATETIME;
2024
else if (arg0_field_type == DRIZZLE_TYPE_NEWDATE)
2028
if (arg0_field_type == MYSQL_TYPE_DATETIME ||
2029
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
2030
cached_field_type= MYSQL_TYPE_DATETIME;
2031
else if (arg0_field_type == MYSQL_TYPE_NEWDATE)
2026
2033
if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
2027
2034
cached_field_type= arg0_field_type;
2029
cached_field_type= DRIZZLE_TYPE_DATETIME;
2036
cached_field_type= MYSQL_TYPE_DATETIME;
2034
2041
/* Here arg[1] is a Item_interval object */
2036
bool Item_date_add_interval::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2043
bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date __attribute__((__unused__)))
2038
2045
INTERVAL interval;
2053
2060
String *Item_date_add_interval::val_str(String *str)
2055
2062
assert(fixed == 1);
2057
2064
enum date_time_format_types format;
2059
2066
if (Item_date_add_interval::get_date(<ime, TIME_NO_ZERO_DATE))
2062
if (ltime.time_type == DRIZZLE_TIMESTAMP_DATE)
2069
if (ltime.time_type == MYSQL_TIMESTAMP_DATE)
2063
2070
format= DATE_ONLY;
2064
2071
else if (ltime.second_part)
2065
2072
format= DATE_TIME_MICROSECOND;
2077
2084
int64_t Item_date_add_interval::val_int()
2079
2086
assert(fixed == 1);
2082
2089
if (Item_date_add_interval::get_date(<ime, TIME_NO_ZERO_DATE))
2083
2090
return (int64_t) 0;
2084
2091
date = (ltime.year*100L + ltime.month)*100L + ltime.day;
2085
return ltime.time_type == DRIZZLE_TIMESTAMP_DATE ? date :
2092
return ltime.time_type == MYSQL_TIMESTAMP_DATE ? date :
2086
2093
((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
2322
2329
// Convert character set if differ
2323
uint32_t dummy_errors;
2324
2331
if (!(res= args[0]->val_str(&tmp_value)) ||
2325
2332
str->copy(res->ptr(), res->length(), from_cs,
2326
2333
cast_cs, &dummy_errors))
2341
2348
if (cast_length >= 0)
2343
if (res->length() > (length= (uint32_t) res->charpos(cast_length)))
2350
if (res->length() > (length= (uint32) res->charpos(cast_length)))
2344
2351
{ // Safe even if const arg
2345
2352
char char_type[40];
2346
2353
snprintf(char_type, sizeof(char_type), "%s(%lu)",
2352
2359
str_value= *res; // Not malloced string
2353
2360
res= &str_value;
2355
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2362
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2356
2363
ER_TRUNCATED_WRONG_VALUE,
2357
2364
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
2358
2365
res->c_ptr_safe());
2366
2373
str->copy(*res);
2369
memset(res->ptr() + res->length(), 0,
2370
(uint) cast_length - res->length());
2376
bzero((char*) res->ptr() + res->length(),
2377
(uint) cast_length - res->length());
2371
2378
res->length(cast_length);
2404
2411
from_cs= (args[0]->result_type() == INT_RESULT ||
2405
2412
args[0]->result_type() == DECIMAL_RESULT ||
2406
2413
args[0]->result_type() == REAL_RESULT) ?
2407
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_utf8_general_ci) :
2414
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
2408
2415
args[0]->collation.collation;
2409
2416
charset_conversion= (cast_cs->mbmaxlen > 1) ||
2410
2417
(!my_charset_same(from_cs, cast_cs) && from_cs != &my_charset_bin && cast_cs != &my_charset_bin);
2447
bool Item_time_typecast::get_time(DRIZZLE_TIME *ltime)
2454
bool Item_time_typecast::get_time(MYSQL_TIME *ltime)
2449
2456
bool res= get_arg0_time(ltime);
2451
For DRIZZLE_TIMESTAMP_TIME value we can have non-zero day part,
2458
For MYSQL_TIMESTAMP_TIME value we can have non-zero day part,
2452
2459
which we should not lose.
2454
if (ltime->time_type == DRIZZLE_TIMESTAMP_DATETIME)
2461
if (ltime->time_type == MYSQL_TIMESTAMP_DATETIME)
2455
2462
ltime->year= ltime->month= ltime->day= 0;
2456
ltime->time_type= DRIZZLE_TIMESTAMP_TIME;
2463
ltime->time_type= MYSQL_TIMESTAMP_TIME;
2461
2468
int64_t Item_time_typecast::val_int()
2464
2471
if (get_time(<ime))
2487
bool Item_date_typecast::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2494
bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date __attribute__((__unused__)))
2489
2496
bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
2490
2497
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
2491
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
2498
ltime->time_type= MYSQL_TIMESTAMP_DATE;
2496
bool Item_date_typecast::get_time(DRIZZLE_TIME *ltime)
2503
bool Item_date_typecast::get_time(MYSQL_TIME *ltime)
2498
memset(ltime, 0, sizeof(DRIZZLE_TIME));
2505
bzero((char *)ltime, sizeof(MYSQL_TIME));
2499
2506
return args[0]->null_value;
2619
2626
The field type for the result of an Item_func_add_time function is defined
2622
- If first arg is a DRIZZLE_TYPE_DATETIME or DRIZZLE_TYPE_TIMESTAMP
2623
result is DRIZZLE_TYPE_DATETIME
2624
- If first arg is a DRIZZLE_TYPE_TIME result is DRIZZLE_TYPE_TIME
2625
- Otherwise the result is DRIZZLE_TYPE_VARCHAR
2629
- If first arg is a MYSQL_TYPE_DATETIME or MYSQL_TYPE_TIMESTAMP
2630
result is MYSQL_TYPE_DATETIME
2631
- If first arg is a MYSQL_TYPE_TIME result is MYSQL_TYPE_TIME
2632
- Otherwise the result is MYSQL_TYPE_STRING
2628
cached_field_type= DRIZZLE_TYPE_VARCHAR;
2635
cached_field_type= MYSQL_TYPE_STRING;
2629
2636
arg0_field_type= args[0]->field_type();
2630
if (arg0_field_type == DRIZZLE_TYPE_NEWDATE ||
2631
arg0_field_type == DRIZZLE_TYPE_DATETIME ||
2632
arg0_field_type == DRIZZLE_TYPE_TIMESTAMP)
2633
cached_field_type= DRIZZLE_TYPE_DATETIME;
2634
else if (arg0_field_type == DRIZZLE_TYPE_TIME)
2635
cached_field_type= DRIZZLE_TYPE_TIME;
2637
if (arg0_field_type == MYSQL_TYPE_NEWDATE ||
2638
arg0_field_type == MYSQL_TYPE_DATETIME ||
2639
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
2640
cached_field_type= MYSQL_TYPE_DATETIME;
2641
else if (arg0_field_type == MYSQL_TYPE_TIME)
2642
cached_field_type= MYSQL_TYPE_TIME;
2648
2655
String *Item_func_add_time::val_str(String *str)
2650
2657
assert(fixed == 1);
2651
DRIZZLE_TIME l_time1, l_time2, l_time3;
2658
MYSQL_TIME l_time1, l_time2, l_time3;
2652
2659
bool is_time= 0;
2653
2660
long days, microseconds;
2654
2661
int64_t seconds;
2660
2667
if (get_arg0_date(&l_time1, TIME_FUZZY_DATE) ||
2661
2668
args[1]->get_time(&l_time2) ||
2662
l_time1.time_type == DRIZZLE_TIMESTAMP_TIME ||
2663
l_time2.time_type != DRIZZLE_TIMESTAMP_TIME)
2669
l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
2670
l_time2.time_type != MYSQL_TIMESTAMP_TIME)
2664
2671
goto null_date;
2666
2673
else // ADDTIME function
2668
2675
if (args[0]->get_time(&l_time1) ||
2669
2676
args[1]->get_time(&l_time2) ||
2670
l_time2.time_type == DRIZZLE_TIMESTAMP_DATETIME)
2677
l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
2671
2678
goto null_date;
2672
is_time= (l_time1.time_type == DRIZZLE_TIMESTAMP_TIME);
2679
is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
2674
2681
if (l_time1.neg != l_time2.neg)
2675
2682
l_sign= -l_sign;
2677
memset(&l_time3, 0, sizeof(l_time3));
2684
bzero((char *)&l_time3, sizeof(l_time3));
2679
2686
l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
2680
2687
&seconds, µseconds);
2751
2758
int64_t seconds;
2752
2759
long microseconds;
2754
DRIZZLE_TIME l_time1 ,l_time2, l_time3;
2761
MYSQL_TIME l_time1 ,l_time2, l_time3;
2757
2764
if (args[0]->get_time(&l_time1) ||
2762
2769
if (l_time1.neg != l_time2.neg)
2763
2770
l_sign= -l_sign;
2765
memset(&l_time3, 0, sizeof(l_time3));
2772
bzero((char *)&l_time3, sizeof(l_time3));
2767
2774
l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign,
2768
2775
&seconds, µseconds);
2771
For DRIZZLE_TIMESTAMP_TIME only:
2778
For MYSQL_TIMESTAMP_TIME only:
2772
2779
If first argument was negative and diff between arguments
2773
2780
is non-zero we need to swap sign to get proper result.
2811
2818
str->alloc(MAX_DATE_STRING_REP_LENGTH))))
2814
memset(<ime, 0, sizeof(ltime));
2821
bzero((char *)<ime, sizeof(ltime));
2817
2824
/* Check for integer overflows */
2827
if (args[0]->unsigned_flag)
2821
2832
if (-hour > UINT_MAX || hour > UINT_MAX)
2836
2847
char *ptr= int64_t10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
2837
2848
int len = (int)(ptr - buf) +
2838
2849
sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second);
2839
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2840
buf, len, DRIZZLE_TIMESTAMP_TIME,
2850
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2851
buf, len, MYSQL_TIMESTAMP_TIME,
2844
2855
if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str))
2889
2900
int_type == INTERVAL_QUARTER ||
2890
2901
int_type == INTERVAL_MONTH)
2892
uint32_t year_beg, year_end, month_beg, month_end, day_beg, day_end;
2894
uint32_t second_beg, second_end, microsecond_beg, microsecond_end;
2903
uint year_beg, year_end, month_beg, month_end, day_beg, day_end;
2905
uint second_beg, second_end, microsecond_beg, microsecond_end;
3035
3046
(format_name= format->format_name);
3038
uint32_t format_name_len;
3049
uint format_name_len;
3039
3050
format_name_len= strlen(format_name);
3040
3051
if (val_len == format_name_len &&
3041
!my_strnncoll(&my_charset_utf8_general_ci,
3042
(const unsigned char *) val->ptr(), val_len,
3043
(const unsigned char *) format_name, val_len))
3052
!my_strnncoll(&my_charset_latin1,
3053
(const uchar *) val->ptr(), val_len,
3054
(const uchar *) format_name, val_len))
3045
3056
const char *format_str= get_date_time_format_str(format, type);
3046
3057
str->set(format_str, strlen(format_str), &my_charset_bin);
3059
3070
str->append('(');
3061
3072
switch (type) {
3062
case DRIZZLE_TIMESTAMP_DATE:
3073
case MYSQL_TIMESTAMP_DATE:
3063
3074
str->append(STRING_WITH_LEN("DATE, "));
3065
case DRIZZLE_TIMESTAMP_DATETIME:
3076
case MYSQL_TIMESTAMP_DATETIME:
3066
3077
str->append(STRING_WITH_LEN("DATETIME, "));
3068
case DRIZZLE_TIMESTAMP_TIME:
3079
case MYSQL_TIMESTAMP_TIME:
3069
3080
str->append(STRING_WITH_LEN("TIME, "));
3103
3114
static date_time_format_types
3104
get_date_time_result_type(const char *format, uint32_t length)
3115
get_date_time_result_type(const char *format, uint length)
3106
3117
const char *time_part_frms= "HISThiklrs";
3107
3118
const char *date_part_frms= "MVUXYWabcjmvuxyw";
3152
cached_field_type= DRIZZLE_TYPE_DATETIME;
3163
cached_field_type= MYSQL_TYPE_DATETIME;
3153
3164
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
3154
cached_timestamp_type= DRIZZLE_TIMESTAMP_NONE;
3165
cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
3155
3166
if ((const_item= args[1]->const_item()))
3157
3168
char format_buff[64];
3163
3174
format->length());
3164
3175
switch (cached_format_type) {
3165
3176
case DATE_ONLY:
3166
cached_timestamp_type= DRIZZLE_TIMESTAMP_DATE;
3167
cached_field_type= DRIZZLE_TYPE_NEWDATE;
3177
cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
3178
cached_field_type= MYSQL_TYPE_NEWDATE;
3168
3179
max_length= MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
3170
3181
case TIME_ONLY:
3171
3182
case TIME_MICROSECOND:
3172
cached_timestamp_type= DRIZZLE_TIMESTAMP_TIME;
3173
cached_field_type= DRIZZLE_TYPE_TIME;
3183
cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
3184
cached_field_type= MYSQL_TYPE_TIME;
3174
3185
max_length= MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
3177
cached_timestamp_type= DRIZZLE_TIMESTAMP_DATETIME;
3178
cached_field_type= DRIZZLE_TYPE_DATETIME;
3188
cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
3189
cached_field_type= MYSQL_TYPE_DATETIME;
3186
bool Item_func_str_to_date::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3197
bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
3188
3199
DATE_TIME_FORMAT date_time_format;
3189
3200
char val_buff[64], format_buff[64];
3196
3207
goto null_date;
3199
memset(ltime, 0, sizeof(*ltime));
3210
bzero((char*) ltime, sizeof(*ltime));
3200
3211
date_time_format.format.str= (char*) format->ptr();
3201
3212
date_time_format.format.length= format->length();
3202
3213
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
3204
3215
((fuzzy_date & TIME_NO_ZERO_DATE) &&
3205
3216
(ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
3206
3217
goto null_date;
3207
if (cached_timestamp_type == DRIZZLE_TIMESTAMP_TIME && ltime->day)
3218
if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day)
3210
3221
Day part for time type can be nonzero value and so
3240
bool Item_func_last_day::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3251
bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
3242
3253
if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
3243
3254
(ltime->month == 0))
3249
uint32_t month_idx= ltime->month-1;
3260
uint month_idx= ltime->month-1;
3250
3261
ltime->day= days_in_month[month_idx];
3251
3262
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
3252
3263
ltime->day= 29;
3253
3264
ltime->hour= ltime->minute= ltime->second= 0;
3254
3265
ltime->second_part= 0;
3255
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
3266
ltime->time_type= MYSQL_TIMESTAMP_DATE;