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:
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user