1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1
/* Copyright (C) 2000-2003 MySQL AB
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
30
26
#include <drizzled/server_includes.h>
32
#include <drizzled/error.h>
33
#include <drizzled/tztime.h>
28
#include <drizzled/drizzled_error_messages.h>
35
30
/** Day number for Dec 31st, 9999. */
36
31
#define MAX_DAY_NUMBER 3652424L
127
make_truncated_value_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
122
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
128
123
str->ptr(), str->length(),
129
DRIZZLE_TIMESTAMP_TIME, NULL);
124
DRIZZLE_TIMESTAMP_TIME, NullS);
130
125
return make_datetime(format, ltime, str);
154
make_truncated_value_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
149
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
155
150
str->ptr(), str->length(),
156
DRIZZLE_TIMESTAMP_TIME, NULL);
151
DRIZZLE_TIMESTAMP_TIME, NullS);
157
152
make_time(format, l_time, str);
213
210
int len= (int)(int64_t10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
215
make_truncated_value_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
212
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
216
213
buf, len, DRIZZLE_TIMESTAMP_TIME,
267
264
static bool extract_date_time(DATE_TIME_FORMAT *format,
268
const char *val, uint32_t length, DRIZZLE_TIME *l_time,
269
enum enum_drizzle_timestamp_type cached_timestamp_type,
265
const char *val, uint length, DRIZZLE_TIME *l_time,
266
timestamp_type cached_timestamp_type,
270
267
const char **sub_pattern_end,
271
268
const char *date_time_type)
305
302
switch (*++ptr) {
308
tmp= (char*) val + cmin(4, val_len);
305
tmp= (char*) val + min(4, val_len);
309
306
l_time->year= (int) my_strtoll10(val, &tmp, &error);
310
307
if ((int) (tmp-val) <= 2)
311
308
l_time->year= year_2000_handling(l_time->year);
315
tmp= (char*) val + cmin(2, val_len);
312
tmp= (char*) val + min(2, val_len);
316
313
l_time->year= (int) my_strtoll10(val, &tmp, &error);
318
315
l_time->year= year_2000_handling(l_time->year);
324
tmp= (char*) val + cmin(2, val_len);
321
tmp= (char*) val + min(2, val_len);
325
322
l_time->month= (int) my_strtoll10(val, &tmp, &error);
341
tmp= (char*) val + cmin(2, val_len);
338
tmp= (char*) val + min(2, val_len);
342
339
l_time->day= (int) my_strtoll10(val, &tmp, &error);
346
tmp= (char*) val + cmin(2, val_len);
343
tmp= (char*) val + min(2, val_len);
347
344
l_time->day= (int) my_strtoll10(val, &tmp, &error);
348
345
/* Skip 'st, 'nd, 'th .. */
349
val= tmp + cmin((int) (val_end-tmp), 2);
346
val= tmp + min((int) (val_end-tmp), 2);
357
354
/* fall through */
360
tmp= (char*) val + cmin(2, val_len);
357
tmp= (char*) val + min(2, val_len);
361
358
l_time->hour= (int) my_strtoll10(val, &tmp, &error);
367
tmp= (char*) val + cmin(2, val_len);
364
tmp= (char*) val + min(2, val_len);
368
365
l_time->minute= (int) my_strtoll10(val, &tmp, &error);
375
tmp= (char*) val + cmin(2, val_len);
372
tmp= (char*) val + min(2, val_len);
376
373
l_time->second= (int) my_strtoll10(val, &tmp, &error);
394
391
if (val_len < 2 || ! usa_time)
396
if (!my_strnncoll(&my_charset_utf8_general_ci,
397
(const unsigned char *) val, 2,
398
(const unsigned char *) "PM", 2))
393
if (!my_strnncoll(&my_charset_latin1,
394
(const uchar *) val, 2,
395
(const uchar *) "PM", 2))
400
else if (my_strnncoll(&my_charset_utf8_general_ci,
401
(const unsigned char *) val, 2,
402
(const unsigned char *) "AM", 2))
397
else if (my_strnncoll(&my_charset_latin1,
398
(const uchar *) val, 2,
399
(const uchar *) "AM", 2))
427
tmp= (char*) val + cmin(val_len, 3);
424
tmp= (char*) val + min(val_len, 3);
428
425
yearday= (int) my_strtoll10(val, &tmp, &error);
437
434
sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
438
435
strict_week_number= (*ptr=='V' || *ptr=='v');
439
tmp= (char*) val + cmin(val_len, 2);
436
tmp= (char*) val + min(val_len, 2);
440
437
if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
441
438
(strict_week_number && !week_number) ||
442
439
week_number > 53)
450
447
strict_week_number_year_type= (*ptr=='X');
451
tmp= (char*) val + cmin(4, val_len);
448
tmp= (char*) val + min(4, val_len);
452
449
strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
581
if (!my_isspace(&my_charset_utf8_general_ci,*val))
578
if (!my_isspace(&my_charset_latin1,*val))
583
make_truncated_value_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
580
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
584
581
val_begin, length,
585
cached_timestamp_type, NULL);
582
cached_timestamp_type, NullS);
588
585
} while (++val != val_end);
595
strmake(buff, val_begin, cmin(length, (uint)sizeof(buff)-1));
596
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
592
strmake(buff, val_begin, min(length, (uint)sizeof(buff)-1));
593
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
597
594
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
598
595
date_time_type, buff, "str_to_date");
608
605
bool make_date_time(DATE_TIME_FORMAT *format, DRIZZLE_TIME *l_time,
609
enum enum_drizzle_timestamp_type type, String *str)
606
timestamp_type type, String *str)
611
608
char intbuff[15];
615
612
const char *ptr, *end;
616
Session *session= current_session;
617
MY_LOCALE *locale= session->variables.lc_time_names;
613
THD *thd= current_thd;
614
MY_LOCALE *locale= thd->variables.lc_time_names;
853
850
For example, '1.1' -> '1.100000'
856
static bool get_interval_info(const char *str,uint32_t length, const CHARSET_INFO * const cs,
857
uint32_t count, uint64_t *values,
853
static bool get_interval_info(const char *str,uint length, const CHARSET_INFO * const cs,
854
uint count, uint64_t *values,
858
855
bool transform_msec)
860
857
const char *end=str+length;
862
859
while (str != end && !my_isdigit(cs,*str))
868
865
const char *start= str;
869
866
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
870
value= value * 10L + (int64_t) (*str - '0');
867
value= value * 10LL + (int64_t) (*str - '0');
871
868
if (transform_msec && i == count - 1) // microseconds always last
873
870
long msec_length= 6 - (str - start);
883
880
/* Change values[0...i-1] -> values[0...count-1] */
884
bmove_upp((unsigned char*) (values+count), (unsigned char*) (values+i),
881
bmove_upp((uchar*) (values+count), (uchar*) (values+i),
885
882
sizeof(*values)*i);
886
883
memset(values, 0, sizeof(*values)*(count-i));
894
891
int64_t Item_func_period_add::val_int()
896
893
assert(fixed == 1);
897
uint32_t period= args[0]->val_int();
894
ulong period=(ulong) args[0]->val_int();
898
895
int months=(int) args[1]->val_int();
900
897
if ((null_value=args[0]->null_value || args[1]->null_value) ||
909
906
int64_t Item_func_period_diff::val_int()
911
908
assert(fixed == 1);
912
uint32_t period1= args[0]->val_int();
913
uint32_t period2= args[1]->val_int();
909
ulong period1=(ulong) args[0]->val_int();
910
ulong period2=(ulong) args[1]->val_int();
915
912
if ((null_value=args[0]->null_value || args[1]->null_value))
916
913
return 0; /* purecov: inspected */
1035
1032
return (String*) 0;
1038
month_name= session->variables.lc_time_names->month_names->type_names[month-1];
1035
month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
1039
1036
str->set(month_name, strlen(month_name), system_charset_info);
1085
uint32_t week_mode(uint32_t mode)
1082
uint week_mode(uint mode)
1087
uint32_t week_format= (mode & 7);
1084
uint week_format= (mode & 7);
1088
1085
if (!(week_format & WEEK_MONDAY_FIRST))
1089
1086
week_format^= WEEK_FIRST_WEEKDAY;
1090
1087
return week_format;
1165
1162
String* Item_func_dayname::val_str(String* str)
1167
1164
assert(fixed == 1);
1168
uint32_t weekday=(uint) val_int(); // Always Item_func_daynr()
1165
uint weekday=(uint) val_int(); // Always Item_func_daynr()
1169
1166
const char *day_name;
1170
Session *session= current_session;
1167
THD *thd= current_thd;
1172
1169
if (null_value)
1173
1170
return (String*) 0;
1175
day_name= session->variables.lc_time_names->day_names->type_names[weekday];
1172
day_name= thd->variables.lc_time_names->day_names->type_names[weekday];
1176
1173
str->set(day_name, strlen(day_name), system_charset_info);
1249
1246
assert(fixed == 1);
1250
1247
if (arg_count == 0)
1251
return (int64_t) current_session->query_start();
1248
return (int64_t) current_thd->query_start();
1252
1249
if (args[0]->type() == FIELD_ITEM)
1253
1250
{ // Optimize timestamp field
1254
1251
Field *field=((Item_field*) args[0])->field;
1469
bool Item_func_from_days::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
1466
bool Item_func_from_days::get_date(DRIZZLE_TIME *ltime, uint fuzzy_date __attribute__((unused)))
1471
1468
int64_t value=args[0]->val_int();
1472
1469
if ((null_value=args[0]->null_value))
1511
1508
void Item_func_curdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1513
Session *session= current_session;
1514
session->variables.time_zone->gmt_sec_to_TIME(now_time,
1515
(my_time_t)session->query_start());
1516
session->time_zone_used= 1;
1510
THD *thd= current_thd;
1511
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1512
(my_time_t)thd->query_start());
1513
thd->time_zone_used= 1;
1524
1521
void Item_func_curdate_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1526
1523
my_tz_UTC->gmt_sec_to_TIME(now_time,
1527
(my_time_t)(current_session->query_start()));
1524
(my_time_t)(current_thd->query_start()));
1529
1526
We are not flagging this query as using time zone, since it uses fixed
1530
1527
UTC-SYSTEM time-zone.
1568
1565
void Item_func_curtime_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1570
Session *session= current_session;
1571
session->variables.time_zone->gmt_sec_to_TIME(now_time,
1572
(my_time_t)session->query_start());
1573
session->time_zone_used= 1;
1567
THD *thd= current_thd;
1568
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1569
(my_time_t)thd->query_start());
1570
thd->time_zone_used= 1;
1581
1578
void Item_func_curtime_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1583
1580
my_tz_UTC->gmt_sec_to_TIME(now_time,
1584
(my_time_t)(current_session->query_start()));
1581
(my_time_t)(current_thd->query_start()));
1586
1583
We are not flagging this query as using time zone, since it uses fixed
1587
1584
UTC-SYSTEM time-zone.
1617
1614
void Item_func_now_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1619
Session *session= current_session;
1620
session->variables.time_zone->gmt_sec_to_TIME(now_time,
1621
(my_time_t)session->query_start());
1622
session->time_zone_used= 1;
1616
THD *thd= current_thd;
1617
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1618
(my_time_t)thd->query_start());
1619
thd->time_zone_used= 1;
1630
1627
void Item_func_now_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1632
1629
my_tz_UTC->gmt_sec_to_TIME(now_time,
1633
(my_time_t)(current_session->query_start()));
1630
(my_time_t)(current_thd->query_start()));
1635
1632
We are not flagging this query as using time zone, since it uses fixed
1636
1633
UTC-SYSTEM time-zone.
1660
1657
void Item_func_sysdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1662
Session *session= current_session;
1663
session->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
1664
session->time_zone_used= 1;
1659
THD *thd= current_thd;
1660
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
1661
thd->time_zone_used= 1;
1702
1699
bool Item_func_sysdate_local::get_date(DRIZZLE_TIME *res,
1703
uint32_t fuzzy_date __attribute__((unused)))
1700
uint fuzzy_date __attribute__((unused)))
1705
1702
store_now_in_TIME(<ime);
1763
1760
Item *arg1= args[1]->this_item();
1766
const CHARSET_INFO * const cs= session->variables.collation_connection;
1763
const CHARSET_INFO * const cs= thd->variables.collation_connection;
1767
1764
uint32_t repertoire= arg1->collation.repertoire;
1768
if (!session->variables.lc_time_names->is_ascii)
1765
if (!thd->variables.lc_time_names->is_ascii)
1769
1766
repertoire|= MY_REPERTOIRE_EXTENDED;
1770
1767
collation.set(cs, arg1->collation.derivation, repertoire);
1771
1768
if (arg1->type() == STRING_ITEM)
1779
1776
fixed_length=0;
1780
max_length=cmin(arg1->max_length,(uint32_t) MAX_BLOB_WIDTH) * 10 *
1777
max_length=min(arg1->max_length,(uint32_t) MAX_BLOB_WIDTH) * 10 *
1781
1778
collation.collation->mbmaxlen;
1782
1779
set_if_smaller(max_length,MAX_BLOB_WIDTH);
1943
1940
void Item_func_from_unixtime::fix_length_and_dec()
1945
session= current_session;
1946
1943
collation.set(&my_charset_bin);
1947
1944
decimals= DATETIME_DEC;
1948
1945
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
1950
session->time_zone_used= 1;
1947
thd->time_zone_used= 1;
1987
1984
bool Item_func_from_unixtime::get_date(DRIZZLE_TIME *ltime,
1988
uint32_t fuzzy_date __attribute__((unused)))
1985
uint fuzzy_date __attribute__((unused)))
1990
1987
uint64_t tmp= (uint64_t)(args[0]->val_int());
1995
1992
if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
1998
session->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp);
1995
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp);
2039
2036
/* Here arg[1] is a Item_interval object */
2041
bool Item_date_add_interval::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2038
bool Item_date_add_interval::get_date(DRIZZLE_TIME *ltime, uint fuzzy_date __attribute__((unused)))
2043
2040
INTERVAL interval;
2200
2197
case INTERVAL_MONTH: return ltime.month;
2201
2198
case INTERVAL_WEEK:
2203
week_format= current_session->variables.default_week_format;
2200
week_format= current_thd->variables.default_week_format;
2204
2201
return calc_week(<ime, week_mode(week_format), &year);
2206
2203
case INTERVAL_DAY: return ltime.day;
2327
2324
// Convert character set if differ
2328
uint32_t dummy_errors;
2329
2326
if (!(res= args[0]->val_str(&tmp_value)) ||
2330
2327
str->copy(res->ptr(), res->length(), from_cs,
2331
2328
cast_cs, &dummy_errors))
2357
2354
str_value= *res; // Not malloced string
2358
2355
res= &str_value;
2360
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2357
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2361
2358
ER_TRUNCATED_WRONG_VALUE,
2362
2359
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
2363
2360
res->c_ptr_safe());
2409
2406
from_cs= (args[0]->result_type() == INT_RESULT ||
2410
2407
args[0]->result_type() == DECIMAL_RESULT ||
2411
2408
args[0]->result_type() == REAL_RESULT) ?
2412
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_utf8_general_ci) :
2409
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
2413
2410
args[0]->collation.collation;
2414
2411
charset_conversion= (cast_cs->mbmaxlen > 1) ||
2415
2412
(!my_charset_same(from_cs, cast_cs) && from_cs != &my_charset_bin && cast_cs != &my_charset_bin);
2492
bool Item_date_typecast::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2489
bool Item_date_typecast::get_date(DRIZZLE_TIME *ltime, uint fuzzy_date __attribute__((unused)))
2494
2491
bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
2495
2492
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
2841
2842
char *ptr= int64_t10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
2842
2843
int len = (int)(ptr - buf) +
2843
2844
sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second);
2844
make_truncated_value_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2845
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2845
2846
buf, len, DRIZZLE_TIMESTAMP_TIME,
2849
2850
if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str))
2894
2895
int_type == INTERVAL_QUARTER ||
2895
2896
int_type == INTERVAL_MONTH)
2897
uint32_t year_beg, year_end, month_beg, month_end, day_beg, day_end;
2899
uint32_t second_beg, second_end, microsecond_beg, microsecond_end;
2898
uint year_beg, year_end, month_beg, month_end, day_beg, day_end;
2900
uint second_beg, second_end, microsecond_beg, microsecond_end;
3040
3041
(format_name= format->format_name);
3043
uint32_t format_name_len;
3044
uint format_name_len;
3044
3045
format_name_len= strlen(format_name);
3045
3046
if (val_len == format_name_len &&
3046
!my_strnncoll(&my_charset_utf8_general_ci,
3047
(const unsigned char *) val->ptr(), val_len,
3048
(const unsigned char *) format_name, val_len))
3047
!my_strnncoll(&my_charset_latin1,
3048
(const uchar *) val->ptr(), val_len,
3049
(const uchar *) format_name, val_len))
3050
3051
const char *format_str= get_date_time_format_str(format, type);
3051
3052
str->set(format_str, strlen(format_str), &my_charset_bin);
3108
3109
static date_time_format_types
3109
get_date_time_result_type(const char *format, uint32_t length)
3110
get_date_time_result_type(const char *format, uint length)
3111
3112
const char *time_part_frms= "HISThiklrs";
3112
3113
const char *date_part_frms= "MVUXYWabcjmvuxyw";
3191
bool Item_func_str_to_date::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3192
bool Item_func_str_to_date::get_date(DRIZZLE_TIME *ltime, uint fuzzy_date)
3193
3194
DATE_TIME_FORMAT date_time_format;
3194
3195
char val_buff[64], format_buff[64];
3245
bool Item_func_last_day::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3246
bool Item_func_last_day::get_date(DRIZZLE_TIME *ltime, uint fuzzy_date)
3247
3248
if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
3248
3249
(ltime->month == 0))