1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-392 Function fixes

Fixes most of the functions in funcexp so that time and datetime's
microseconds are handled correctly
This commit is contained in:
Andrew Hutchings
2018-04-27 21:18:14 +01:00
parent bd50bbb8bb
commit 957dc44615
11 changed files with 271 additions and 101 deletions

View File

@ -666,14 +666,14 @@ inline const std::string& TreeNode::getStrVal()
case CalpontSystemCatalog::DATETIME: case CalpontSystemCatalog::DATETIME:
{ {
dataconvert::DataConvert::datetimeToString(fResult.intVal, tmp, 255); dataconvert::DataConvert::datetimeToString(fResult.intVal, tmp, 255, fResultType.precision);
fResult.strVal = std::string(tmp); fResult.strVal = std::string(tmp);
break; break;
} }
case CalpontSystemCatalog::TIME: case CalpontSystemCatalog::TIME:
{ {
dataconvert::DataConvert::timeToString(fResult.intVal, tmp, 255); dataconvert::DataConvert::timeToString(fResult.intVal, tmp, 255, fResultType.precision);
fResult.strVal = std::string(tmp); fResult.strVal = std::string(tmp);
break; break;
} }
@ -992,11 +992,20 @@ inline int64_t TreeNode::getDatetimeIntVal()
else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIME) else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIME)
{ {
dataconvert::Time tt; dataconvert::Time tt;
int day = 0;
memcpy(&tt, &fResult.intVal, 8); memcpy(&tt, &fResult.intVal, 8);
if (tt.hour > 23 || tt.hour < 0) // Note, this should probably be current date +/- time
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from time (out of range)."); if (tt.hour > 23)
dataconvert::DateTime dt(0, 0, 0, tt.hour, tt.minute, tt.second, tt.msecond); {
day = tt.hour / 24;
tt.hour = tt.hour % 24;
}
else if (tt.hour < 0)
{
tt.hour = 0;
}
dataconvert::DateTime dt(0, 0, day, tt.hour, tt.minute, tt.second, tt.msecond);
memcpy(&fResult.intVal, &dt, 8); memcpy(&fResult.intVal, &dt, 8);
return fResult.intVal; return fResult.intVal;
} }

View File

@ -3518,8 +3518,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
if (ifp->field_type() == MYSQL_TYPE_DATETIME || if (ifp->field_type() == MYSQL_TYPE_DATETIME ||
ifp->field_type() == MYSQL_TYPE_DATETIME2 || ifp->field_type() == MYSQL_TYPE_DATETIME2 ||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP || ifp->field_type() == MYSQL_TYPE_TIMESTAMP ||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP2 || ifp->field_type() == MYSQL_TYPE_TIMESTAMP2)
funcName == "add_time")
{ {
CalpontSystemCatalog::ColType ct; CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::DATETIME; ct.colDataType = CalpontSystemCatalog::DATETIME;

View File

@ -2065,9 +2065,9 @@ std::string DataConvert::datetimeToString( long long datetimevalue, long decima
{ {
snprintf(buf + strlen(buf), 21 + decimals, ".%d", dt.msecond); snprintf(buf + strlen(buf), 21 + decimals, ".%d", dt.msecond);
// Pad end with zeros // Pad end with zeros
if (strlen(buf) < (21 + decimals)) if (strlen(buf) < (size_t)(21 + decimals))
{ {
sprintf(buf + strlen(buf), "%0*d", 21 + decimals - strlen(buf), 0); sprintf(buf + strlen(buf), "%0*d", (int)(21 + decimals - strlen(buf)), 0);
} }
} }
return buf; return buf;
@ -2091,9 +2091,9 @@ std::string DataConvert::timeToString( long long timevalue, long decimals )
size_t start = strlen(buf); size_t start = strlen(buf);
snprintf(buf + strlen(buf), 12 + decimals, ".%d", dt.msecond); snprintf(buf + strlen(buf), 12 + decimals, ".%d", dt.msecond);
// Pad end with zeros // Pad end with zeros
if (strlen(buf) - start < decimals) if (strlen(buf) - start < (size_t)decimals)
{ {
sprintf(buf + strlen(buf), "%0*d", decimals - (strlen(buf) - start), 0); sprintf(buf + strlen(buf), "%0*d", (int)(decimals - (strlen(buf) - start) + 1), 0);
} }
} }
return buf; return buf;
@ -2642,7 +2642,7 @@ int64_t DataConvert::intToTime(int64_t data)
atime.second = 0; atime.second = 0;
atime.msecond = 0; atime.msecond = 0;
return *(reinterpret_cast<uint64_t*>(&atime)); return *(reinterpret_cast<int64_t*>(&atime));
} }
snprintf( buf, 15, "%llu", (long long unsigned int)data); snprintf( buf, 15, "%llu", (long long unsigned int)data);
@ -2696,7 +2696,7 @@ int64_t DataConvert::stringToTime(const string& data)
// -34 <= D <= 34 // -34 <= D <= 34
// -838 <= H <= 838 // -838 <= H <= 838
uint64_t min = 0, sec = 0, msec = 0; uint64_t min = 0, sec = 0, msec = 0;
int64_t day = 0, hour = 0; int64_t day = -1, hour = 0;
string time, hms, ms; string time, hms, ms;
char* end = NULL; char* end = NULL;

View File

@ -173,7 +173,7 @@ struct DateTime
inline inline
int64_t DateTime::convertToMySQLint() const int64_t DateTime::convertToMySQLint() const
{ {
return (int64_t) (year * 10000000000000000LL) + (month * 100000000000000) + (day * 1000000000000) + (hour * 10000000000) + (minute * 100000000) + (second * 1000000) + msecond; return (int64_t) (year * 10000000000LL) + (month * 100000000) + (day * 1000000) + (hour * 10000) + (minute * 100) + second;
} }
inline inline
@ -235,16 +235,11 @@ void Time::reset()
inline inline
int64_t Time::convertToMySQLint() const int64_t Time::convertToMySQLint() const
{ {
return (int64_t) (hour * 10000000000) + (minute * 100000000) + (second * 1000000) + msecond; 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}; static uint32_t daysInMonth[13] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
inline uint32_t getDaysInMonth(uint32_t month)
{
return ( (month < 1 || month > 12) ? 0 : daysInMonth[month - 1]);
}
inline bool isLeapYear ( int year) inline bool isLeapYear ( int year)
{ {
if ( year % 400 == 0 ) if ( year % 400 == 0 )
@ -256,6 +251,18 @@ inline bool isLeapYear ( int year)
return false; return false;
} }
inline uint32_t getDaysInMonth(uint32_t month, int year)
{
if (month < 1 || month > 12)
return 0;
uint32_t days = daysInMonth[month - 1];
if ((month == 2) && isLeapYear(year))
days++;
return days;
}
inline inline
bool isDateValid ( int day, int month, int year) bool isDateValid ( int day, int month, int year)
{ {
@ -266,11 +273,7 @@ bool isDateValid ( int day, int month, int year)
return true; return true;
} }
int daycheck = getDaysInMonth( month ); int daycheck = getDaysInMonth( month, year );
if ( month == 2 && isLeapYear( year ) )
// 29 days in February in a leap year
daycheck = 29;
if ( ( year < 1000 ) || ( year > 9999 ) ) if ( ( year < 1000 ) || ( year > 9999 ) )
valid = false; valid = false;
@ -407,7 +410,7 @@ public:
* @param data the columns string representation of it's data * @param data the columns string representation of it's data
*/ */
EXPORT static std::string datetimeToString( long long datetimevalue, long decimals = 0 ); EXPORT static std::string datetimeToString( long long datetimevalue, long decimals = 0 );
static inline void datetimeToString( long long datetimevalue, char* buf, unsigned int buflen ); static inline void datetimeToString( long long datetimevalue, char* buf, unsigned int buflen, long decimals = 0 );
/** /**
* @brief convert a columns data from native format to a string * @brief convert a columns data from native format to a string
@ -416,7 +419,7 @@ public:
* @param data the columns string representation of it's data * @param data the columns string representation of it's data
*/ */
EXPORT static std::string timeToString( long long timevalue, long decimals = 0 ); EXPORT static std::string timeToString( long long timevalue, long decimals = 0 );
static inline void timeToString( long long timevalue, char* buf, unsigned int buflen ); static inline void timeToString( long long timevalue, char* buf, unsigned int buflen, long decimals = 0);
/** /**
* @brief convert a columns data from native format to a string * @brief convert a columns data from native format to a string
@ -537,37 +540,48 @@ inline void DataConvert::dateToString( int datevalue, char* buf, unsigned int bu
); );
} }
inline void DataConvert::datetimeToString( long long datetimevalue, char* buf, unsigned int buflen ) inline void DataConvert::datetimeToString( long long datetimevalue, char* buf, unsigned int buflen, long decimals )
{ {
// 10 is default which means we don't need microseconds
if (decimals > 6 || decimals < 0)
{
decimals = 0;
}
int msec = 0;
if ((datetimevalue & 0xfffff) > 0) if ((datetimevalue & 0xfffff) > 0)
{ {
snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d.%d", msec = (unsigned)((datetimevalue) & 0xfffff);
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f),
(unsigned)((datetimevalue) & 0xfffff)
);
} }
else snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d",
(unsigned)((datetimevalue >> 48) & 0xffff),
(unsigned)((datetimevalue >> 44) & 0xf),
(unsigned)((datetimevalue >> 38) & 0x3f),
(unsigned)((datetimevalue >> 32) & 0x3f),
(unsigned)((datetimevalue >> 26) & 0x3f),
(unsigned)((datetimevalue >> 20) & 0x3f)
);
if (msec || decimals)
{ {
snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d", size_t start = strlen(buf);
(unsigned)((datetimevalue >> 48) & 0xffff), snprintf(buf + strlen(buf), buflen - start, ".%d", msec);
(unsigned)((datetimevalue >> 44) & 0xf), // Pad end with zeros
(unsigned)((datetimevalue >> 38) & 0x3f), if (strlen(buf) - start < (size_t)decimals)
(unsigned)((datetimevalue >> 32) & 0x3f), {
(unsigned)((datetimevalue >> 26) & 0x3f), snprintf(buf + strlen(buf), buflen - strlen(buf), "%0*d", (int)(decimals - (strlen(buf) - start) + 1), 0);
(unsigned)((datetimevalue >> 20) & 0x3f) }
);
} }
} }
inline void DataConvert::timeToString( long long timevalue, char* buf, unsigned int buflen ) inline void DataConvert::timeToString( long long timevalue, char* buf, unsigned int buflen, long decimals )
{ {
// 10 is default which means we don't need microseconds
if (decimals > 6 || decimals < 0)
{
decimals = 0;
}
// Handle negative correctly // Handle negative correctly
int hour = 0; int hour = 0, msec = 0;
if ((timevalue >> 40) & 0x800) if ((timevalue >> 40) & 0x800)
{ {
hour = 0xfffff000; hour = 0xfffff000;
@ -577,20 +591,23 @@ inline void DataConvert::timeToString( long long timevalue, char* buf, unsigned
if ((timevalue & 0xffffff) > 0) if ((timevalue & 0xffffff) > 0)
{ {
snprintf( buf, buflen, "%02d:%02d:%02d.%d", msec = (unsigned)((timevalue) & 0xffffff);
hour,
(unsigned)((timevalue >> 32) & 0xff),
(unsigned)((timevalue >> 24) & 0xff),
(unsigned)((timevalue) & 0xffffff)
);
} }
else snprintf( buf, buflen, "%02d:%02d:%02d",
hour,
(unsigned)((timevalue >> 32) & 0xff),
(unsigned)((timevalue >> 24) & 0xff)
);
if (msec || decimals)
{ {
snprintf( buf, buflen, "%02d:%02d:%02d", size_t start = strlen(buf);
hour, snprintf(buf + strlen(buf), buflen - start, ".%d", msec);
(unsigned)((timevalue >> 32) & 0xff), // Pad end with zeros
(unsigned)((timevalue >> 24) & 0xff) if (strlen(buf) - start < (size_t)decimals)
); {
snprintf(buf + strlen(buf), buflen - strlen(buf), "%0*d", (int)(decimals - (strlen(buf) - start) + 1), 0);
}
} }
} }

View File

@ -80,16 +80,15 @@ int64_t addTime(DateTime& dt1, Time& dt2)
} }
hour = (signed)(dt1.hour + dt2.hour + min / 60); hour = (signed)(dt1.hour + dt2.hour + min / 60);
dt.hour = tmp = hour % 24;
// if (tmp < -1) if ((hour < 0) || (hour > 23))
if (tmp < 0) // fix for subtime dlh
{ {
dt.hour = tmp + 24; dt.hour = hour % 24;
dt2.day--; dt2.day = hour / 24;
} }
day = (signed)(dt1.day + dt2.day + hour / 24); day = (signed)(dt1.day + dt2.day);
if (isLeapYear(dt1.year) && dt1.month == 2) if (isLeapYear(dt1.year) && dt1.month == 2)
day--; day--;
@ -97,7 +96,7 @@ int64_t addTime(DateTime& dt1, Time& dt2)
month = dt1.month; month = dt1.month;
int addyear = 0; int addyear = 0;
if (dt2.day < 0 || dt2.hour < 0) if (day < 0)
{ {
int monthSave = month; int monthSave = month;
@ -106,7 +105,7 @@ int64_t addTime(DateTime& dt1, Time& dt2)
month = (month == 1 ? 12 : month - 1); month = (month == 1 ? 12 : month - 1);
for (; day <= 0 && month > 0; month--) for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month); day += getDaysInMonth(month, dt1.year);
month++; month++;
// month=12; // month=12;
@ -119,10 +118,10 @@ int64_t addTime(DateTime& dt1, Time& dt2)
{ {
int monthSave = month; int monthSave = month;
while (day > getDaysInMonth(month)) while (day > getDaysInMonth(month, dt1.year))
{ {
for (; day > getDaysInMonth(month) && month <= 12; month++) for (; day > getDaysInMonth(month, dt1.year) && month <= 12; month++)
day -= getDaysInMonth(month); day -= getDaysInMonth(month, dt1.year);
if (month > 12) if (month > 12)
month = 1; month = 1;
@ -175,8 +174,23 @@ int64_t addTime(Time& dt1, Time& dt2)
dt2.hour--; dt2.hour--;
} }
hour = (signed)(dt1.hour + dt2.hour + min / 60); dt.hour = (signed)(dt1.hour + dt2.hour + min / 60);
dt.hour = tmp = hour % 838;
// Saturation
if (dt.hour > 838)
{
dt.hour = 838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
else if (dt.hour < -838)
{
dt.hour = -838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
return *(reinterpret_cast<int64_t*>(&dt)); return *(reinterpret_cast<int64_t*>(&dt));
} }
@ -226,6 +240,13 @@ int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row,
if (isNull) if (isNull)
return -1; return -1;
// Adding a zero date to a time is always NULL
if (val1 == 0)
{
isNull = true;
return -1;
}
const string& val2 = parm[1]->data()->getStrVal(row, isNull); const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull); int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1; DateTime dt1;
@ -311,7 +332,7 @@ int64_t Func_add_time::getTimeIntVal(rowgroup::Row& row,
const string& val2 = parm[1]->data()->getStrVal(row, isNull); const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull); int sign = parm[2]->data()->getIntVal(row, isNull);
Time dt1; Time dt1;
dt1.hour = (val1 >> 40) & 0xff; dt1.hour = (val1 >> 40) & 0xfff;
dt1.minute = (val1 >> 32) & 0xff; dt1.minute = (val1 >> 32) & 0xff;
dt1.second = (val1 >> 24) & 0xff; dt1.second = (val1 >> 24) & 0xff;
dt1.msecond = val1 & 0xffffff; dt1.msecond = val1 & 0xffffff;

View File

@ -158,20 +158,21 @@ inline bool getBool(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::TIME: case execplan::CalpontSystemCatalog::TIME:
{ {
int64_t val = pm[0]->data()->getTimeIntVal(row, isNull); // Shift out unused day for compare
int64_t val = pm[0]->data()->getTimeIntVal(row, isNull) << 12;
if (notBetween) if (notBetween)
{ {
if (!numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull)) && !isNull) if (!numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull) << 12) && !isNull)
return true; return true;
isNull = false; isNull = false;
return (!numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull)) && !isNull); return (!numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull) << 12) && !isNull);
} }
return !isNull && return !isNull &&
numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull)) && numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull) << 12) &&
numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull)); numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull) << 12);
} }
case execplan::CalpontSystemCatalog::DOUBLE: case execplan::CalpontSystemCatalog::DOUBLE:
@ -265,7 +266,8 @@ CalpontSystemCatalog::ColType Func_between::operationType( FunctionParm& fp, Cal
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT && fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) || fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) ||
ct.colDataType == CalpontSystemCatalog::DATE || ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME) ct.colDataType == CalpontSystemCatalog::DATETIME ||
ct.colDataType == CalpontSystemCatalog::TIME)
{ {
allString = false; allString = false;
} }
@ -293,6 +295,23 @@ CalpontSystemCatalog::ColType Func_between::operationType( FunctionParm& fp, Cal
} }
} }
} }
else if (op.operationType().colDataType == CalpontSystemCatalog::TIME)
{
ConstantColumn* cc = NULL;
for (uint32_t i = 1; i < fp.size(); i++)
{
cc = dynamic_cast<ConstantColumn*>(fp[i]->data());
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::timeToInt(result.strVal);
cc->result(result);
}
}
}
return ct; return ct;
} }

View File

@ -131,6 +131,90 @@ long long dateGet( uint64_t time, IntervalColumn::interval_type unit, bool dateT
throw runtime_error("unit type is not supported: " + unit); throw runtime_error("unit type is not supported: " + unit);
}; };
} }
long long timeGet( uint64_t time, IntervalColumn::interval_type unit )
{
int32_t hour = 0,
min = 0,
sec = 0,
msec = 0,
day = 0;
min = (int32_t)((time >> 32) & 0xff);
sec = (int32_t)((time >> 24) & 0xff);
msec = (int32_t)((time & 0xfffff));
// If negative, mask so it doesn't turn positive
int64_t mask = 0;
if ((time >> 40) & 0x800)
mask = 0xfffffffffffff000;
hour = mask | ((time >> 40) & 0xfff);
// Always positive!
day = abs(hour / 24);
switch ( unit )
{
case IntervalColumn::INTERVAL_YEAR:
case IntervalColumn::INTERVAL_MONTH:
return 0;
case IntervalColumn::INTERVAL_DAY:
return day;
case IntervalColumn::INTERVAL_HOUR:
return hour;
case IntervalColumn::INTERVAL_MINUTE:
return min;
case IntervalColumn::INTERVAL_SECOND:
return sec;
case IntervalColumn::INTERVAL_MICROSECOND:
return msec;
case IntervalColumn::INTERVAL_QUARTER:
case IntervalColumn::INTERVAL_WEEK:
case IntervalColumn::INTERVAL_YEAR_MONTH:
return 0;
case IntervalColumn::INTERVAL_DAY_HOUR:
return (day * 100) + hour;
case IntervalColumn::INTERVAL_DAY_MINUTE:
return (day * 10000) + (hour * 100) + min;
case IntervalColumn::INTERVAL_DAY_SECOND:
return (day * 1000000) + (hour * 10000) + (min * 100) + sec;
case IntervalColumn::INTERVAL_HOUR_MINUTE:
return (hour * 100) + min;
case IntervalColumn::INTERVAL_HOUR_SECOND:
return (hour * 10000) + (min * 100) + sec;
case IntervalColumn::INTERVAL_MINUTE_SECOND:
return (min * 100) + sec;
case IntervalColumn::INTERVAL_DAY_MICROSECOND:
return (((day * 1000000) + (hour * 10000) + (min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_HOUR_MICROSECOND:
return (((hour * 10000) + (min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_MINUTE_MICROSECOND:
return (((min * 100) + sec) * 1000000) + msec;
case IntervalColumn::INTERVAL_SECOND_MICROSECOND:
return (sec * 1000000) + msec;
default:
throw runtime_error("unit type is not supported: " + unit);
};
}
} }
namespace funcexp namespace funcexp
@ -148,16 +232,21 @@ int64_t Func_extract::getIntVal(rowgroup::Row& row,
{ {
IntervalColumn::interval_type unit = static_cast<IntervalColumn::interval_type>(parm[1]->data()->getIntVal(row, isNull)); IntervalColumn::interval_type unit = static_cast<IntervalColumn::interval_type>(parm[1]->data()->getIntVal(row, isNull));
uint64_t time; uint64_t time;
bool isTime = false;
//@bug4678 handle conversion from non date/datetime datatype //@bug4678 handle conversion from non date/datetime datatype
switch (parm[0]->data()->resultType().colDataType) switch (parm[0]->data()->resultType().colDataType)
{ {
case CalpontSystemCatalog::DATE: case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME: case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::TIME:
time = parm[0]->data()->getDatetimeIntVal(row, isNull); time = parm[0]->data()->getDatetimeIntVal(row, isNull);
break; break;
case CalpontSystemCatalog::TIME:
time = parm[0]->data()->getTimeIntVal(row, isNull);
isTime = true;
break;
case CalpontSystemCatalog::VARCHAR: case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT: case CalpontSystemCatalog::TEXT:
@ -182,7 +271,11 @@ int64_t Func_extract::getIntVal(rowgroup::Row& row,
time = parm[0]->data()->getIntVal(row, isNull); time = parm[0]->data()->getIntVal(row, isNull);
} }
long long value = dateGet( time, unit, false ); long long value;
if (isTime)
value = timeGet( time, unit );
else
value = dateGet( time, unit, false );
return value; return value;
} }

View File

@ -211,13 +211,14 @@ int64_t Func_greatest::getTimeIntVal(rowgroup::Row& row,
bool& isNull, bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct) execplan::CalpontSystemCatalog::ColType& ct)
{ {
int64_t str = fp[0]->data()->getTimeIntVal(row, isNull); // Strip off unused day
int64_t str = fp[0]->data()->getTimeIntVal(row, isNull) << 12;
int64_t greatestStr = str; int64_t greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++) for (uint32_t i = 1; i < fp.size(); i++)
{ {
int64_t str1 = fp[i]->data()->getTimeIntVal(row, isNull); int64_t str1 = fp[i]->data()->getTimeIntVal(row, isNull) << 12;
if ( greatestStr < str1 ) if ( greatestStr < str1 )
greatestStr = str1; greatestStr = str1;

View File

@ -48,6 +48,7 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType& op_ct) CalpontSystemCatalog::ColType& op_ct)
{ {
int64_t val = 0; int64_t val = 0;
bool isTime = false;
switch (parm[0]->data()->resultType().colDataType) switch (parm[0]->data()->resultType().colDataType)
{ {
@ -110,7 +111,8 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::TIME: case execplan::CalpontSystemCatalog::TIME:
{ {
val = parm[0]->data()->getDatetimeIntVal(row, isNull); isTime = true;
val = parm[0]->data()->getTimeIntVal(row, isNull);
break; break;
} }
@ -123,10 +125,20 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
if (isNull) if (isNull)
return -1; return -1;
if ( val < 1000000000 ) if (isTime)
return 0; {
// If negative, mask so it doesn't turn positive
int64_t mask = 0;
if ((val >> 40) & 0x800)
mask = 0xfffffffffffff000;
val = mask | ((val >> 40) & 0xfff);
}
else
{
val = (val >> 32) & 0x3f;
}
return (uint32_t)((val >> 32) & 0x3f); return val;
} }

View File

@ -187,13 +187,14 @@ int64_t Func_least::getTimeIntVal(rowgroup::Row& row,
bool& isNull, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct) execplan::CalpontSystemCatalog::ColType& op_ct)
{ {
int64_t str = fp[0]->data()->getTimeIntVal(row, isNull); // Strip off unused day
int64_t str = fp[0]->data()->getTimeIntVal(row, isNull) << 12;
int64_t leastStr = str; int64_t leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++) for (uint32_t i = 1; i < fp.size(); i++)
{ {
int64_t str1 = fp[i]->data()->getTimeIntVal(row, isNull); int64_t str1 = fp[i]->data()->getTimeIntVal(row, isNull) << 12;
if ( leastStr > str1 ) if ( leastStr > str1 )
leastStr = str1; leastStr = str1;

View File

@ -59,7 +59,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::TINYINT: case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT: case execplan::CalpontSystemCatalog::SMALLINT:
{ {
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull)); val = dataconvert::DataConvert::intToTime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1) if (val == -1)
isNull = true; isNull = true;
@ -73,7 +73,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
{ {
if (parm[0]->data()->resultType().scale) if (parm[0]->data()->resultType().scale)
{ {
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull)); val = dataconvert::DataConvert::intToTime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1) if (val == -1)
isNull = true; isNull = true;
@ -96,7 +96,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
case execplan::CalpontSystemCatalog::CHAR: case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT: case execplan::CalpontSystemCatalog::TEXT:
{ {
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull)); val = dataconvert::DataConvert::stringToTime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1) if (val == -1)
isNull = true; isNull = true;
@ -106,16 +106,14 @@ string Func_time::getStrVal(rowgroup::Row& row,
break; break;
} }
case execplan::CalpontSystemCatalog::DATE: case execplan::CalpontSystemCatalog::TIME:
{ {
val = parm[0]->data()->getDatetimeIntVal(row, isNull); val = parm[0]->data()->getTimeIntVal(row, isNull);
break; break;
} }
case execplan::CalpontSystemCatalog::TIME:
case execplan::CalpontSystemCatalog::DATETIME: case execplan::CalpontSystemCatalog::DATETIME:
{ {
val = parm[0]->data()->getDatetimeIntVal(row, isNull); val = parm[0]->data()->getTimeIntVal(row, isNull);
break; break;
} }
@ -129,9 +127,9 @@ string Func_time::getStrVal(rowgroup::Row& row,
return ""; return "";
char buf[30] = {'\0'}; char buf[30] = {'\0'};
dataconvert::DataConvert::datetimeToString(val, buf, sizeof(buf)); dataconvert::DataConvert::timeToString(val, buf, sizeof(buf));
string time(buf); string time(buf);
return time.substr(11, 80); return time;
} }
int64_t Func_time::getIntVal(rowgroup::Row& row, int64_t Func_time::getIntVal(rowgroup::Row& row,
@ -139,7 +137,7 @@ int64_t Func_time::getIntVal(rowgroup::Row& row,
bool& isNull, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct) execplan::CalpontSystemCatalog::ColType& op_ct)
{ {
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, fp, isNull, op_ct)); return dataconvert::DataConvert::timeToInt(getStrVal(row, fp, isNull, op_ct));
} }
double Func_time::getDoubleVal(rowgroup::Row& row, double Func_time::getDoubleVal(rowgroup::Row& row,