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 Function fixes
Fixes most of the functions in funcexp so that time and datetime's microseconds are handled correctly
This commit is contained in:
@ -666,14 +666,14 @@ inline const std::string& TreeNode::getStrVal()
|
||||
|
||||
case CalpontSystemCatalog::DATETIME:
|
||||
{
|
||||
dataconvert::DataConvert::datetimeToString(fResult.intVal, tmp, 255);
|
||||
dataconvert::DataConvert::datetimeToString(fResult.intVal, tmp, 255, fResultType.precision);
|
||||
fResult.strVal = std::string(tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
case CalpontSystemCatalog::TIME:
|
||||
{
|
||||
dataconvert::DataConvert::timeToString(fResult.intVal, tmp, 255);
|
||||
dataconvert::DataConvert::timeToString(fResult.intVal, tmp, 255, fResultType.precision);
|
||||
fResult.strVal = std::string(tmp);
|
||||
break;
|
||||
}
|
||||
@ -992,11 +992,20 @@ inline int64_t TreeNode::getDatetimeIntVal()
|
||||
else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIME)
|
||||
{
|
||||
dataconvert::Time tt;
|
||||
int day = 0;
|
||||
|
||||
memcpy(&tt, &fResult.intVal, 8);
|
||||
if (tt.hour > 23 || tt.hour < 0)
|
||||
throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from time (out of range).");
|
||||
dataconvert::DateTime dt(0, 0, 0, tt.hour, tt.minute, tt.second, tt.msecond);
|
||||
// Note, this should probably be current date +/- time
|
||||
if (tt.hour > 23)
|
||||
{
|
||||
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);
|
||||
return fResult.intVal;
|
||||
}
|
||||
|
@ -3518,8 +3518,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non
|
||||
if (ifp->field_type() == MYSQL_TYPE_DATETIME ||
|
||||
ifp->field_type() == MYSQL_TYPE_DATETIME2 ||
|
||||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP ||
|
||||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP2 ||
|
||||
funcName == "add_time")
|
||||
ifp->field_type() == MYSQL_TYPE_TIMESTAMP2)
|
||||
{
|
||||
CalpontSystemCatalog::ColType ct;
|
||||
ct.colDataType = CalpontSystemCatalog::DATETIME;
|
||||
|
@ -2065,9 +2065,9 @@ std::string DataConvert::datetimeToString( long long datetimevalue, long decima
|
||||
{
|
||||
snprintf(buf + strlen(buf), 21 + decimals, ".%d", dt.msecond);
|
||||
// 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;
|
||||
@ -2091,9 +2091,9 @@ std::string DataConvert::timeToString( long long timevalue, long decimals )
|
||||
size_t start = strlen(buf);
|
||||
snprintf(buf + strlen(buf), 12 + decimals, ".%d", dt.msecond);
|
||||
// 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;
|
||||
@ -2642,7 +2642,7 @@ int64_t DataConvert::intToTime(int64_t data)
|
||||
atime.second = 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);
|
||||
@ -2696,7 +2696,7 @@ int64_t DataConvert::stringToTime(const string& data)
|
||||
// -34 <= D <= 34
|
||||
// -838 <= H <= 838
|
||||
uint64_t min = 0, sec = 0, msec = 0;
|
||||
int64_t day = 0, hour = 0;
|
||||
int64_t day = -1, hour = 0;
|
||||
string time, hms, ms;
|
||||
char* end = NULL;
|
||||
|
||||
|
@ -173,7 +173,7 @@ struct DateTime
|
||||
inline
|
||||
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
|
||||
@ -235,16 +235,11 @@ void Time::reset()
|
||||
inline
|
||||
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};
|
||||
|
||||
inline uint32_t getDaysInMonth(uint32_t month)
|
||||
{
|
||||
return ( (month < 1 || month > 12) ? 0 : daysInMonth[month - 1]);
|
||||
}
|
||||
|
||||
inline bool isLeapYear ( int year)
|
||||
{
|
||||
if ( year % 400 == 0 )
|
||||
@ -256,6 +251,18 @@ inline bool isLeapYear ( int year)
|
||||
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
|
||||
bool isDateValid ( int day, int month, int year)
|
||||
{
|
||||
@ -266,11 +273,7 @@ bool isDateValid ( int day, int month, int year)
|
||||
return true;
|
||||
}
|
||||
|
||||
int daycheck = getDaysInMonth( month );
|
||||
|
||||
if ( month == 2 && isLeapYear( year ) )
|
||||
// 29 days in February in a leap year
|
||||
daycheck = 29;
|
||||
int daycheck = getDaysInMonth( month, year );
|
||||
|
||||
if ( ( year < 1000 ) || ( year > 9999 ) )
|
||||
valid = false;
|
||||
@ -407,7 +410,7 @@ public:
|
||||
* @param data the columns string representation of it's data
|
||||
*/
|
||||
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
|
||||
@ -416,7 +419,7 @@ public:
|
||||
* @param data the columns string representation of it's data
|
||||
*/
|
||||
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
|
||||
@ -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)
|
||||
{
|
||||
snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d.%d",
|
||||
(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)
|
||||
);
|
||||
msec = (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",
|
||||
(unsigned)((datetimevalue >> 48) & 0xffff),
|
||||
(unsigned)((datetimevalue >> 44) & 0xf),
|
||||
(unsigned)((datetimevalue >> 38) & 0x3f),
|
||||
(unsigned)((datetimevalue >> 32) & 0x3f),
|
||||
(unsigned)((datetimevalue >> 26) & 0x3f),
|
||||
(unsigned)((datetimevalue >> 20) & 0x3f)
|
||||
);
|
||||
size_t start = strlen(buf);
|
||||
snprintf(buf + strlen(buf), buflen - start, ".%d", msec);
|
||||
// Pad end with zeros
|
||||
if (strlen(buf) - start < (size_t)decimals)
|
||||
{
|
||||
snprintf(buf + strlen(buf), buflen - strlen(buf), "%0*d", (int)(decimals - (strlen(buf) - start) + 1), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
int hour = 0;
|
||||
int hour = 0, msec = 0;
|
||||
if ((timevalue >> 40) & 0x800)
|
||||
{
|
||||
hour = 0xfffff000;
|
||||
@ -577,20 +591,23 @@ inline void DataConvert::timeToString( long long timevalue, char* buf, unsigned
|
||||
|
||||
if ((timevalue & 0xffffff) > 0)
|
||||
{
|
||||
snprintf( buf, buflen, "%02d:%02d:%02d.%d",
|
||||
hour,
|
||||
(unsigned)((timevalue >> 32) & 0xff),
|
||||
(unsigned)((timevalue >> 24) & 0xff),
|
||||
(unsigned)((timevalue) & 0xffffff)
|
||||
);
|
||||
msec = (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",
|
||||
hour,
|
||||
(unsigned)((timevalue >> 32) & 0xff),
|
||||
(unsigned)((timevalue >> 24) & 0xff)
|
||||
);
|
||||
size_t start = strlen(buf);
|
||||
snprintf(buf + strlen(buf), buflen - start, ".%d", msec);
|
||||
// Pad end with zeros
|
||||
if (strlen(buf) - start < (size_t)decimals)
|
||||
{
|
||||
snprintf(buf + strlen(buf), buflen - strlen(buf), "%0*d", (int)(decimals - (strlen(buf) - start) + 1), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,16 +80,15 @@ int64_t addTime(DateTime& dt1, Time& dt2)
|
||||
}
|
||||
|
||||
hour = (signed)(dt1.hour + dt2.hour + min / 60);
|
||||
dt.hour = tmp = hour % 24;
|
||||
|
||||
// if (tmp < -1)
|
||||
if (tmp < 0) // fix for subtime dlh
|
||||
if ((hour < 0) || (hour > 23))
|
||||
{
|
||||
dt.hour = tmp + 24;
|
||||
dt2.day--;
|
||||
dt.hour = hour % 24;
|
||||
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)
|
||||
day--;
|
||||
@ -97,7 +96,7 @@ int64_t addTime(DateTime& dt1, Time& dt2)
|
||||
month = dt1.month;
|
||||
int addyear = 0;
|
||||
|
||||
if (dt2.day < 0 || dt2.hour < 0)
|
||||
if (day < 0)
|
||||
{
|
||||
int monthSave = month;
|
||||
|
||||
@ -106,7 +105,7 @@ int64_t addTime(DateTime& dt1, Time& dt2)
|
||||
month = (month == 1 ? 12 : month - 1);
|
||||
|
||||
for (; day <= 0 && month > 0; month--)
|
||||
day += getDaysInMonth(month);
|
||||
day += getDaysInMonth(month, dt1.year);
|
||||
|
||||
month++;
|
||||
// month=12;
|
||||
@ -119,10 +118,10 @@ int64_t addTime(DateTime& dt1, Time& dt2)
|
||||
{
|
||||
int monthSave = month;
|
||||
|
||||
while (day > getDaysInMonth(month))
|
||||
while (day > getDaysInMonth(month, dt1.year))
|
||||
{
|
||||
for (; day > getDaysInMonth(month) && month <= 12; month++)
|
||||
day -= getDaysInMonth(month);
|
||||
for (; day > getDaysInMonth(month, dt1.year) && month <= 12; month++)
|
||||
day -= getDaysInMonth(month, dt1.year);
|
||||
|
||||
if (month > 12)
|
||||
month = 1;
|
||||
@ -175,8 +174,23 @@ int64_t addTime(Time& dt1, Time& dt2)
|
||||
dt2.hour--;
|
||||
}
|
||||
|
||||
hour = (signed)(dt1.hour + dt2.hour + min / 60);
|
||||
dt.hour = tmp = hour % 838;
|
||||
dt.hour = (signed)(dt1.hour + dt2.hour + min / 60);
|
||||
|
||||
// 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));
|
||||
}
|
||||
@ -226,6 +240,13 @@ int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row,
|
||||
if (isNull)
|
||||
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);
|
||||
int sign = parm[2]->data()->getIntVal(row, isNull);
|
||||
DateTime dt1;
|
||||
@ -311,7 +332,7 @@ int64_t Func_add_time::getTimeIntVal(rowgroup::Row& row,
|
||||
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
|
||||
int sign = parm[2]->data()->getIntVal(row, isNull);
|
||||
Time dt1;
|
||||
dt1.hour = (val1 >> 40) & 0xff;
|
||||
dt1.hour = (val1 >> 40) & 0xfff;
|
||||
dt1.minute = (val1 >> 32) & 0xff;
|
||||
dt1.second = (val1 >> 24) & 0xff;
|
||||
dt1.msecond = val1 & 0xffffff;
|
||||
|
@ -158,20 +158,21 @@ inline bool getBool(rowgroup::Row& row,
|
||||
|
||||
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 (!numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull)) && !isNull)
|
||||
if (!numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull) << 12) && !isNull)
|
||||
return true;
|
||||
|
||||
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 &&
|
||||
numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull)) &&
|
||||
numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull));
|
||||
numericGE(val, pm[1]->data()->getTimeIntVal(row, isNull) << 12) &&
|
||||
numericLE(val, pm[2]->data()->getTimeIntVal(row, isNull) << 12);
|
||||
}
|
||||
|
||||
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::VARCHAR) ||
|
||||
ct.colDataType == CalpontSystemCatalog::DATE ||
|
||||
ct.colDataType == CalpontSystemCatalog::DATETIME)
|
||||
ct.colDataType == CalpontSystemCatalog::DATETIME ||
|
||||
ct.colDataType == CalpontSystemCatalog::TIME)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
@ -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));
|
||||
uint64_t time;
|
||||
bool isTime = false;
|
||||
|
||||
//@bug4678 handle conversion from non date/datetime datatype
|
||||
switch (parm[0]->data()->resultType().colDataType)
|
||||
{
|
||||
case CalpontSystemCatalog::DATE:
|
||||
case CalpontSystemCatalog::DATETIME:
|
||||
case CalpontSystemCatalog::TIME:
|
||||
time = parm[0]->data()->getDatetimeIntVal(row, isNull);
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::TIME:
|
||||
time = parm[0]->data()->getTimeIntVal(row, isNull);
|
||||
isTime = true;
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::VARCHAR:
|
||||
case CalpontSystemCatalog::CHAR:
|
||||
case CalpontSystemCatalog::TEXT:
|
||||
@ -182,7 +271,11 @@ int64_t Func_extract::getIntVal(rowgroup::Row& row,
|
||||
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;
|
||||
}
|
||||
|
@ -211,13 +211,14 @@ int64_t Func_greatest::getTimeIntVal(rowgroup::Row& row,
|
||||
bool& isNull,
|
||||
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;
|
||||
|
||||
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 )
|
||||
greatestStr = str1;
|
||||
|
@ -48,6 +48,7 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
|
||||
CalpontSystemCatalog::ColType& op_ct)
|
||||
{
|
||||
int64_t val = 0;
|
||||
bool isTime = false;
|
||||
|
||||
switch (parm[0]->data()->resultType().colDataType)
|
||||
{
|
||||
@ -110,7 +111,8 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
|
||||
|
||||
case execplan::CalpontSystemCatalog::TIME:
|
||||
{
|
||||
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
|
||||
isTime = true;
|
||||
val = parm[0]->data()->getTimeIntVal(row, isNull);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -123,10 +125,20 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row,
|
||||
if (isNull)
|
||||
return -1;
|
||||
|
||||
if ( val < 1000000000 )
|
||||
return 0;
|
||||
if (isTime)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,13 +187,14 @@ int64_t Func_least::getTimeIntVal(rowgroup::Row& row,
|
||||
bool& isNull,
|
||||
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;
|
||||
|
||||
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 )
|
||||
leastStr = str1;
|
||||
|
@ -59,7 +59,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
|
||||
case execplan::CalpontSystemCatalog::TINYINT:
|
||||
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)
|
||||
isNull = true;
|
||||
@ -73,7 +73,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
|
||||
{
|
||||
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)
|
||||
isNull = true;
|
||||
@ -96,7 +96,7 @@ string Func_time::getStrVal(rowgroup::Row& row,
|
||||
case execplan::CalpontSystemCatalog::CHAR:
|
||||
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)
|
||||
isNull = true;
|
||||
@ -106,16 +106,14 @@ string Func_time::getStrVal(rowgroup::Row& row,
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::DATE:
|
||||
case execplan::CalpontSystemCatalog::TIME:
|
||||
{
|
||||
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
|
||||
val = parm[0]->data()->getTimeIntVal(row, isNull);
|
||||
break;
|
||||
}
|
||||
|
||||
case execplan::CalpontSystemCatalog::TIME:
|
||||
case execplan::CalpontSystemCatalog::DATETIME:
|
||||
{
|
||||
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
|
||||
val = parm[0]->data()->getTimeIntVal(row, isNull);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -129,9 +127,9 @@ string Func_time::getStrVal(rowgroup::Row& row,
|
||||
return "";
|
||||
|
||||
char buf[30] = {'\0'};
|
||||
dataconvert::DataConvert::datetimeToString(val, buf, sizeof(buf));
|
||||
dataconvert::DataConvert::timeToString(val, buf, sizeof(buf));
|
||||
string time(buf);
|
||||
return time.substr(11, 80);
|
||||
return time;
|
||||
}
|
||||
|
||||
int64_t Func_time::getIntVal(rowgroup::Row& row,
|
||||
@ -139,7 +137,7 @@ int64_t Func_time::getIntVal(rowgroup::Row& row,
|
||||
bool& isNull,
|
||||
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,
|
||||
|
Reference in New Issue
Block a user