You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-392 fix negative zero hours
Also fix some functions that were not behaving correctly
This commit is contained in:
@ -1005,6 +1005,7 @@ bool mysql_str_to_time( const string& input, Time& output )
|
||||
output.minute = 59;
|
||||
output.second = 59;
|
||||
output.msecond = 999999;
|
||||
output.is_neg = 0;
|
||||
}
|
||||
else if (hour < -838)
|
||||
{
|
||||
@ -1012,6 +1013,7 @@ bool mysql_str_to_time( const string& input, Time& output )
|
||||
output.minute = 59;
|
||||
output.second = 59;
|
||||
output.msecond = 999999;
|
||||
output.is_neg = 1;
|
||||
}
|
||||
// If neither of the above match then we return a 0 time
|
||||
else
|
||||
@ -1025,6 +1027,7 @@ bool mysql_str_to_time( const string& input, Time& output )
|
||||
output.minute = min;
|
||||
output.second = sec;
|
||||
output.msecond = usec;
|
||||
output.is_neg = isNeg;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1914,12 +1917,18 @@ int64_t DataConvert::convertColumnTime(
|
||||
inMinute = 0;
|
||||
inSecond = 0;
|
||||
inMicrosecond = 0;
|
||||
bool isNeg = false;
|
||||
if ( datetimeFormat != CALPONTTIME_ENUM )
|
||||
{
|
||||
status = -1;
|
||||
return value;
|
||||
}
|
||||
|
||||
if (p[0] == '-')
|
||||
{
|
||||
isNeg = true;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
p = strtok_r(p, ":.", &savePoint);
|
||||
@ -1981,6 +1990,7 @@ int64_t DataConvert::convertColumnTime(
|
||||
atime.minute = inMinute;
|
||||
atime.second = inSecond;
|
||||
atime.msecond = inMicrosecond;
|
||||
atime.is_neg = isNeg;
|
||||
|
||||
memcpy( &value, &atime, 8);
|
||||
}
|
||||
@ -1994,6 +2004,7 @@ int64_t DataConvert::convertColumnTime(
|
||||
atime.minute = 59;
|
||||
atime.second = 59;
|
||||
atime.msecond = 999999;
|
||||
atime.is_neg = false;
|
||||
memcpy( &value, &atime, 8);
|
||||
}
|
||||
else if (inHour < -838)
|
||||
@ -2003,6 +2014,7 @@ int64_t DataConvert::convertColumnTime(
|
||||
atime.minute = 59;
|
||||
atime.second = 59;
|
||||
atime.msecond = 999999;
|
||||
atime.is_neg = false;
|
||||
memcpy( &value, &atime, 8);
|
||||
}
|
||||
// If neither of the above match then we return a 0 time
|
||||
@ -2084,8 +2096,15 @@ std::string DataConvert::timeToString( long long timevalue, long decimals )
|
||||
Time dt(timevalue);
|
||||
const int TIMETOSTRING_LEN = 19; // (-H)HH:MM:SS.mmmmmm\0
|
||||
char buf[TIMETOSTRING_LEN];
|
||||
char* outbuf = buf;
|
||||
|
||||
sprintf(buf, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
|
||||
if ((dt.hour >= 0) && dt.is_neg)
|
||||
{
|
||||
outbuf[0] = '-';
|
||||
outbuf++;
|
||||
}
|
||||
|
||||
sprintf(outbuf, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
|
||||
if (dt.msecond && decimals)
|
||||
{
|
||||
size_t start = strlen(buf);
|
||||
@ -2128,7 +2147,9 @@ std::string DataConvert::timeToString1( long long datetimevalue )
|
||||
const int TIMETOSTRING1_LEN = 14; // HHMMSSmmmmmm\0
|
||||
char buf[TIMETOSTRING1_LEN];
|
||||
|
||||
sprintf(buf, "%02d%02d%02d%06d", dt.hour, dt.minute, dt.second, dt.msecond);
|
||||
char* outbuf = buf;
|
||||
|
||||
sprintf(outbuf, "%02d%02d%02d%06d", dt.hour, dt.minute, dt.second, dt.msecond);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -2633,7 +2654,9 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
||||
int64_t DataConvert::intToTime(int64_t data)
|
||||
{
|
||||
char buf[21] = {0};
|
||||
char* bufread = buf;
|
||||
Time atime;
|
||||
bool isNeg = false;
|
||||
|
||||
if (data == 0)
|
||||
{
|
||||
@ -2641,6 +2664,7 @@ int64_t DataConvert::intToTime(int64_t data)
|
||||
atime.minute = 0;
|
||||
atime.second = 0;
|
||||
atime.msecond = 0;
|
||||
atime.is_neg = 0;
|
||||
|
||||
return *(reinterpret_cast<int64_t*>(&atime));
|
||||
}
|
||||
@ -2650,24 +2674,37 @@ int64_t DataConvert::intToTime(int64_t data)
|
||||
string hour, min, sec, msec;
|
||||
int64_t h = 0, minute = 0, s = 0, ms = 0;
|
||||
|
||||
switch (strlen(buf))
|
||||
if (bufread[0] == '-')
|
||||
{
|
||||
isNeg = true;
|
||||
bufread++;
|
||||
}
|
||||
|
||||
switch (strlen(bufread))
|
||||
{
|
||||
case 7:
|
||||
hour = string(bufread, 3);
|
||||
min = string(bufread + 2, 2);
|
||||
sec = string(bufread + 4, 2);
|
||||
msec = string(bufread + 6, 6);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
hour = string(buf, 2);
|
||||
min = string(buf + 2, 2);
|
||||
sec = string(buf + 4, 2);
|
||||
msec = string(buf + 6, 6);
|
||||
hour = string(bufread, 2);
|
||||
min = string(bufread + 2, 2);
|
||||
sec = string(bufread + 4, 2);
|
||||
msec = string(bufread + 6, 6);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
min = string(buf, 2);
|
||||
sec = string(buf + 2, 2);
|
||||
msec = string(buf + 4, 6);
|
||||
min = string(bufread, 2);
|
||||
sec = string(bufread + 2, 2);
|
||||
msec = string(bufread + 4, 6);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sec = string(buf, 2);
|
||||
msec = string(buf + 2, 6);
|
||||
sec = string(bufread, 2);
|
||||
msec = string(bufread + 2, 6);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2686,6 +2723,7 @@ int64_t DataConvert::intToTime(int64_t data)
|
||||
atime.minute = minute;
|
||||
atime.second = s;
|
||||
atime.msecond = ms;
|
||||
atime.is_neg = isNeg;
|
||||
|
||||
return *(reinterpret_cast<uint64_t*>(&atime));
|
||||
}
|
||||
@ -2697,11 +2735,20 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
// -838 <= H <= 838
|
||||
uint64_t min = 0, sec = 0, msec = 0;
|
||||
int64_t day = -1, hour = 0;
|
||||
bool isNeg = false;
|
||||
string time, hms, ms;
|
||||
char* end = NULL;
|
||||
|
||||
|
||||
size_t pos = data.find("-");
|
||||
|
||||
if (pos != string::npos)
|
||||
{
|
||||
isNeg = true;
|
||||
}
|
||||
|
||||
// Day
|
||||
size_t pos = data.find(" ");
|
||||
pos = data.find(" ");
|
||||
|
||||
if (pos != string::npos)
|
||||
{
|
||||
@ -2762,6 +2809,7 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
atime.minute = min;
|
||||
atime.second = sec;
|
||||
atime.msecond = msec;
|
||||
atime.is_neg = isNeg;
|
||||
return *(reinterpret_cast<int64_t*>(&atime));
|
||||
}
|
||||
|
||||
|
@ -197,14 +197,17 @@ struct Time
|
||||
signed second : 8;
|
||||
signed minute : 8;
|
||||
signed hour : 12;
|
||||
signed day : 12;
|
||||
signed day : 11;
|
||||
signed is_neg : 1;
|
||||
|
||||
// NULL column value = 0xFFFFFFFFFFFFFFFE
|
||||
Time() : msecond (0xFFFFFE),
|
||||
second (0xFF),
|
||||
minute (0xFF),
|
||||
hour (0xFFF),
|
||||
day (0xFFF) {}
|
||||
day (0x7FF),
|
||||
is_neg (0b1)
|
||||
{}
|
||||
|
||||
// Construct a Time from a 64 bit integer InfiniDB time.
|
||||
Time(int64_t val) :
|
||||
@ -212,11 +215,16 @@ struct Time
|
||||
second((val >> 24) & 0xff),
|
||||
minute((val >> 32) & 0xff),
|
||||
hour((val >> 40) & 0xfff),
|
||||
day((val >> 52) & 0xfff)
|
||||
day((val >> 52) & 0x7ff),
|
||||
is_neg(val >> 63)
|
||||
{}
|
||||
|
||||
Time(signed d, signed h, signed min, signed sec, signed msec) :
|
||||
msecond(msec), second(sec), minute(min), hour(h), day(d) {}
|
||||
Time(signed d, signed h, signed min, signed sec, signed msec, bool neg) :
|
||||
msecond(msec), second(sec), minute(min), hour(h), day(d), is_neg(neg)
|
||||
{
|
||||
if (h < 0)
|
||||
is_neg = 0b1;
|
||||
}
|
||||
|
||||
int64_t convertToMySQLint() const;
|
||||
void reset();
|
||||
@ -229,13 +237,25 @@ void Time::reset()
|
||||
second = 0xFF;
|
||||
minute = 0xFF;
|
||||
hour = 0xFFF;
|
||||
day = 0xFFF;
|
||||
is_neg = 0b1;
|
||||
day = 0x7FF;
|
||||
}
|
||||
|
||||
inline
|
||||
int64_t Time::convertToMySQLint() const
|
||||
{
|
||||
return (int64_t) (hour * 10000) + (minute * 100) + second;
|
||||
if ((hour >= 0) && is_neg)
|
||||
{
|
||||
return (int64_t) ((hour * 10000) + (minute * 100) + second) * -1;
|
||||
}
|
||||
else if (hour >= 0)
|
||||
{
|
||||
return (int64_t) (hour * 10000) + (minute * 100) + second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int64_t) (hour * 10000) - (minute * 100) - second;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t daysInMonth[13] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
|
||||
@ -593,6 +613,12 @@ inline void DataConvert::timeToString( long long timevalue, char* buf, unsigned
|
||||
{
|
||||
msec = (unsigned)((timevalue) & 0xffffff);
|
||||
}
|
||||
if ((hour >= 0) && (timevalue >> 63))
|
||||
{
|
||||
buf[0] = '-';
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
snprintf( buf, buflen, "%02d:%02d:%02d",
|
||||
hour,
|
||||
(unsigned)((timevalue >> 32) & 0xff),
|
||||
@ -636,13 +662,20 @@ inline void DataConvert::timeToString1( long long timevalue, char* buf, unsigned
|
||||
{
|
||||
// Handle negative correctly
|
||||
int hour = 0;
|
||||
if ((timevalue >> 40) & 0xf00)
|
||||
if ((timevalue >> 40) & 0x800)
|
||||
{
|
||||
hour = 0xfffff000;
|
||||
}
|
||||
|
||||
hour |= ((timevalue >> 40) & 0xfff);
|
||||
|
||||
if ((hour >= 0) && (timevalue >> 63))
|
||||
{
|
||||
buf[0] = '-';
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
|
||||
snprintf( buf, buflen, "%02d%02d%02d",
|
||||
hour,
|
||||
(unsigned)((timevalue >> 32) & 0xff),
|
||||
|
Reference in New Issue
Block a user