SAPDB date/time finctions
mysql-test/r/cast.result: Changes for SAPDB date/time finctions
This commit is contained in:
parent
01e7f418af
commit
4adf180432
@ -44,10 +44,10 @@ t1 CREATE TABLE `t1` (
|
||||
drop table t1;
|
||||
select cast("2001-1-1" as date) = "2001-01-01";
|
||||
cast("2001-1-1" as date) = "2001-01-01"
|
||||
0
|
||||
1
|
||||
select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
|
||||
cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
|
||||
0
|
||||
1
|
||||
select cast("1:2:3" as TIME) = "1:02:03";
|
||||
cast("1:2:3" as TIME) = "1:02:03"
|
||||
0
|
||||
|
@ -101,8 +101,8 @@ timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002")
|
||||
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
|
||||
timediff("1997-12-31 23:59:59.000001","23:59:59.000001")
|
||||
NULL
|
||||
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1");
|
||||
timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1")
|
||||
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
|
||||
timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001")
|
||||
-00:00:00.000001
|
||||
select maketime(10,11,12);
|
||||
maketime(10,11,12)
|
||||
@ -122,6 +122,12 @@ NULL
|
||||
select timestamp("2001-12-01", "25:01:01");
|
||||
timestamp("2001-12-01", "25:01:01")
|
||||
2001-12-02 01:01:01
|
||||
select timestamp("2001-12-01 01:01:01.000100");
|
||||
timestamp("2001-12-01 01:01:01.000100")
|
||||
2001-12-01 01:01:01.000100
|
||||
select timestamp("2001-12-01");
|
||||
timestamp("2001-12-01")
|
||||
2001-12-01 00:00:00
|
||||
select day("1997-12-31 23:59:59.000001");
|
||||
day("1997-12-31 23:59:59.000001")
|
||||
31
|
||||
@ -147,7 +153,7 @@ addtime(cast("23:59:59.999999" as time) , "1 1:1:1.000002") as f3,
|
||||
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
|
||||
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
|
||||
maketime(10,11,12) as f6,
|
||||
timestamp("2001-12-01", "01:01:01") as f7,
|
||||
timestamp(cast("2001-12-01" as date), "01:01:01") as f7,
|
||||
date("1997-12-31 23:59:59.000001") as f8,
|
||||
time("1997-12-31 23:59:59.000001") as f9;
|
||||
describe t1;
|
||||
|
@ -51,7 +51,7 @@ select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
|
||||
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
|
||||
select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002");
|
||||
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
|
||||
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1");
|
||||
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
|
||||
|
||||
select maketime(10,11,12);
|
||||
select maketime(25,11,12);
|
||||
@ -61,6 +61,8 @@ select maketime(-25,11,12);
|
||||
select timestamp("2001-12-01", "01:01:01.999999");
|
||||
select timestamp("2001-13-01", "01:01:01.000001");
|
||||
select timestamp("2001-12-01", "25:01:01");
|
||||
select timestamp("2001-12-01 01:01:01.000100");
|
||||
select timestamp("2001-12-01");
|
||||
select day("1997-12-31 23:59:59.000001");
|
||||
select date("1997-12-31 23:59:59.000001");
|
||||
select date("1997-13-31 23:59:59.000001");
|
||||
@ -75,7 +77,7 @@ select makedate(1997,1) as f1,
|
||||
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
|
||||
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
|
||||
maketime(10,11,12) as f6,
|
||||
timestamp("2001-12-01", "01:01:01") as f7,
|
||||
timestamp(cast("2001-12-01" as date), "01:01:01") as f7,
|
||||
date("1997-12-31 23:59:59.000001") as f8,
|
||||
time("1997-12-31 23:59:59.000001") as f9;
|
||||
describe t1;
|
||||
|
@ -709,12 +709,12 @@ Item *create_func_makedate(Item* a,Item* b)
|
||||
|
||||
Item *create_func_addtime(Item* a,Item* b)
|
||||
{
|
||||
return new Item_func_add_time(a, b, 0);
|
||||
return new Item_func_add_time(a, b, 0, 0);
|
||||
}
|
||||
|
||||
Item *create_func_subtime(Item* a,Item* b)
|
||||
{
|
||||
return new Item_func_add_time(a, b, 1);
|
||||
return new Item_func_add_time(a, b, 0, 1);
|
||||
}
|
||||
|
||||
Item *create_func_timediff(Item* a,Item* b)
|
||||
|
@ -29,6 +29,8 @@
|
||||
** Todo: Move month and days to language files
|
||||
*/
|
||||
|
||||
#define MAX_DAY_NUMBER 3652424L
|
||||
|
||||
static String month_names[] =
|
||||
{
|
||||
String("January", &my_charset_latin1),
|
||||
@ -55,10 +57,14 @@ static String day_names[] =
|
||||
String("Sunday", &my_charset_latin1)
|
||||
};
|
||||
|
||||
enum date_time_format_types { TIME_ONLY= 0, TIME_MICROSECOND,
|
||||
DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND};
|
||||
enum date_time_format_types
|
||||
{
|
||||
TIME_ONLY= 0, TIME_MICROSECOND,
|
||||
DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
|
||||
};
|
||||
|
||||
typedef struct date_time_format {
|
||||
typedef struct date_time_format
|
||||
{
|
||||
const char* format_str;
|
||||
uint length;
|
||||
};
|
||||
@ -73,6 +79,14 @@ static struct date_time_format date_time_formats[]=
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
OPTIMIZATION TODO:
|
||||
- Replace the switch with a function that should be called for each
|
||||
date type.
|
||||
- Remove sprintf and opencode the conversion, like we do in
|
||||
Field_datetime.
|
||||
*/
|
||||
|
||||
String *make_datetime(String *str, TIME *ltime,
|
||||
enum date_time_format_types format)
|
||||
{
|
||||
@ -898,8 +912,8 @@ String *Item_func_date_format::val_str(String *str)
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
length= my_sprintf(intbuff, (intbuff,"%d",l_time.day));
|
||||
str->append(intbuff, length);
|
||||
length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
if (l_time.day >= 10 && l_time.day <= 19)
|
||||
str->append("th");
|
||||
else
|
||||
@ -921,45 +935,45 @@ String *Item_func_date_format::val_str(String *str)
|
||||
}
|
||||
break;
|
||||
case 'Y':
|
||||
sprintf(intbuff,"%04d",l_time.year);
|
||||
str->append(intbuff,4);
|
||||
length= int10_to_str(l_time.year, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 4, '0');
|
||||
break;
|
||||
case 'y':
|
||||
sprintf(intbuff,"%02d",l_time.year%100);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(l_time.year%100, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'm':
|
||||
sprintf(intbuff,"%02d",l_time.month);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(l_time.month, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'c':
|
||||
sprintf(intbuff,"%d",l_time.month);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str(l_time.month, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
break;
|
||||
case 'd':
|
||||
sprintf(intbuff,"%02d",l_time.day);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'e':
|
||||
sprintf(intbuff,"%d",l_time.day);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
break;
|
||||
case 'f':
|
||||
sprintf(intbuff,"%06ld",l_time.second_part);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str(l_time.second_part, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 6, '0');
|
||||
break;
|
||||
case 'H':
|
||||
sprintf(intbuff,"%02d",l_time.hour);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(l_time.hour, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'h':
|
||||
case 'I':
|
||||
sprintf(intbuff,"%02d", (l_time.hour+11)%12+1);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'i': /* minutes */
|
||||
sprintf(intbuff,"%02d",l_time.minute);
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(l_time.minute, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'j':
|
||||
if (date_or_time)
|
||||
@ -967,52 +981,60 @@ String *Item_func_date_format::val_str(String *str)
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
sprintf(intbuff,"%03d",
|
||||
(int) (calc_daynr(l_time.year,l_time.month,l_time.day) -
|
||||
calc_daynr(l_time.year,1,1)) + 1);
|
||||
str->append(intbuff,3);
|
||||
length= int10_to_str(calc_daynr(l_time.year,l_time.month,l_time.day) -
|
||||
calc_daynr(l_time.year,1,1) + 1, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 3, '0');
|
||||
break;
|
||||
case 'k':
|
||||
sprintf(intbuff,"%d",l_time.hour);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str(l_time.hour, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
break;
|
||||
case 'l':
|
||||
sprintf(intbuff,"%d", (l_time.hour+11)%12+1);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
break;
|
||||
case 'p':
|
||||
str->append(l_time.hour < 12 ? "AM" : "PM",2);
|
||||
break;
|
||||
case 'r':
|
||||
sprintf(intbuff,(l_time.hour < 12) ? "%02d:%02d:%02d AM" :
|
||||
"%02d:%02d:%02d PM",(l_time.hour+11)%12+1,l_time.minute,
|
||||
l_time.second);
|
||||
str->append(intbuff);
|
||||
length= my_sprintf(intbuff,
|
||||
(intbuff,
|
||||
(l_time.hour < 12) ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
|
||||
(l_time.hour+11)%12+1,
|
||||
l_time.minute,
|
||||
l_time.second));
|
||||
str->append(intbuff, length);
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
sprintf(intbuff,"%02d",l_time.second);
|
||||
str->append(intbuff);
|
||||
length= int10_to_str(l_time.second, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
break;
|
||||
case 'T':
|
||||
sprintf(intbuff,"%02d:%02d:%02d", l_time.hour, l_time.minute,
|
||||
l_time.second);
|
||||
str->append(intbuff);
|
||||
length= my_sprintf(intbuff,
|
||||
(intbuff,
|
||||
"%02d:%02d:%02d",
|
||||
l_time.hour,
|
||||
l_time.minute,
|
||||
l_time.second));
|
||||
str->append(intbuff, length);
|
||||
break;
|
||||
case 'U':
|
||||
case 'u':
|
||||
{
|
||||
uint year;
|
||||
sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year));
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(calc_week(&l_time, 0, (*ptr) == 'U', &year),
|
||||
intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
{
|
||||
uint year;
|
||||
sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year));
|
||||
str->append(intbuff,2);
|
||||
length= int10_to_str(calc_week(&l_time, 1, (*ptr) == 'V', &year),
|
||||
intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 2, '0');
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
@ -1020,14 +1042,15 @@ String *Item_func_date_format::val_str(String *str)
|
||||
{
|
||||
uint year;
|
||||
(void) calc_week(&l_time, 1, (*ptr) == 'X', &year);
|
||||
sprintf(intbuff,"%04d",year);
|
||||
str->append(intbuff,4);
|
||||
length= int10_to_str(year, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 4, '0');
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1);
|
||||
sprintf(intbuff,"%d",weekday);
|
||||
str->append(intbuff,1);
|
||||
length= int10_to_str(weekday, intbuff, 10) - intbuff;
|
||||
str->append_with_prefill(intbuff, length, 1, '0');
|
||||
|
||||
break;
|
||||
default:
|
||||
str->append(*ptr);
|
||||
@ -1109,7 +1132,7 @@ void Item_date_add_interval::fix_length_and_dec()
|
||||
enum_field_types arg0_field_type;
|
||||
set_charset(default_charset());
|
||||
maybe_null=1;
|
||||
max_length=26*default_charset()->mbmaxlen;
|
||||
max_length=26*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
value.alloc(32);
|
||||
|
||||
/*
|
||||
@ -1197,13 +1220,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date)
|
||||
ltime->hour=sec/3600;
|
||||
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
|
||||
get_date_from_daynr(daynr,<ime->year,<ime->month,<ime->day);
|
||||
if (daynr < 0 || daynr >= 3652424) // Day number from year 0 to 9999-12-31
|
||||
if (daynr < 0 || daynr >= MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31
|
||||
goto null_date;
|
||||
break;
|
||||
case INTERVAL_DAY:
|
||||
period= calc_daynr(ltime->year,ltime->month,ltime->day) +
|
||||
sign*interval.day;
|
||||
if (period < 0 || period >= 3652424) // Daynumber from year 0 to 9999-12-31
|
||||
if (period < 0 || period >= MAX_DAY_NUMBER) // Daynumber from year 0 to 9999-12-31
|
||||
goto null_date;
|
||||
get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day);
|
||||
break;
|
||||
@ -1375,6 +1398,63 @@ void Item_typecast::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
String *Item_datetime_typecast::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
|
||||
if (!get_arg0_date(<ime,1) &&
|
||||
make_datetime(str, <ime, ltime.second_part ?
|
||||
DATE_TIME_MICROSECOND : DATE_TIME))
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool Item_time_typecast::get_time(TIME *ltime)
|
||||
{
|
||||
bool res= get_arg0_time(ltime);
|
||||
ltime->time_type= TIMESTAMP_TIME;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
String *Item_time_typecast::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
|
||||
if (!get_arg0_time(<ime) &&
|
||||
make_datetime(str, <ime, ltime.second_part ? TIME_MICROSECOND : TIME_ONLY))
|
||||
return str;
|
||||
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool Item_date_typecast::get_date(TIME *ltime, bool fuzzy_date)
|
||||
{
|
||||
bool res= get_arg0_date(ltime,1);
|
||||
ltime->time_type= TIMESTAMP_DATE;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
String *Item_date_typecast::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
|
||||
if (!get_arg0_date(<ime,1) &&
|
||||
make_datetime(str, <ime, DATE_ONLY))
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
MAKEDATE(a,b) is a date function that creates a date value
|
||||
from a year and day value.
|
||||
@ -1392,7 +1472,7 @@ String *Item_func_makedate::val_str(String *str)
|
||||
goto null_date;
|
||||
|
||||
days= calc_daynr(yearnr,1,1) + daynr - 1;
|
||||
if (days > 0 || days < 3652424L) // Day number from year 0 to 9999-12-31
|
||||
if (days > 0 || days < MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31
|
||||
{
|
||||
null_value=0;
|
||||
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
|
||||
@ -1410,7 +1490,7 @@ void Item_func_add_time::fix_length_and_dec()
|
||||
{
|
||||
enum_field_types arg0_field_type;
|
||||
decimals=0;
|
||||
max_length=26*my_charset_bin.mbmaxlen;
|
||||
max_length=26*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
|
||||
/*
|
||||
The field type for the result of an Item_func_add_time function is defined as
|
||||
@ -1424,7 +1504,8 @@ void Item_func_add_time::fix_length_and_dec()
|
||||
|
||||
cached_field_type= MYSQL_TYPE_STRING;
|
||||
arg0_field_type= args[0]->field_type();
|
||||
if (arg0_field_type == MYSQL_TYPE_DATETIME ||
|
||||
if (arg0_field_type == MYSQL_TYPE_DATE ||
|
||||
arg0_field_type == MYSQL_TYPE_DATETIME ||
|
||||
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
|
||||
cached_field_type= MYSQL_TYPE_DATETIME;
|
||||
else if (arg0_field_type == MYSQL_TYPE_TIME)
|
||||
@ -1443,20 +1524,28 @@ void Item_func_add_time::fix_length_and_dec()
|
||||
String *Item_func_add_time::val_str(String *str)
|
||||
{
|
||||
TIME l_time1, l_time2, l_time3;
|
||||
bool is_time;
|
||||
bool is_time= 0;
|
||||
long microseconds, seconds, days= 0;
|
||||
int l_sign= sign;
|
||||
|
||||
null_value=0;
|
||||
if (args[0]->get_time(&l_time1) ||
|
||||
args[1]->get_time(&l_time2) ||
|
||||
l_time2.time_type == TIMESTAMP_FULL)
|
||||
goto null_date;
|
||||
is_time= (l_time1.time_type == TIMESTAMP_TIME);
|
||||
l_time3.neg= 0;
|
||||
if (is_time)
|
||||
if (is_date) // TIMESTAMP function
|
||||
{
|
||||
if ((l_time2.neg == l_time1.neg) && l_time1.neg)
|
||||
if (get_arg0_date(&l_time1,1) ||
|
||||
args[1]->get_time(&l_time2) ||
|
||||
l_time1.time_type == TIMESTAMP_TIME ||
|
||||
l_time2.time_type != TIMESTAMP_TIME)
|
||||
goto null_date;
|
||||
}
|
||||
else // ADDTIME function
|
||||
{
|
||||
if (args[0]->get_time(&l_time1) ||
|
||||
args[1]->get_time(&l_time2) ||
|
||||
l_time2.time_type == TIMESTAMP_FULL)
|
||||
goto null_date;
|
||||
is_time= (l_time1.time_type == TIMESTAMP_TIME);
|
||||
if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg))
|
||||
l_time3.neg= 1;
|
||||
}
|
||||
if (l_time1.neg != l_time2.neg)
|
||||
@ -1504,13 +1593,17 @@ String *Item_func_add_time::val_str(String *str)
|
||||
{
|
||||
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
|
||||
if (l_time3.day &&
|
||||
make_datetime(str, &l_time3, DATE_TIME_MICROSECOND))
|
||||
make_datetime(str, &l_time3,
|
||||
l_time1.second_part || l_time2.second_part ?
|
||||
DATE_TIME_MICROSECOND : DATE_TIME))
|
||||
return str;
|
||||
goto null_date;
|
||||
}
|
||||
|
||||
l_time3.hour+= days*24;
|
||||
if (make_datetime(str, &l_time3, TIME_MICROSECOND))
|
||||
if (make_datetime(str, &l_time3,
|
||||
l_time1.second_part || l_time2.second_part ?
|
||||
TIME_MICROSECOND : TIME_ONLY))
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
@ -1578,7 +1671,9 @@ String *Item_func_timediff::val_str(String *str)
|
||||
l_time3.neg= l_time3.neg ? 0 : 1;
|
||||
|
||||
calc_time_from_sec(&l_time3, seconds, microseconds);
|
||||
if (make_datetime(str, &l_time3, TIME_MICROSECOND))
|
||||
if (make_datetime(str, &l_time3,
|
||||
l_time1.second_part || l_time2.second_part ?
|
||||
TIME_MICROSECOND : TIME_ONLY))
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
@ -1623,99 +1718,6 @@ null_date:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
TIMESTAMP(a,b) is a function ( extraction) that calculates a datetime value
|
||||
comprising a date value, time value.
|
||||
|
||||
a: Date_or_datetime value
|
||||
b: Time value
|
||||
Result: Datetime value
|
||||
*/
|
||||
|
||||
String *Item_func_timestamp::val_str(String *str)
|
||||
{
|
||||
TIME l_time1 ,l_time2, l_time3;
|
||||
long seconds;
|
||||
long microseconds;
|
||||
long days;
|
||||
int l_sign;
|
||||
|
||||
if (get_arg0_date(&l_time1,1) ||
|
||||
args[1]->get_time(&l_time2) ||
|
||||
l_time1.time_type == TIMESTAMP_TIME ||
|
||||
l_time2.time_type != TIMESTAMP_TIME)
|
||||
goto null_date;
|
||||
|
||||
l_sign= l_time2.neg ? -1 : 1;
|
||||
days= (calc_daynr((uint) l_time1.year,(uint) l_time1.month,
|
||||
(uint) l_time1.day) + l_sign*l_time2.day);
|
||||
|
||||
microseconds= l_time1.second_part + l_sign*l_time2.second_part;
|
||||
seconds= (l_time1.hour*3600L + l_time1.minute*60L + l_time1.second +
|
||||
(l_time2.day*86400L + l_time2.hour*3600L +
|
||||
l_time2.minute*60L + l_time2.second)*l_sign);
|
||||
days+= seconds/86400L;
|
||||
seconds%= 86400L;
|
||||
if (microseconds < 0)
|
||||
{
|
||||
microseconds+= 1000000L;
|
||||
seconds--;
|
||||
}
|
||||
if (seconds < 0)
|
||||
{
|
||||
days--;
|
||||
seconds+= 86400L;
|
||||
}
|
||||
if (days < 0)
|
||||
goto null_date;
|
||||
|
||||
calc_time_from_sec(&l_time3, seconds, microseconds);
|
||||
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
|
||||
make_datetime(str, &l_time3, DATE_TIME_MICROSECOND);
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
DATE(a) is a function ( extraction) that calculates a date value.
|
||||
|
||||
a: Datetime value
|
||||
Result: Date value
|
||||
*/
|
||||
String *Item_func_date::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
|
||||
if (!get_arg0_date(<ime,1) &&
|
||||
make_datetime(str, <ime, DATE_ONLY))
|
||||
return str;
|
||||
|
||||
null_date:
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
TIME(a) is a function ( extraction) that calculates a time value.
|
||||
|
||||
a: Datetime value
|
||||
Result: Time value
|
||||
*/
|
||||
String *Item_func_time::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
|
||||
if (!get_arg0_time(<ime) &&
|
||||
make_datetime(str, <ime, TIME_MICROSECOND))
|
||||
return str;
|
||||
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
MICROSECOND(a) is a function ( extraction) that extracts the microseconds from a.
|
||||
|
||||
|
@ -557,6 +557,8 @@ class Item_date_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
Item_date_typecast(Item *a) :Item_typecast(a) {}
|
||||
String *val_str(String *str);
|
||||
bool get_date(TIME *ltime, bool fuzzy_date);
|
||||
const char *func_name() const { return "date"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
@ -571,6 +573,8 @@ class Item_time_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
Item_time_typecast(Item *a) :Item_typecast(a) {}
|
||||
String *val_str(String *str);
|
||||
bool get_time(TIME *ltime);
|
||||
const char *func_name() const { return "time"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
@ -585,6 +589,7 @@ class Item_datetime_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
Item_datetime_typecast(Item *a) :Item_typecast(a) {}
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "datetime"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
@ -604,7 +609,7 @@ public:
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=8*my_charset_bin.mbmaxlen;
|
||||
max_length=8*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
@ -613,18 +618,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_func_add_time :public Item_str_func
|
||||
{
|
||||
const bool is_date;
|
||||
int sign;
|
||||
enum_field_types cached_field_type;
|
||||
|
||||
public:
|
||||
Item_func_add_time(Item *a, Item *b, bool neg_arg)
|
||||
:Item_str_func(a, b) { sign= neg_arg ? -1 : 1; }
|
||||
Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
|
||||
:Item_str_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "addtime"; }
|
||||
enum_field_types field_type() const { return cached_field_type; }
|
||||
void fix_length_and_dec();
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Change this when we support
|
||||
microseconds in TIME/DATETIME
|
||||
*/
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
@ -647,7 +660,7 @@ public:
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=17*my_charset_bin.mbmaxlen;
|
||||
max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
@ -667,66 +680,7 @@ public:
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=8*my_charset_bin.mbmaxlen;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_timestamp :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_timestamp(Item *a, Item *b) :Item_str_func(a, b) {}
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "timestamp"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=26*my_charset_bin.mbmaxlen;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_date :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_date(Item *a)
|
||||
:Item_str_func(a) {}
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "date"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=10*my_charset_bin.mbmaxlen;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_time :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_time(Item *a)
|
||||
:Item_str_func(a) {}
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "time"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=15*my_charset_bin.mbmaxlen;
|
||||
max_length=8*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Field *tmp_table_field() { return result_field; }
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
|
@ -224,6 +224,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||
|
||||
#define RAID_BLOCK_SIZE 1024
|
||||
|
||||
#define MY_CHARSET_BIN_MB_MAXLEN 1
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
/*
|
||||
Sync points allow us to force the server to reach a certain line of code
|
||||
|
@ -823,6 +823,13 @@ bool Protocol_simple::store(Field *field)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
*/
|
||||
|
||||
|
||||
bool Protocol_simple::store(TIME *tm)
|
||||
{
|
||||
#ifndef DEBUG_OFF
|
||||
@ -863,6 +870,12 @@ bool Protocol_simple::store_date(TIME *tm)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
*/
|
||||
|
||||
bool Protocol_simple::store_time(TIME *tm)
|
||||
{
|
||||
#ifndef DEBUG_OFF
|
||||
|
@ -390,6 +390,23 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool String::append_with_prefill(const char *s,uint32 arg_length,
|
||||
uint32 full_length, char fill_char)
|
||||
{
|
||||
int t_length= arg_length > full_length ? arg_length : full_length;
|
||||
|
||||
if (realloc(str_length + t_length))
|
||||
return TRUE;
|
||||
t_length= full_length - arg_length;
|
||||
if (t_length > 0)
|
||||
{
|
||||
bfill(Ptr+str_length, t_length, fill_char);
|
||||
str_length=str_length + t_length;
|
||||
}
|
||||
append(s, arg_length);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint32 String::numchars()
|
||||
{
|
||||
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
|
||||
|
@ -189,6 +189,8 @@ public:
|
||||
bool append(const char *s,uint32 arg_length=0);
|
||||
bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs);
|
||||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
bool append_with_prefill(const char *s, uint32 arg_length,
|
||||
uint32 full_length, char fill_char);
|
||||
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
int strstr_case(const String &s,uint32 offset=0);
|
||||
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
|
@ -2381,7 +2381,7 @@ simple_expr:
|
||||
Lex->safe_to_cache_query=0;
|
||||
}
|
||||
| DATE_SYM '(' expr ')'
|
||||
{ $$= new Item_func_date($3); }
|
||||
{ $$= new Item_date_typecast($3); }
|
||||
| DAY_SYM '(' expr ')'
|
||||
{ $$= new Item_func_dayofmonth($3); }
|
||||
| ELT_FUNC '(' expr ',' expr_list ')'
|
||||
@ -2580,9 +2580,11 @@ simple_expr:
|
||||
| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
|
||||
{ $$= new Item_func_substr_index($3,$5,$7); }
|
||||
| TIME_SYM '(' expr ')'
|
||||
{ $$= new Item_func_time($3); }
|
||||
{ $$= new Item_time_typecast($3); }
|
||||
| TIMESTAMP '(' expr ')'
|
||||
{ $$= new Item_datetime_typecast($3); }
|
||||
| TIMESTAMP '(' expr ',' expr ')'
|
||||
{ $$= new Item_func_timestamp($3, $5); }
|
||||
{ $$= new Item_func_add_time($3, $5, 1, 0); }
|
||||
| TRIM '(' expr ')'
|
||||
{ $$= new Item_func_trim($3); }
|
||||
| TRIM '(' LEADING expr FROM expr ')'
|
||||
@ -4427,6 +4429,7 @@ keyword:
|
||||
| MEDIUM_SYM {}
|
||||
| MERGE_SYM {}
|
||||
| MEMORY_SYM {}
|
||||
| MICROSECOND_SYM {}
|
||||
| MINUTE_SYM {}
|
||||
| MIN_ROWS {}
|
||||
| MODIFY_SYM {}
|
||||
|
@ -432,6 +432,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
|
||||
l_time->minute=date[4];
|
||||
l_time->second=date[5];
|
||||
l_time->second_part=date[6];
|
||||
l_time->neg= 0;
|
||||
DBUG_RETURN(l_time->time_type=
|
||||
(number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_FULL));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user