Commit b14d3ada authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

merge

parents 9892ace4 afe1ef5e
...@@ -1040,6 +1040,27 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) ...@@ -1040,6 +1040,27 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
} }
/*
Helper function for datetime formatting.
Format number as string, left-padded with 0.
The reason to use own formatting rather than sprintf() is performance - in a
datetime benchmark it helped to reduced the datetime formatting overhead
from ~30% down to ~4%.
*/
static char* fmt_number(uint val, char *out, uint digits)
{
uint i;
for(i= 0; i < digits; i++)
{
out[digits-i-1]= '0' + val%10;
val/=10;
}
return out + digits;
}
/* /*
Functions to convert time/date/datetime value to a string, Functions to convert time/date/datetime value to a string,
using default format. using default format.
...@@ -1053,42 +1074,84 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) ...@@ -1053,42 +1074,84 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits) int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
{ {
ulong day= (l_time->year || l_time->month) ? 0 : l_time->day; uint day= (l_time->year || l_time->month) ? 0 : l_time->day;
uint hour= day * 24 + l_time->hour;
char*pos= to;
if (digits == AUTO_SEC_PART_DIGITS) if (digits == AUTO_SEC_PART_DIGITS)
digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0; digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0;
DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS); DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS);
return sprintf(to, if(l_time->neg)
digits ? "%s%02lu:%02u:%02u.%0*lu" *pos++= '-';
: "%s%02lu:%02u:%02u",
(l_time->neg ? "-" : ""), if(hour > 99)
day * 24L + l_time->hour, l_time->minute, l_time->second, /* Need more than 2 digits for hours in string representation. */
digits, (ulong)sec_part_shift(l_time->second_part, digits)); pos= longlong10_to_str((longlong)hour, pos, 10);
else
pos= fmt_number(hour, pos, 2);
*pos++= ':';
pos= fmt_number(l_time->minute, pos, 2);
*pos++= ':';
pos= fmt_number(l_time->second, pos, 2);
if (digits)
{
*pos++= '.';
pos= fmt_number((uint)sec_part_shift(l_time->second_part, digits),
pos, digits);
}
*pos= 0;
return (int) (pos-to);
} }
int my_date_to_str(const MYSQL_TIME *l_time, char *to) int my_date_to_str(const MYSQL_TIME *l_time, char *to)
{ {
return sprintf(to, "%04u-%02u-%02u", char *pos=to;
l_time->year, pos= fmt_number(l_time->year, pos, 4);
l_time->month, *pos++='-';
l_time->day); pos= fmt_number(l_time->month, pos, 2);
*pos++='-';
pos= fmt_number(l_time->day, pos, 2);
*pos= 0;
return (int)(pos - to);
} }
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits) int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits)
{ {
char *pos= to;
if (digits == AUTO_SEC_PART_DIGITS) if (digits == AUTO_SEC_PART_DIGITS)
digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0; digits= l_time->second_part ? TIME_SECOND_PART_DIGITS : 0;
DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS); DBUG_ASSERT(digits <= TIME_SECOND_PART_DIGITS);
return sprintf(to, pos= fmt_number(l_time->year, pos, 4);
digits ? "%04u-%02u-%02u %02u:%02u:%02u.%0*lu" *pos++='-';
: "%04u-%02u-%02u %02u:%02u:%02u", pos= fmt_number(l_time->month, pos, 2);
l_time->year, l_time->month, l_time->day, *pos++='-';
l_time->hour, l_time->minute, l_time->second, pos= fmt_number(l_time->day, pos, 2);
digits, (ulong)sec_part_shift(l_time->second_part, digits)); *pos++=' ';
pos= fmt_number(l_time->hour, pos, 2);
*pos++= ':';
pos= fmt_number(l_time->minute, pos, 2);
*pos++= ':';
pos= fmt_number(l_time->second, pos, 2);
if (digits)
{
*pos++='.';
pos= fmt_number((uint) sec_part_shift(l_time->second_part, digits), pos,
digits);
}
*pos= 0;
return (int)(pos - to);
} }
......
...@@ -1265,7 +1265,7 @@ err: ...@@ -1265,7 +1265,7 @@ err:
bool Item::get_seconds(ulonglong *sec, ulong *sec_part) bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
{ {
if (result_type() == INT_RESULT) if (decimals == 0)
{ // optimize for an important special case { // optimize for an important special case
longlong val= val_int(); longlong val= val_int();
bool neg= val < 0 && !unsigned_flag; bool neg= val < 0 && !unsigned_flag;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment