From d9e6ba90ad345296a479336920c10eec3e44e9c2 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 8 Jun 2018 14:58:08 +0100 Subject: [PATCH] MCOL-1433 Fix several functions for TIME handling This fixes hex() so that it outputs the hex of the ASCII for the time data to make it aligned with MariaDB. It also fixes the following functions so that they use NOW() as a DATETIME with the input TIME added to it: * weekday() * yearweek() * monthname() * last_day() * year() * weekofyear() * week() * to_days() * quarter() * month() * dayofyear() * dayofweek() * dayofmonth() * day() * date() --- utils/funcexp/func_add_time.cpp | 174 ----------------------------- utils/funcexp/func_date.cpp | 17 +++ utils/funcexp/func_day.cpp | 13 +++ utils/funcexp/func_dayname.cpp | 14 +++ utils/funcexp/func_dayofweek.cpp | 14 +++ utils/funcexp/func_dayofyear.cpp | 14 +++ utils/funcexp/func_hex.cpp | 1 + utils/funcexp/func_last_day.cpp | 13 +++ utils/funcexp/func_month.cpp | 11 ++ utils/funcexp/func_monthname.cpp | 12 ++ utils/funcexp/func_quarter.cpp | 11 ++ utils/funcexp/func_to_days.cpp | 18 +++ utils/funcexp/func_week.cpp | 13 +++ utils/funcexp/func_weekday.cpp | 13 +++ utils/funcexp/func_year.cpp | 11 ++ utils/funcexp/func_yearweek.cpp | 13 +++ utils/funcexp/functor.cpp | 185 +++++++++++++++++++++++++++++++ utils/funcexp/functor.h | 7 ++ 18 files changed, 380 insertions(+), 174 deletions(-) diff --git a/utils/funcexp/func_add_time.cpp b/utils/funcexp/func_add_time.cpp index c3d5d7d85..db854c085 100644 --- a/utils/funcexp/func_add_time.cpp +++ b/utils/funcexp/func_add_time.cpp @@ -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(&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(&dt)); -} - - -} - namespace funcexp { diff --git a/utils/funcexp/func_date.cpp b/utils/funcexp/func_date.cpp index 5f700e446..9f875b374 100644 --- a/utils/funcexp/func_date.cpp +++ b/utils/funcexp/func_date.cpp @@ -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(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: diff --git a/utils/funcexp/func_day.cpp b/utils/funcexp/func_day.cpp index bbd5edfcb..a25a41bcf 100644 --- a/utils/funcexp/func_day.cpp +++ b/utils/funcexp/func_day.cpp @@ -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(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: diff --git a/utils/funcexp/func_dayname.cpp b/utils/funcexp/func_dayname.cpp index 3825bc1a3..0122e4898 100644 --- a/utils/funcexp/func_dayname.cpp +++ b/utils/funcexp/func_dayname.cpp @@ -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(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: diff --git a/utils/funcexp/func_dayofweek.cpp b/utils/funcexp/func_dayofweek.cpp index a152ee15f..1ac549060 100644 --- a/utils/funcexp/func_dayofweek.cpp +++ b/utils/funcexp/func_dayofweek.cpp @@ -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(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: diff --git a/utils/funcexp/func_dayofyear.cpp b/utils/funcexp/func_dayofyear.cpp index 65c017202..0ec48f22f 100644 --- a/utils/funcexp/func_dayofyear.cpp +++ b/utils/funcexp/func_dayofyear.cpp @@ -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(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: diff --git a/utils/funcexp/func_hex.cpp b/utils/funcexp/func_hex.cpp index 79ed1d57e..83106a9be 100644 --- a/utils/funcexp/func_hex.cpp +++ b/utils/funcexp/func_hex.cpp @@ -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 hexPtr(new char[strlen(arg.c_str()) * 2 + 1]); diff --git a/utils/funcexp/func_last_day.cpp b/utils/funcexp/func_last_day.cpp index 38ba46ccb..757e19d77 100644 --- a/utils/funcexp/func_last_day.cpp +++ b/utils/funcexp/func_last_day.cpp @@ -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(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: diff --git a/utils/funcexp/func_month.cpp b/utils/funcexp/func_month.cpp index ba285f348..4269ae22f 100644 --- a/utils/funcexp/func_month.cpp +++ b/utils/funcexp/func_month.cpp @@ -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(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: diff --git a/utils/funcexp/func_monthname.cpp b/utils/funcexp/func_monthname.cpp index dbe5aa513..8a22b4b67 100644 --- a/utils/funcexp/func_monthname.cpp +++ b/utils/funcexp/func_monthname.cpp @@ -75,6 +75,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) { @@ -86,6 +88,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(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: diff --git a/utils/funcexp/func_quarter.cpp b/utils/funcexp/func_quarter.cpp index 1603ef31f..c819cbdbe 100644 --- a/utils/funcexp/func_quarter.cpp +++ b/utils/funcexp/func_quarter.cpp @@ -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(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: diff --git a/utils/funcexp/func_to_days.cpp b/utils/funcexp/func_to_days.cpp index 773ec4a8e..5c58b1b11 100644 --- a/utils/funcexp/func_to_days.cpp +++ b/utils/funcexp/func_to_days.cpp @@ -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(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: diff --git a/utils/funcexp/func_week.cpp b/utils/funcexp/func_week.cpp index 65145052f..9cb869c1e 100644 --- a/utils/funcexp/func_week.cpp +++ b/utils/funcexp/func_week.cpp @@ -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(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: diff --git a/utils/funcexp/func_weekday.cpp b/utils/funcexp/func_weekday.cpp index 6022a860f..67f535f1f 100644 --- a/utils/funcexp/func_weekday.cpp +++ b/utils/funcexp/func_weekday.cpp @@ -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(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: diff --git a/utils/funcexp/func_year.cpp b/utils/funcexp/func_year.cpp index 119881499..8b3f79fa0 100644 --- a/utils/funcexp/func_year.cpp +++ b/utils/funcexp/func_year.cpp @@ -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(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: diff --git a/utils/funcexp/func_yearweek.cpp b/utils/funcexp/func_yearweek.cpp index 84b8ca0a4..749491e11 100644 --- a/utils/funcexp/func_yearweek.cpp +++ b/utils/funcexp/func_yearweek.cpp @@ -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(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: diff --git a/utils/funcexp/functor.cpp b/utils/funcexp/functor.cpp index b74812ee9..f722dd557 100644 --- a/utils/funcexp/functor.cpp +++ b/utils/funcexp/functor.cpp @@ -28,6 +28,8 @@ #include #include #include +#include + 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(&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(&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(&dt)); +} + + string Func::intToString(int64_t i) { return helpers::intToString(i); diff --git a/utils/funcexp/functor.h b/utils/funcexp/functor.h index 9edb9bf62..a16917453 100644 --- a/utils/funcexp/functor.h +++ b/utils/funcexp/functor.h @@ -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: