You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-31 18:30:33 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			362 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
|    Copyright (C) 2019 MariaDB Corporation
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| /****************************************************************************
 | |
|  * $Id: functor.cpp 3898 2013-06-17 20:41:05Z rdempsey $
 | |
|  *
 | |
|  *
 | |
|  ****************************************************************************/
 | |
| #ifndef __STDC_FORMAT_MACROS
 | |
| #define __STDC_FORMAT_MACROS
 | |
| #endif
 | |
| #include <inttypes.h>
 | |
| #include <string>
 | |
| #include <sstream>
 | |
| #include <boost/date_time/posix_time/posix_time.hpp>
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| #include "joblisttypes.h"
 | |
| 
 | |
| #include "dataconvert.h"
 | |
| using namespace dataconvert;
 | |
| 
 | |
| #include "idberrorinfo.h"
 | |
| #include "errorids.h"
 | |
| #include "exceptclasses.h"
 | |
| using namespace logging;
 | |
| 
 | |
| #include "functor.h"
 | |
| #include "funchelpers.h"
 | |
| 
 | |
| using namespace funcexp;
 | |
| 
 | |
| namespace funcexp
 | |
| {
 | |
| void Func::init()
 | |
| {
 | |
|   uint32_t fni = joblist::FLOATNULL;
 | |
|   float* fp = reinterpret_cast<float*>(&fni);
 | |
|   fFloatNullVal = *fp;
 | |
| 
 | |
|   uint64_t dni = joblist::DOUBLENULL;
 | |
|   double* dp = reinterpret_cast<double*>(&dni);
 | |
|   fDoubleNullVal = *dp;
 | |
| 
 | |
|   fLongDoubleNullVal = joblist::LONGDOUBLENULL;
 | |
| }
 | |
| 
 | |
| Func::Func()
 | |
| {
 | |
|   init();
 | |
| }
 | |
| 
 | |
| Func::Func(const string& funcName) : fFuncName(funcName)
 | |
| {
 | |
|   init();
 | |
| }
 | |
| 
 | |
| uint32_t Func::stringToDate(const string str)
 | |
| {
 | |
|   int64_t ret = DataConvert::stringToDate(str);
 | |
| 
 | |
|   if (ret == -1)
 | |
|   {
 | |
|     Message::Args args;
 | |
|     args.add("date");
 | |
|     args.add(str);
 | |
|     unsigned errcode = ERR_INCORRECT_VALUE;
 | |
|     throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| uint64_t Func::stringToDatetime(const string str)
 | |
| {
 | |
|   int64_t ret = DataConvert::stringToDatetime(str);
 | |
| 
 | |
|   if (ret == -1)
 | |
|   {
 | |
|     Message::Args args;
 | |
|     args.add("datetime");
 | |
|     args.add(str);
 | |
|     unsigned errcode = ERR_INCORRECT_VALUE;
 | |
|     throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| uint64_t Func::stringToTimestamp(const std::string& str, long timeZone)
 | |
| {
 | |
|   int64_t ret = DataConvert::stringToTimestamp(str, timeZone);
 | |
| 
 | |
|   if (ret == -1)
 | |
|   {
 | |
|     Message::Args args;
 | |
|     args.add("timestamp");
 | |
|     args.add(str);
 | |
|     unsigned errcode = ERR_INCORRECT_VALUE;
 | |
|     throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| int64_t Func::stringToTime(const string str)
 | |
| {
 | |
|   int64_t ret = DataConvert::stringToTime(str);
 | |
| 
 | |
|   if (ret == -1)
 | |
|   {
 | |
|     Message::Args args;
 | |
|     args.add("time");
 | |
|     args.add(str);
 | |
|     unsigned errcode = ERR_INCORRECT_VALUE;
 | |
|     throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
 | |
|   }
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| uint32_t Func::intToDate(int64_t i)
 | |
| {
 | |
|   if ((uint64_t)i > 0xFFFFFFFFL)
 | |
|     return ((((uint32_t)(i >> 32)) & 0xFFFFFFC0L) | 0x3E);
 | |
| 
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| uint64_t Func::intToDatetime(int64_t i)
 | |
| {
 | |
|   if ((uint64_t)i < 0xFFFFFFFFL)
 | |
|     return (i << 32);
 | |
| 
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| uint64_t Func::intToTimestamp(int64_t i)
 | |
| {
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| int64_t Func::intToTime(int64_t i)
 | |
| {
 | |
|   // Don't think we need to do anything here?
 | |
|   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);
 | |
| }
 | |
| 
 | |
| string Func::doubleToString(double d)
 | |
| {
 | |
|   return helpers::doubleToString(d);
 | |
| }
 | |
| 
 | |
| string Func::longDoubleToString(long double ld)
 | |
| {
 | |
|   return helpers::longDoubleToString(ld);
 | |
| }
 | |
| 
 | |
| }  // namespace funcexp
 |