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

Merge pull request #494 from mariadb-corporation/MCOL-1433

MCOL-1433 Fix several functions for TIME handling
This commit is contained in:
David.Hall
2018-06-11 10:20:49 -05:00
committed by GitHub
18 changed files with 380 additions and 174 deletions

View File

@ -36,180 +36,6 @@ using namespace dataconvert;
#include "functor_dtm.h"
#include "funchelpers.h"
namespace
{
using namespace funcexp;
int64_t addTime(DateTime& dt1, Time& dt2)
{
DateTime dt;
dt.year = 0;
dt.month = 0;
dt.day = 0;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
int64_t month, day, hour, min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec / 1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec / 60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
hour = (signed)(dt1.hour + dt2.hour + min / 60);
if ((hour < 0) || (hour > 23))
{
dt2.day = hour / 24;
hour = hour % 24;
}
if (hour < 0)
{
dt.hour = hour + 24;
dt2.day--;
}
else
{
dt.hour = hour;
}
day = (signed)(dt1.day + dt2.day);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (day < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1 ? 12 : month - 1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month, dt1.year);
month++;
// month=12;
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month, dt1.year))
{
for (; day > getDaysInMonth(month, dt1.year) && month <= 12; month++)
day -= getDaysInMonth(month, dt1.year);
if (month > 12)
month = 1;
}
if ( month < monthSave )
addyear++;
}
dt.day = day;
dt.month = month;
dt.year = dt1.year + addyear;
return *(reinterpret_cast<int64_t*>(&dt));
}
int64_t addTime(Time& dt1, Time& dt2)
{
Time dt;
dt.is_neg = false;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
int64_t min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec / 1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec / 60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
dt.hour = tmp = (signed)(dt1.hour + dt2.hour + min / 60);
// Saturation
if (tmp > 838)
{
dt.hour = 838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
else if (tmp < -838)
{
dt.is_neg = true;
dt.hour = -838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
return *(reinterpret_cast<int64_t*>(&dt));
}
}
namespace funcexp
{

View File

@ -56,6 +56,9 @@ int64_t Func_date::getIntVal(rowgroup::Row& row,
string value = "";
DateTime aDateTime;
Time aTime;
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
@ -72,6 +75,20 @@ int64_t Func_date::getIntVal(rowgroup::Row& row,
break;
}
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
{
int64_t val;
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
value = dataconvert::DataConvert::datetimeToString(val);
value = value.substr(0, 10);
break;
}
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:

View File

@ -49,6 +49,9 @@ int64_t Func_day::getIntVal(rowgroup::Row& row,
{
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
@ -59,6 +62,16 @@ int64_t Func_day::getIntVal(rowgroup::Row& row,
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 38) & 0x3f);
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
return (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -54,6 +54,9 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row,
int64_t val = 0;
int32_t dayofweek = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
@ -70,6 +73,17 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -52,6 +52,9 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
uint32_t day = 0;
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
@ -68,6 +71,17 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -52,6 +52,9 @@ int64_t Func_dayofyear::getIntVal(rowgroup::Row& row,
uint32_t day = 0;
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
@ -68,6 +71,17 @@ int64_t Func_dayofyear::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -78,6 +78,7 @@ string Func_hex::getStrVal(rowgroup::Row& row,
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::TIME:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str()) * 2 + 1]);

View File

@ -53,6 +53,8 @@ int64_t Func_last_day::getIntVal(rowgroup::Row& row,
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -70,6 +72,17 @@ int64_t Func_last_day::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -48,6 +48,8 @@ int64_t Func_month::getIntVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -59,6 +61,15 @@ int64_t Func_month::getIntVal(rowgroup::Row& row,
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
return (unsigned)((val >> 44) & 0xf);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -77,6 +77,8 @@ int64_t Func_monthname::getIntVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -88,6 +90,16 @@ int64_t Func_monthname::getIntVal(rowgroup::Row& row,
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
return (unsigned)((val >> 44) & 0xf);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -50,6 +50,8 @@ int64_t Func_quarter::getIntVal(rowgroup::Row& row,
{
// try to cast to date/datetime
int64_t val = 0, month = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -63,6 +65,15 @@ int64_t Func_quarter::getIntVal(rowgroup::Row& row,
month = (val >> 44) & 0xf;
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
month = (uint32_t)((val >> 44) & 0xf);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -59,6 +59,9 @@ int64_t Func_to_days::getIntVal(rowgroup::Row& row,
month = 0,
day = 0;
DateTime aDateTime;
Time aTime;
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
@ -82,6 +85,21 @@ int64_t Func_to_days::getIntVal(rowgroup::Row& row,
break;
}
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
{
int64_t val;
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
return helpers::calc_mysql_daynr(year, month, day);
break;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:

View File

@ -53,6 +53,8 @@ int64_t Func_week::getIntVal(rowgroup::Row& row,
int64_t val = 0;
int16_t mode = 0;
DateTime aDateTime;
Time aTime;
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
@ -73,6 +75,17 @@ int64_t Func_week::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -52,6 +52,8 @@ int64_t Func_weekday::getIntVal(rowgroup::Row& row,
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -69,6 +71,17 @@ int64_t Func_weekday::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -48,6 +48,8 @@ int64_t Func_year::getIntVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
DateTime aDateTime;
Time aTime;
switch (parm[0]->data()->resultType().colDataType)
{
@ -59,6 +61,15 @@ int64_t Func_year::getIntVal(rowgroup::Row& row,
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 48) & 0xffff);
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
return (unsigned)((val >> 48) & 0xffff);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -54,6 +54,8 @@ int64_t Func_yearweek::getIntVal(rowgroup::Row& row,
int64_t val = 0;
int16_t mode = 0; // default to 2
DateTime aDateTime;
Time aTime;
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
@ -76,6 +78,17 @@ int64_t Func_yearweek::getIntVal(rowgroup::Row& row,
day = (uint32_t)((val >> 38) & 0x3f);
break;
// Time adds to now() and then gets value
case CalpontSystemCatalog::TIME:
aDateTime = static_cast<DateTime>(nowDatetime());
aTime = parm[0]->data()->getTimeIntVal(row, isNull);
aTime.day = 0;
val = addTime(aDateTime, aTime);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:

View File

@ -28,6 +28,8 @@
#include <inttypes.h>
#include <string>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
#include "joblisttypes.h"
@ -145,6 +147,189 @@ int64_t Func::intToTime(int64_t i)
return i;
}
int64_t Func::nowDatetime()
{
DateTime result;
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
result.year = now.date().year();
result.month = now.date().month();
result.day = now.date().day();
result.hour = now.time_of_day().hours();
result.minute = now.time_of_day().minutes();
result.second = now.time_of_day().seconds();
result.msecond = now.time_of_day().total_microseconds();
return (int64_t) * (reinterpret_cast<int64_t*>(&result));
}
int64_t Func::addTime(DateTime& dt1, Time& dt2)
{
DateTime dt;
dt.year = 0;
dt.month = 0;
dt.day = 0;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
int64_t month, day, hour, min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec / 1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec / 60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
hour = (signed)(dt1.hour + dt2.hour + min / 60);
if ((hour < 0) || (hour > 23))
{
dt2.day = hour / 24;
hour = hour % 24;
}
if (hour < 0)
{
dt.hour = hour + 24;
dt2.day--;
}
else
{
dt.hour = hour;
}
day = (signed)(dt1.day + dt2.day);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (day < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1 ? 12 : month - 1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month, dt1.year);
month++;
// month=12;
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month, dt1.year))
{
for (; day > getDaysInMonth(month, dt1.year) && month <= 12; month++)
day -= getDaysInMonth(month, dt1.year);
if (month > 12)
month = 1;
}
if ( month < monthSave )
addyear++;
}
dt.day = day;
dt.month = month;
dt.year = dt1.year + addyear;
return *(reinterpret_cast<int64_t*>(&dt));
}
int64_t Func::addTime(Time& dt1, Time& dt2)
{
Time dt;
dt.is_neg = false;
dt.hour = 0;
dt.minute = 0;
dt.second = 0;
dt.msecond = 0;
int64_t min, sec, msec, tmp;
msec = (signed)(dt1.msecond + dt2.msecond);
dt.msecond = tmp = msec % 1000000;
if (tmp < 0)
{
dt.msecond = tmp + 1000000;
dt2.second--;
}
sec = (signed)(dt1.second + dt2.second + msec / 1000000);
dt.second = tmp = sec % 60;
if (tmp < 0)
{
dt.second = tmp + 60;
dt2.minute--;
}
min = (signed)(dt1.minute + dt2.minute + sec / 60);
dt.minute = tmp = min % 60;
if (tmp < 0)
{
dt.minute = tmp + 60;
dt2.hour--;
}
dt.hour = tmp = (signed)(dt1.hour + dt2.hour + min / 60);
// Saturation
if (tmp > 838)
{
dt.hour = 838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
else if (tmp < -838)
{
dt.is_neg = true;
dt.hour = -838;
dt.minute = 59;
dt.second = 59;
dt.msecond = 999999;
}
return *(reinterpret_cast<int64_t*>(&dt));
}
string Func::intToString(int64_t i)
{
return helpers::intToString(i);

View File

@ -34,6 +34,9 @@
#include "calpontsystemcatalog.h"
#include "dataconvert.h"
using namespace dataconvert;
namespace rowgroup
{
class Row;
@ -162,6 +165,10 @@ protected:
virtual std::string intToString(int64_t);
virtual std::string doubleToString(double);
virtual int64_t nowDatetime();
virtual int64_t addTime(DateTime& dt1, Time& dt2);
virtual int64_t addTime(Time& dt1, Time& dt2);
std::string fFuncName;
private: