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

Reformat all code to coding standard

This commit is contained in:
Andrew Hutchings
2017-10-26 17:18:17 +01:00
parent 4985f3456e
commit 01446d1e22
1296 changed files with 403852 additions and 353747 deletions

View File

@ -37,45 +37,45 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_abs::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
int64_t Func_abs::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
return llabs(parm[0]->data()->getIntVal(row, isNull));
// null value is indicated by isNull
return llabs(parm[0]->data()->getIntVal(row, isNull));
}
uint64_t Func_abs::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
return parm[0]->data()->getIntVal(row, isNull);
// null value is indicated by isNull
return parm[0]->data()->getIntVal(row, isNull);
}
IDB_Decimal Func_abs::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
d.value = llabs(d.value);
return d;
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
d.value = llabs(d.value);
return d;
}
double Func_abs::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
return fabs(parm[0]->data()->getDoubleVal(row, isNull));
return fabs(parm[0]->data()->getDoubleVal(row, isNull));
}

View File

@ -42,84 +42,101 @@ 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;
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);
dt.hour = tmp = hour % 24;
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);
dt.hour = tmp = hour % 24;
// if (tmp < -1)
if (tmp < 0) // fix for subtime dlh
{
dt.hour = tmp + 24;
dt2.day--;
}
day = (signed)(dt1.day + dt2.day + hour/24);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (dt2.day < 0 || dt2.hour < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1? 12: month-1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month);
month++;
if (tmp < 0) // fix for subtime dlh
{
dt.hour = tmp + 24;
dt2.day--;
}
day = (signed)(dt1.day + dt2.day + hour / 24);
if (isLeapYear(dt1.year) && dt1.month == 2)
day--;
month = dt1.month;
int addyear = 0;
if (dt2.day < 0 || dt2.hour < 0)
{
int monthSave = month;
while (day <= 0)
{
month = (month == 1 ? 12 : month - 1);
for (; day <= 0 && month > 0; month--)
day += getDaysInMonth(month);
month++;
// month=12;
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month))
{
for (; day > getDaysInMonth(month) && month <= 12; month++)
day -= getDaysInMonth(month);
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));
}
if ( month > monthSave )
addyear--;
}
else
{
int monthSave = month;
while (day > getDaysInMonth(month))
{
for (; day > getDaysInMonth(month) && month <= 12; month++)
day -= getDaysInMonth(month);
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));
}
}
@ -128,107 +145,113 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_add_time::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_add_time::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return getDatetimeIntVal(row, parm, isNull, op_ct);
return getDatetimeIntVal(row, parm, isNull, op_ct);
}
string Func_add_time::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
int32_t Func_add_time::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return -1;
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
int64_t time = DataConvert::stringToTime(val2);
if (time == -1)
{
isNull = true;
return -1;
}
Time t2 = *(reinterpret_cast<Time*>(&time));
// MySQL TIME type range '-838:59:59' and '838:59:59'
if (t2.minute > 59 || t2.second > 59 || t2.msecond > 999999)
{
isNull = true;
return -1;
}
int val_sign = 1;
if (t2.day != 0 && t2.hour < 0)
{
isNull = true;
return -1;
}
else if (t2.day < 0 || t2.hour < 0)
{
val_sign = -1;
}
if ((abs(t2.day) * 24 + abs(t2.hour)) > 838)
{
t2.hour = 838;
t2.minute = 59;
t2.second = 59;
if (isNull)
return -1;
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
int64_t time = DataConvert::stringToTime(val2);
if (time == -1)
{
isNull = true;
return -1;
}
Time t2 = *(reinterpret_cast<Time*>(&time));
// MySQL TIME type range '-838:59:59' and '838:59:59'
if (t2.minute > 59 || t2.second > 59 || t2.msecond > 999999)
{
isNull = true;
return -1;
}
int val_sign = 1;
if (t2.day != 0 && t2.hour < 0)
{
isNull = true;
return -1;
}
else if (t2.day < 0 || t2.hour < 0)
{
val_sign = -1;
}
if ((abs(t2.day) * 24 + abs(t2.hour)) > 838)
{
t2.hour = 838;
t2.minute = 59;
t2.second = 59;
t2.msecond = 999999;
}
else
{
t2.hour = abs(t2.day) * 24 + t2.hour;
}
t2.day = 0;
if (val_sign * sign < 0)
{
t2.hour = -abs(t2.hour);
t2.minute = -abs(t2.minute);
t2.second = -abs(t2.second);
t2.msecond = -abs(t2.msecond);
}
else
{
t2.hour = abs(t2.hour);
t2.minute = abs(t2.minute);
t2.second = abs(t2.second);
t2.msecond = abs(t2.msecond);
}
}
else
{
t2.hour = abs(t2.day) * 24 + t2.hour;
}
return addTime(dt1, t2);
t2.day = 0;
if (val_sign * sign < 0)
{
t2.hour = -abs(t2.hour);
t2.minute = -abs(t2.minute);
t2.second = -abs(t2.second);
t2.msecond = -abs(t2.msecond);
}
else
{
t2.hour = abs(t2.hour);
t2.minute = abs(t2.minute);
t2.second = abs(t2.second);
t2.msecond = abs(t2.msecond);
}
return addTime(dt1, t2);
}

View File

@ -40,18 +40,20 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_ascii::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_ascii::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (str.empty())
return 0;
return (unsigned char)str[0];
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (str.empty())
return 0;
return (unsigned char)str[0];
}

View File

@ -44,158 +44,186 @@ using namespace funcexp;
namespace
{
template<typename result_t>
inline bool numericGE(result_t op1, result_t op2)
{
return op1 >= op2;
}
template<typename result_t>
inline bool numericGE(result_t op1, result_t op2)
{
return op1 >= op2;
}
template<typename result_t>
inline bool numericLE(result_t op1, result_t op2)
{
return op1 <= op2;
}
template<typename result_t>
inline bool numericLE(result_t op1, result_t op2)
{
return op1 <= op2;
}
inline bool strGE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) >= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) >= 0;
}
inline bool strGE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) >= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) >= 0;
}
inline bool strLE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) <= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) <= 0;
}
inline bool strLE(const string& op1, const string& op2)
{
//return strcoll(op1.c_str(), op2.c_str()) <= 0;
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) <= 0;
}
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool notBetween)
{
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool notBetween)
{
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (notBetween)
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getUintVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getUintVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull;
if (!numericGE(val, pm[1]->data()->getIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull);
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDateIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDateIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDoubleVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDoubleVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDecimalVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDecimalVal(row, isNull));
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (notBetween)
{
if (!strGE(val, pm[1]->data()->getStrVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!strLE(val, pm[2]->data()->getStrVal(row, isNull)) && !isNull);
}
return !isNull &&
strGE(val, pm[1]->data()->getStrVal(row, isNull)) &&
strLE(val, pm[2]->data()->getStrVal(row, isNull));
}
default:
{
std::ostringstream oss;
oss << "between: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
return !isNull &&
numericGE(val, pm[1]->data()->getIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getIntVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getUintVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getUintVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getUintVal(row, isNull)) && !isNull;
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDateIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDateIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDateIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDatetimeIntVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDatetimeIntVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDoubleVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDoubleVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDoubleVal(row, isNull));
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (notBetween)
{
if (!numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!numericLE(val, pm[2]->data()->getDecimalVal(row, isNull)) && !isNull);
}
return !isNull &&
numericGE(val, pm[1]->data()->getDecimalVal(row, isNull)) &&
numericLE(val, pm[2]->data()->getDecimalVal(row, isNull));
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (notBetween)
{
if (!strGE(val, pm[1]->data()->getStrVal(row, isNull)) && !isNull)
return true;
isNull = false;
return (!strLE(val, pm[2]->data()->getStrVal(row, isNull)) && !isNull);
}
return !isNull &&
strGE(val, pm[1]->data()->getStrVal(row, isNull)) &&
strLE(val, pm[2]->data()->getStrVal(row, isNull));
}
default:
{
std::ostringstream oss;
oss << "between: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
}
@ -204,56 +232,59 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_between::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator op;
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
//op.operationType(fp[0]->data()->resultType());
bool allString = true;
PredicateOperator op;
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
//op.operationType(fp[0]->data()->resultType());
bool allString = true;
for (uint32_t i = 1; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
for (uint32_t i = 1; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
if ((fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) ||
ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME)
{
allString = false;
}
}
if ((fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR) ||
ct.colDataType == CalpontSystemCatalog::DATE ||
ct.colDataType == CalpontSystemCatalog::DATETIME)
{
allString = false;
}
}
if (allString)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
if (allString)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
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::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
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::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
}
bool Func_between::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBool(row, pm, isNull, ct, false) && !isNull;
return getBool(row, pm, isNull, ct, false) && !isNull;
}
@ -262,19 +293,19 @@ bool Func_between::getBoolVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_notbetween::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator *op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
op->setOpType(op->resultType(), fp[2]->data()->resultType());
return op->operationType();
PredicateOperator* op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
op->setOpType(op->resultType(), fp[2]->data()->resultType());
return op->operationType();
}
bool Func_notbetween::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBool(row, pm, isNull, ct, true) && !isNull;
return getBool(row, pm, isNull, ct, true) && !isNull;
}

View File

@ -44,130 +44,137 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_bitand::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitand::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
vector<int64_t> values;
vector<int64_t> values;
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
for (uint32_t i = 0; i < parm.size(); i++)
{
switch (parm[i]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
for (uint32_t i = 0; i < parm.size(); i++)
{
switch (parm[i]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::UFLOAT:
{
values.push_back(parm[i]->data()->getIntVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t value = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = true;
return value;
}
values.push_back(0);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[i]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / power(d.scale);
int lefto = (d.value - value * power(d.scale)) / power(d.scale-1);
if ( value >= 0 && lefto > 4 )
value++;
if ( value < 0 && lefto < -4 )
value--;
values.push_back(value);
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int64_t time = parm[i]->data()->getDateIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0;
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
values.push_back((year*10000)+(month*100)+day);
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm[i]->data()->getDatetimeIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
// return (int64_t) (year*1000000000000)+(month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec;
values.push_back((month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec);
}
break;
default:
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
{
values.push_back(parm[i]->data()->getIntVal(row, isNull));
}
break;
vector<int64_t>::iterator p = values.begin();
int64_t retValue = *p;
p++;
while ( p != values.end() )
{
retValue = retValue & *p;
p++;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t value = parm[i]->data()->getIntVal(row, isNull);
return retValue;
if (isNull)
{
isNull = true;
return value;
}
values.push_back(0);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[i]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / power(d.scale);
int lefto = (d.value - value * power(d.scale)) / power(d.scale - 1);
if ( value >= 0 && lefto > 4 )
value++;
if ( value < 0 && lefto < -4 )
value--;
values.push_back(value);
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int64_t time = parm[i]->data()->getDateIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0;
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
values.push_back((year * 10000) + (month * 100) + day);
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm[i]->data()->getDatetimeIntVal(row, isNull);
int32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
// return (int64_t) (year*1000000000000)+(month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec;
values.push_back((month * 100000000) + (day * 1000000) + (hour * 10000) + (min * 100) + sec);
}
break;
default:
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
vector<int64_t>::iterator p = values.begin();
int64_t retValue = *p;
p++;
while ( p != values.end() )
{
retValue = retValue & *p;
p++;
}
return retValue;
}

View File

@ -52,26 +52,26 @@ using namespace funcexp;
// and could be extracted into a utility class with its own header
// if that is the case - this is left as future exercise
bool getUIntValFromParm(
Row& row,
const execplan::SPTP& parm,
uint64_t& value,
bool& isNull)
Row& row,
const execplan::SPTP& parm,
uint64_t& value,
bool& isNull)
{
switch (parm->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
switch (parm->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::UFLOAT:
{
value = parm->data()->getIntVal(row, isNull);
}
break;
{
value = parm->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -84,65 +84,72 @@ bool getUIntValFromParm(
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
value = parm->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = true;
}
else
{
value = 0;
}
}
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
value = parm->data()->getIntVal(row, isNull);
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm->data()->getDecimalVal(row, isNull);
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
d.value < 0)
{
d.value = 0;
}
int64_t tmpval = d.value / helpers::power(d.scale);
int lefto = (d.value - tmpval * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( tmpval >= 0 && lefto > 4 )
tmpval++;
if ( tmpval < 0 && lefto < -4 )
tmpval--;
value = tmpval;
}
break;
if (isNull)
{
isNull = true;
}
else
{
value = 0;
}
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t time = parm->data()->getDateIntVal(row, isNull);
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm->data()->getDecimalVal(row, isNull);
Date d(time);
value = d.convertToMySQLint();
}
break;
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
d.value < 0)
{
d.value = 0;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm->data()->getDatetimeIntVal(row, isNull);
int64_t tmpval = d.value / helpers::power(d.scale);
int lefto = (d.value - tmpval * helpers::power(d.scale)) / helpers::power(d.scale - 1);
// @bug 4703 - missing year when convering to int
DateTime dt(time);
value = dt.convertToMySQLint();
}
break;
if ( tmpval >= 0 && lefto > 4 )
tmpval++;
default:
{
return false;
}
}
return true;
if ( tmpval < 0 && lefto < -4 )
tmpval--;
value = tmpval;
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t time = parm->data()->getDateIntVal(row, isNull);
Date d(time);
value = d.convertToMySQLint();
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t time = parm->data()->getDatetimeIntVal(row, isNull);
// @bug 4703 - missing year when convering to int
DateTime dt(time);
value = dt.convertToMySQLint();
}
break;
default:
{
return false;
}
}
return true;
}
}
@ -156,30 +163,32 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_bitand::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitand::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 & val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 & val2;
}
@ -190,30 +199,32 @@ int64_t Func_bitand::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_leftshift::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_leftshift::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 << val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 << val2;
}
@ -224,30 +235,32 @@ int64_t Func_leftshift::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_rightshift::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_rightshift::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 >> val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 >> val2;
}
@ -258,7 +271,7 @@ int64_t Func_rightshift::getIntVal(Row& row,
CalpontSystemCatalog::ColType Func_bitor::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitor::getIntVal(Row& row,
@ -266,30 +279,32 @@ int64_t Func_bitor::getIntVal(Row& row,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 | val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 | val2;
}
uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
return static_cast<uint64_t>(getIntVal(row,fp,isNull,op_ct));
{
return static_cast<uint64_t>(getIntVal(row, fp, isNull, op_ct));
}
@ -300,30 +315,32 @@ uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_bitxor::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_bitxor::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
uint64_t val1 = 0;
uint64_t val2 = 0;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
uint64_t val1 = 0;
uint64_t val2 = 0;
return val1 ^ val2;
if (!getUIntValFromParm(row, parm[0], val1, isNull) ||
!getUIntValFromParm(row, parm[1], val2, isNull))
{
std::ostringstream oss;
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
return val1 ^ val2;
}

View File

@ -47,38 +47,40 @@ namespace
using namespace funcexp;
inline uint64_t simple_case_cmp(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size() - 1; // remove expression from count of expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size() - 1; // remove expression from count of expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
switch (operationColType.colDataType)
{
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t ev = parm[n]->data()->getIntVal(row, isNull);
if (isNull)
break;
switch (operationColType.colDataType)
{
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t ev = parm[n]->data()->getIntVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getIntVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getIntVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -87,6 +89,7 @@ inline uint64_t simple_case_cmp(Row& row,
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t ev = parm[n]->data()->getUintVal(row, isNull);
if (isNull)
break;
@ -97,227 +100,243 @@ inline uint64_t simple_case_cmp(Row& row,
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
if (isNull)
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
for (; i < n; i += 2)
{
//BUG 5362
if (utf8::idb_strcoll(ev.c_str(), parm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
case execplan::CalpontSystemCatalog::DECIMAL:
for (; i < n; i += 2)
{
//BUG 5362
if (utf8::idb_strcoll(ev.c_str(), parm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal ev = parm[n]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
{
IDB_Decimal ev = parm[n]->data()->getDecimalVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
case execplan::CalpontSystemCatalog::DOUBLE:
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double ev = parm[n]->data()->getDoubleVal(row, isNull);
if (isNull)
break;
{
double ev = parm[n]->data()->getDoubleVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDoubleVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getDoubleVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float ev = parm[n]->data()->getFloatVal(row, isNull);
if (isNull)
break;
case execplan::CalpontSystemCatalog::UFLOAT:
{
float ev = parm[n]->data()->getFloatVal(row, isNull);
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getFloatVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
break;
}
if (isNull)
break;
default:
{
std::ostringstream oss;
oss << "case: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
for (; i < n; i += 2)
{
if (ev == parm[i]->data()->getFloatVal(row, isNull) && !isNull)
break;
else
isNull = false;
}
if (i == n && !hasElse)
isNull = true;
else if (isNull && hasElse)
// BUG 5110. Only way we can exit above with isNull == true is when ev is NULL
// if so and we have else condition we need to use it by setting i = n
{
i = n;
isNull = false;
}
break;
}
default:
{
std::ostringstream oss;
oss << "case: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
if (i == n && !hasElse)
isNull = true;
else if (isNull && hasElse)
// BUG 5110. Only way we can exit above with isNull == true is when ev is NULL
// if so and we have else condition we need to use it by setting i = n
{
i = n;
isNull = false;
}
return i;
return i;
}
inline uint64_t searched_case_cmp(Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size(); // count of boolean_expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
uint64_t i = 0; // index to the parm list
uint64_t n = parm.size(); // count of boolean_expression_i + result_i
uint64_t hasElse = n % 2; // if 1, then ELSE exist
n -= hasElse; // index to expression
for (; i < n; i += 2)
{
if (parm[i]->getBoolVal(row, isNull))
break;
}
for (; i < n; i += 2)
{
if (parm[i]->getBoolVal(row, isNull))
break;
}
isNull = false;
if (i == n && !hasElse)
isNull = true;
isNull = false;
return (i == n ? i-1 : i);
if (i == n && !hasElse)
isNull = true;
return (i == n ? i - 1 : i);
}
CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType,
bool simpleCase)
CalpontSystemCatalog::ColType& resultType,
bool simpleCase)
{
// ... expression_i + result_i + ... [[expression] + result_N]
FunctionParm::size_type n = fp.size();
// ... expression_i + result_i + ... [[expression] + result_N]
FunctionParm::size_type n = fp.size();
if (simpleCase) // simple case has an expression
n -= 1; // remove expression from count of expression_i + result_i
bool hasElse = ((n % 2) != 0); // if 1, then ELSE exist
if (hasElse)
--n; // n now is an even number
idbassert((n % 2) == 0);
if (simpleCase) // simple case has an expression
n -= 1; // remove expression from count of expression_i + result_i
bool allStringO = true;
bool allStringR = true;
bool hasElse = ((n % 2) != 0); // if 1, then ELSE exist
FunctionParm::size_type l = fp.size() - 1; // last fp index
idbassert(fp[l]->data());
CalpontSystemCatalog::ColType oct = fp[l]->data()->resultType();
CalpontSystemCatalog::ColType rct = resultType;
bool operation = true;
for (uint64_t i = 0; i <= n; i++)
{
// operation or result type
operation = ((i % 2) == 0);
if (hasElse)
--n; // n now is an even number
// the result type of ELSE, if exists.
if (i == n)
{
if (!hasElse)
break;
idbassert((n % 2) == 0);
if (simpleCase)
{
// the case expression
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
PredicateOperator op;
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
bool allStringO = true;
bool allStringR = true;
i += 1;
}
FunctionParm::size_type l = fp.size() - 1; // last fp index
idbassert(fp[l]->data());
CalpontSystemCatalog::ColType oct = fp[l]->data()->resultType();
CalpontSystemCatalog::ColType rct = resultType;
bool operation = true;
operation = false;
}
for (uint64_t i = 0; i <= n; i++)
{
// operation or result type
operation = ((i % 2) == 0);
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
// this is not a string column
PredicateOperator op;
if (operation)
{
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
// the result type of ELSE, if exists.
if (i == n)
{
if (!hasElse)
break;
// If any parm is of string type, the result type should be string. (same as if)
else if (rct.colDataType != CalpontSystemCatalog::CHAR &&
rct.colDataType != CalpontSystemCatalog::TEXT &&
rct.colDataType != CalpontSystemCatalog::VARCHAR)
{
op.setOpType(rct, fp[i]->data()->resultType());
allStringR = false;
rct = op.operationType();
}
}
else
{
// this is a string
// If any parm is of string type, the result type should be string. (same as if)
allStringR = true;
}
}
if (simpleCase)
{
// the case expression
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
PredicateOperator op;
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
if (allStringO)
{
oct.colDataType = CalpontSystemCatalog::VARCHAR;
oct.colWidth = 255;
}
i += 1;
}
if (allStringR)
{
rct.colDataType = CalpontSystemCatalog::VARCHAR;
rct.colWidth = 255;
}
operation = false;
}
if (rct.scale != 0 && rct.colDataType == CalpontSystemCatalog::BIGINT)
rct.colDataType = CalpontSystemCatalog::DECIMAL;
if (oct.scale != 0 && oct.colDataType == CalpontSystemCatalog::BIGINT)
oct.colDataType = CalpontSystemCatalog::DECIMAL;
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
// this is not a string column
PredicateOperator op;
resultType = rct;
return oct;
if (operation)
{
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
// If any parm is of string type, the result type should be string. (same as if)
else if (rct.colDataType != CalpontSystemCatalog::CHAR &&
rct.colDataType != CalpontSystemCatalog::TEXT &&
rct.colDataType != CalpontSystemCatalog::VARCHAR)
{
op.setOpType(rct, fp[i]->data()->resultType());
allStringR = false;
rct = op.operationType();
}
}
else
{
// this is a string
// If any parm is of string type, the result type should be string. (same as if)
allStringR = true;
}
}
if (allStringO)
{
oct.colDataType = CalpontSystemCatalog::VARCHAR;
oct.colWidth = 255;
}
if (allStringR)
{
rct.colDataType = CalpontSystemCatalog::VARCHAR;
rct.colWidth = 255;
}
if (rct.scale != 0 && rct.colDataType == CalpontSystemCatalog::BIGINT)
rct.colDataType = CalpontSystemCatalog::DECIMAL;
if (oct.scale != 0 && oct.colDataType == CalpontSystemCatalog::BIGINT)
oct.colDataType = CalpontSystemCatalog::DECIMAL;
resultType = rct;
return oct;
}
}
@ -339,92 +358,92 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_simple_case::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return caseOperationType(fp, resultType, true);
return caseOperationType(fp, resultType, true);
}
int64_t Func_simple_case::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return joblist::BIGINTNULL;
if (isNull)
return joblist::BIGINTNULL;
return parm[i+1]->data()->getIntVal(row, isNull);
return parm[i + 1]->data()->getIntVal(row, isNull);
}
string Func_simple_case::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return string("");
if (isNull)
return string("");
return parm[i+1]->data()->getStrVal(row, isNull);
return parm[i + 1]->data()->getStrVal(row, isNull);
}
IDB_Decimal Func_simple_case::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
return parm[i+1]->data()->getDecimalVal(row, isNull);
return parm[i + 1]->data()->getDecimalVal(row, isNull);
}
double Func_simple_case::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return doubleNullVal();
if (isNull)
return doubleNullVal();
return parm[i+1]->data()->getDoubleVal(row, isNull);
return parm[i + 1]->data()->getDoubleVal(row, isNull);
}
int32_t Func_simple_case::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATENULL;
if (isNull)
return joblist::DATENULL;
return parm[i + 1]->data()->getDateIntVal(row, isNull);
}
return parm[i+1]->data()->getDateIntVal(row, isNull);
}
int64_t Func_simple_case::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATETIMENULL;
if (isNull)
return joblist::DATETIMENULL;
return parm[i+1]->data()->getDatetimeIntVal(row, isNull);
}
return parm[i + 1]->data()->getDatetimeIntVal(row, isNull);
}
@ -441,94 +460,94 @@ int64_t Func_simple_case::getDatetimeIntVal(rowgroup::Row& row,
//
CalpontSystemCatalog::ColType Func_searched_case::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type not used by this functor.
// return fp[1]->data()->resultType();
return caseOperationType(fp, resultType, false);
// operation type not used by this functor.
// return fp[1]->data()->resultType();
return caseOperationType(fp, resultType, false);
}
int64_t Func_searched_case::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return joblist::BIGINTNULL;
if (isNull)
return joblist::BIGINTNULL;
return parm[i+1]->data()->getIntVal(row, isNull);
return parm[i + 1]->data()->getIntVal(row, isNull);
}
string Func_searched_case::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return string("");
if (isNull)
return string("");
return parm[i+1]->data()->getStrVal(row, isNull);
return parm[i + 1]->data()->getStrVal(row, isNull);
}
IDB_Decimal Func_searched_case::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
return parm[i+1]->data()->getDecimalVal(row, isNull);
return parm[i + 1]->data()->getDecimalVal(row, isNull);
}
double Func_searched_case::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t i = searched_case_cmp(row, parm, isNull);
uint64_t i = searched_case_cmp(row, parm, isNull);
if (isNull)
return doubleNullVal();
if (isNull)
return doubleNullVal();
return parm[i+1]->data()->getDoubleVal(row, isNull);
return parm[i + 1]->data()->getDoubleVal(row, isNull);
}
int32_t Func_searched_case::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATENULL;
if (isNull)
return joblist::DATENULL;
return parm[i + 1]->data()->getDateIntVal(row, isNull);
}
return parm[i+1]->data()->getDateIntVal(row, isNull);
}
int64_t Func_searched_case::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATETIMENULL;
if (isNull)
return joblist::DATETIMENULL;
return parm[i+1]->data()->getDatetimeIntVal(row, isNull);
}
return parm[i + 1]->data()->getDatetimeIntVal(row, isNull);
}
} // namespace funcexp

File diff suppressed because it is too large Load Diff

View File

@ -46,62 +46,64 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ceil::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType();
return fp[0]->data()->resultType();
}
int64_t Func_ceil::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
{
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
if (isNull)
break;
ret = decimal.value;
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
ret = decimal.value;
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
// Adjust to an int based on the scale.
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
// Adjust to an int based on the scale.
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (ret * helpers::powerOf10_c[decimal.scale]) > 0))
ret += 1;
}
}
break;
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (ret * helpers::powerOf10_c[decimal.scale]) > 0))
ret += 1;
}
}
break;
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
@ -111,73 +113,78 @@ int64_t Func_ceil::getIntVal(Row& row,
ret = (int64_t)(parm[0]->data()->getUintVal(row, isNull));
}
break;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
{
ret = (int64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (int64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = d.convertToMySQLint();
}
break;
if (!isNull)
ret = (int64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
if (!isNull)
ret = d.convertToMySQLint();
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
uint64_t Func_ceil::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint64_t ret = 0;
uint64_t ret = 0;
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
{
ret = (uint64_t)parm[0]->data()->getIntVal(row, isNull);
}
break;
break;
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
@ -187,77 +194,83 @@ uint64_t Func_ceil::getUintVal(Row& row,
ret = (parm[0]->data()->getUintVal(row, isNull));
}
break;
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
{
ret = (uint64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (uint64_t) ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATE:
{
if (!isNull)
ret = (uint64_t) ceil(strtod(str.c_str(), 0));
}
break;
case CalpontSystemCatalog::DATE:
{
Date d (parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = d.convertToMySQLint();
}
break;
}
break;
case CalpontSystemCatalog::DATETIME:
{
case CalpontSystemCatalog::DATETIME:
{
DateTime dt(parm[0]->data()->getDatetimeIntVal(row, isNull));
if (!isNull)
ret = dt.convertToMySQLint();
}
break;
}
break;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
default:
{
std::ostringstream oss;
oss << "ceil: datatype of " << colDataTypeToString(op_ct.colDataType)
<< " is not supported";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
double Func_ceil::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT)
{
ret = ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
}
else
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT)
{
ret = ceil(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
}
else
{
if (isUnsigned(op_ct.colDataType))
{
ret = (double) getUintVal(row, parm, isNull, op_ct);
@ -266,34 +279,37 @@ double Func_ceil::getDoubleVal(Row& row,
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
}
}
return ret;
return ret;
}
string Func_ceil::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
char tmp[512] = {'\0'};
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
char tmp[512] = {'\0'};
// remove the decimals in the oss string.
char *d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
// remove the decimals in the oss string.
char* d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
#ifndef __LP64__
@ -302,16 +318,16 @@ string Func_ceil::getStrVal(Row& row,
snprintf(tmp, 511, "%lu", getUintVal(row, parm, isNull, op_ct));
#endif
}
else
{
else
{
#ifndef __LP64__
snprintf(tmp, 511, "%lld", getIntVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%ld", getIntVal(row, parm, isNull, op_ct));
#endif
}
}
return string(tmp);
return string(tmp);
}

View File

@ -48,26 +48,28 @@ inline bool getChar( uint64_t value, char* buf )
uint32_t cur_offset = 0; // current index into buf
int cur_bitpos = 56; // 8th octet in input val
while( cur_bitpos >= 0 )
{
if( ( ( value >> cur_bitpos ) & 0xff ) != 0 )
{
buf[cur_offset++] = char( ( value >> cur_bitpos ) & 0xff );
}
cur_bitpos -= 8;
}
buf[cur_offset] = '\0';
while ( cur_bitpos >= 0 )
{
if ( ( ( value >> cur_bitpos ) & 0xff ) != 0 )
{
buf[cur_offset++] = char( ( value >> cur_bitpos ) & 0xff );
}
return true;
cur_bitpos -= 8;
}
buf[cur_offset] = '\0';
return true;
}
// see comment above regarding buf assumptions
inline bool getChar( int64_t value, char* buf )
{
if ( value < 0 )
return false;
else
return getChar( (uint64_t) value, buf );
if ( value < 0 )
return false;
else
return getChar( (uint64_t) value, buf );
}
}
@ -75,35 +77,36 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_char::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_char::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
const int BUF_SIZE = 9; // see comment above for size requirement
const int BUF_SIZE = 9; // see comment above for size requirement
char buf[BUF_SIZE];
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
if ( !getChar(value, buf) )
{
isNull = true;
return "";
}
}
break;
if ( !getChar(value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -112,7 +115,8 @@ string Func_char::getStrVal(Row& row,
{
uint64_t value = parm[0]->data()->getUintVal(row, isNull);
if ( !getChar(value, buf) ) {
if ( !getChar(value, buf) )
{
isNull = true;
return "";
}
@ -120,72 +124,80 @@ string Func_char::getStrVal(Row& row,
break;
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
// get decimal and round up
int value = d.value / helpers::power(d.scale);
int lefto = (d.value - value * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( lefto > 4 )
value++;
if ( !getChar((int64_t)value, buf) ) {
isNull = true;
return "";
}
}
break;
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
// get decimal and round up
int value = d.value / helpers::power(d.scale);
int lefto = (d.value - value * helpers::power(d.scale)) / helpers::power(d.scale - 1);
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
isNull = true;
return "";
}
break;
if ( lefto > 4 )
value++;
default:
{
std::ostringstream oss;
oss << "char: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// Bug 5110 : Here the data in col is null. But there might have other
// non-null columns we processed before and we do not want entire value
// to become null. Therefore we set isNull flag to false.
if(isNull)
{
isNull = false;
return "";
}
if ( !getChar((int64_t)value, buf) )
{
isNull = true;
return "";
}
}
break;
return buf;
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
isNull = true;
return "";
}
break;
default:
{
std::ostringstream oss;
oss << "char: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// Bug 5110 : Here the data in col is null. But there might have other
// non-null columns we processed before and we do not want entire value
// to become null. Therefore we set isNull flag to false.
if (isNull)
{
isNull = false;
return "";
}
return buf;
}

View File

@ -45,70 +45,71 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_char_length::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_char_length::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
switch (type)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
switch (type)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
const string& tstr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
{
const string& tstr = parm[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
if (isNull)
return 0;
return (int64_t)strwclen;
}
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
case execplan::CalpontSystemCatalog::DATE:
{
string date = dataconvert::DataConvert::dateToString(parm[0]->data()->getDateIntVal(row, isNull));
return (int64_t)date.size();
}
return (int64_t)strwclen;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string date = dataconvert::DataConvert::datetimeToString(parm[0]->data()->getDatetimeIntVal(row, isNull));
return (int64_t)date.size();
}
case execplan::CalpontSystemCatalog::DATE:
{
string date = dataconvert::DataConvert::dateToString(parm[0]->data()->getDateIntVal(row, isNull));
return (int64_t)date.size();
}
default:
{
std::ostringstream oss;
oss << "char_length: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string date = dataconvert::DataConvert::datetimeToString(parm[0]->data()->getDatetimeIntVal(row, isNull));
return (int64_t)date.size();
}
return 0;
default:
{
std::ostringstream oss;
oss << "char_length: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return 0;
}

View File

@ -40,128 +40,152 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_coalesce::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_coalesce::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
string Func_coalesce::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
string val;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return "";
string val;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return "";
}
int32_t Func_coalesce::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
int64_t Func_coalesce::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
int64_t val = 0;
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return val;
}
isNull = true;
return val;
}
double Func_coalesce::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
double d = 0.0;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
double d = 0.0;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
}
execplan::IDB_Decimal Func_coalesce::getDecimalVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
IDB_Decimal d;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
IDB_Decimal d;
for (uint32_t i = 0; i < parm.size(); i++)
{
d = parm[i]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
continue;
}
return d;
}
isNull = true;
return d;
}

View File

@ -42,8 +42,8 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_concat::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
@ -51,17 +51,18 @@ CalpontSystemCatalog::ColType Func_concat::operationType(FunctionParm& fp, Calpo
// concat() returns NULL if any argument is NULL.
//
string Func_concat::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
string ret = stringValue(parm[0], row, isNull);
string ret = stringValue(parm[0], row, isNull);
for ( unsigned int id = 1 ; id < parm.size() ; id++) {
ret.append( stringValue(parm[id], row, isNull) );
}
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
ret.append( stringValue(parm[id], row, isNull) );
}
return ret;
return ret;
}
} // namespace funcexp

View File

@ -39,72 +39,82 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_concat_ws::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_concat_ws::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
string delim = stringValue(parm[0], row, isNull);
if (isNull)
return "";
string delim = stringValue(parm[0], row, isNull);
if (isNull)
return "";
#ifdef STRCOLL_ENH__
wstring wstr;
size_t strwclen = utf8::idb_mbstowcs(0,delim.c_str(),0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, delim.c_str(), strwclen);
wstring wdelim(wcbuf, strwclen);
wstring wstr;
size_t strwclen = utf8::idb_mbstowcs(0, delim.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, delim.c_str(), strwclen);
wstring wdelim(wcbuf, strwclen);
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
string tstr = stringValue(parm[id], row, isNull);
if (isNull)
{
isNull = false;
continue;
}
if (!wstr.empty())
wstr += wdelim;
size_t strwclen1 = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf1 = (wchar_t*)alloca(strwclen1 * sizeof(wchar_t));
strwclen1 = utf8::idb_mbstowcs(wcbuf1, tstr.c_str(), strwclen1);
wstring str1(wcbuf1, strwclen1);
wstr += str1;
}
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
string tstr = stringValue(parm[id], row, isNull);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
if (strmblen == 0)
isNull = true;
else
isNull = false;
return string(outbuf, strmblen);
if (isNull)
{
isNull = false;
continue;
}
if (!wstr.empty())
wstr += wdelim;
size_t strwclen1 = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf1 = (wchar_t*)alloca(strwclen1 * sizeof(wchar_t));
strwclen1 = utf8::idb_mbstowcs(wcbuf1, tstr.c_str(), strwclen1);
wstring str1(wcbuf1, strwclen1);
wstr += str1;
}
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
if (strmblen == 0)
isNull = true;
else
isNull = false;
return string(outbuf, strmblen);
#else
string str;
for ( uint32_t i = 1 ; i < parm.size() ; i++)
{
str += string(stringValue(parm[i], row, isNull).c_str());
string str;
if (isNull)
{
isNull = false;
continue;
}
if (!str.empty() && !isNull)
str += delim;
}
if (str.empty())
isNull = true;
else
isNull = false;
return str;
for ( uint32_t i = 1 ; i < parm.size() ; i++)
{
str += string(stringValue(parm[i], row, isNull).c_str());
if (isNull)
{
isNull = false;
continue;
}
if (!str.empty() && !isNull)
str += delim;
}
if (str.empty())
isNull = true;
else
isNull = false;
return str;
#endif
}

View File

@ -38,85 +38,90 @@ namespace
{
int64_t convStrToNum(const string& str, int base, bool unsignedFlag)
{
int negative;
uint64_t cutoff, cutlim, i, j, save;
int overflow;
// to skip the leading spaces.
for (i = 0; i < str.length() && str.c_str()[i] == ' '; i++)
{}
int negative;
uint64_t cutoff, cutlim, i, j, save;
int overflow;
if (i == str.length())
{
return 0L;
}
// to skip the leading spaces.
for (i = 0; i < str.length() && str.c_str()[i] == ' '; i++)
{}
if (str.c_str()[i] == '-')
{
negative = 1;
++i;
}
else if (str.c_str()[i] == '+')
{
negative = 0;
++i;
}
else
negative = 0;
if (i == str.length())
{
return 0L;
}
save = i;
cutoff = (~(uint64_t) 0) / (uint64_t) base;
cutlim = (uint32_t) ((~(uint64_t) 0) % (uint64_t) base);
overflow = 0;
j = 0;
for (; i < str.length(); i++)
{
unsigned char c= str.c_str()[i];
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='Z')
c = c - 'A' + 10;
else if (c>='a' && c<='z')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (j > cutoff || (j == cutoff && c > cutlim))
overflow = 1;
else
{
j *= (uint64_t) base;
j += c;
}
}
if (i == save)
return 0L;
if (str.c_str()[i] == '-')
{
negative = 1;
++i;
}
else if (str.c_str()[i] == '+')
{
negative = 0;
++i;
}
else
negative = 0;
if (!unsignedFlag)
{
if (negative)
{
if (j > (uint64_t) numeric_limits<int64_t>::min())
overflow = 1;
}
else if (j > (uint64_t) numeric_limits<int64_t>::max())
{
overflow = 1;
}
}
save = i;
if (overflow)
{
if (unsignedFlag)
return (~(uint64_t) 0);
return negative ? numeric_limits<int64_t>::min() : numeric_limits<int64_t>::max();
}
cutoff = (~(uint64_t) 0) / (uint64_t) base;
cutlim = (uint32_t) ((~(uint64_t) 0) % (uint64_t) base);
return (negative ? -((int64_t) j) : (int64_t) j);
overflow = 0;
j = 0;
for (; i < str.length(); i++)
{
unsigned char c = str.c_str()[i];
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'Z')
c = c - 'A' + 10;
else if (c >= 'a' && c <= 'z')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (j > cutoff || (j == cutoff && c > cutlim))
overflow = 1;
else
{
j *= (uint64_t) base;
j += c;
}
}
if (i == save)
return 0L;
if (!unsignedFlag)
{
if (negative)
{
if (j > (uint64_t) numeric_limits<int64_t>::min())
overflow = 1;
}
else if (j > (uint64_t) numeric_limits<int64_t>::max())
{
overflow = 1;
}
}
if (overflow)
{
if (unsignedFlag)
return (~(uint64_t) 0);
return negative ? numeric_limits<int64_t>::min() : numeric_limits<int64_t>::max();
}
return (negative ? -((int64_t) j) : (int64_t) j);
}
}
@ -124,170 +129,196 @@ namespace funcexp
{
namespace helpers
{
const char *convNumToStr(int64_t val,char *dst,int radix)
const char* convNumToStr(int64_t val, char* dst, int radix)
{
if (radix == 16 || radix == -16)
if (radix == 16 || radix == -16)
#ifdef _MSC_VER
sprintf(dst, "%llX", val);
sprintf(dst, "%llX", val);
#else
sprintf(dst, "%lX", val);
sprintf(dst, "%lX", val);
#endif
else if (radix == 8 || radix == -8)
else if (radix == 8 || radix == -8)
#ifdef _MSC_VER
sprintf(dst, "%llo", val);
sprintf(dst, "%llo", val);
#else
sprintf(dst, "%lo", val);
sprintf(dst, "%lo", val);
#endif
else if (radix == 10)
{
uint64_t uval = static_cast<uint64_t>(val);
else if (radix == 10)
{
uint64_t uval = static_cast<uint64_t>(val);
#ifdef _MSC_VER
sprintf(dst, "%llu", uval);
sprintf(dst, "%llu", uval);
#else
sprintf(dst, "%lu", uval);
sprintf(dst, "%lu", uval);
#endif
}
else if (radix == -10)
}
else if (radix == -10)
#ifdef _MSC_VER
sprintf(dst, "%lld", val);
sprintf(dst, "%lld", val);
#else
sprintf(dst, "%ld", val);
sprintf(dst, "%ld", val);
#endif
else if (radix == 2 || radix == -2)
{
char tmp[65];
char* ptr = &tmp[64];
*ptr-- = 0;
for (int i = 0; i < 64; i++)
{
if (val&1)
*ptr-- = '1';
else
*ptr-- = '0';
val >>= 1;
}
ptr = strchr(tmp, '1');
if (ptr == 0)
strcpy(dst, &tmp[63]);
else
strcpy(dst, ptr);
}
else if (radix == 4 || radix == -4)
{
char tmp[33];
char* ptr = &tmp[32];
*ptr-- = 0;
for (int i = 0; i < 32; i++)
{
*ptr-- = '0' + (val&3);
val >>= 2;
}
ptr = strpbrk(tmp, "123");
if (ptr == 0)
strcpy(dst, &tmp[31]);
else
strcpy(dst, ptr);
}
else if (radix == 2 || radix == -2)
{
char tmp[65];
char* ptr = &tmp[64];
*ptr-- = 0;
for (int i = 0; i < 64; i++)
{
if (val & 1)
*ptr-- = '1';
else
*ptr-- = '0';
val >>= 1;
}
ptr = strchr(tmp, '1');
if (ptr == 0)
strcpy(dst, &tmp[63]);
else
strcpy(dst, ptr);
}
else if (radix == 4 || radix == -4)
{
char tmp[33];
char* ptr = &tmp[32];
*ptr-- = 0;
for (int i = 0; i < 32; i++)
{
*ptr-- = '0' + (val & 3);
val >>= 2;
}
ptr = strpbrk(tmp, "123");
if (ptr == 0)
strcpy(dst, &tmp[31]);
else
strcpy(dst, ptr);
}
#if 0
else if (radix == 8 || radix == -8)
{
char tmp[23];
char* ptr = &tmp[22];
*ptr-- = 0;
for (int i = 0; i < 22; i++)
{
*ptr-- = '0' + (val&7);
val >>= 3;
}
ptr = strpbrk(tmp, "1234567");
if (ptr == 0)
strcpy(dst, &tmp[21]);
else
strcpy(dst, ptr);
}
else if (radix == 16 || radix == -16)
{
char tmp[17];
char* ptr = &tmp[16];
*ptr-- = 0;
for (int i = 0; i < 16; i++)
{
int v = val&0xf;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 4;
}
ptr = strpbrk(tmp, "123456789ABCDEF");
if (ptr == 0)
strcpy(dst, &tmp[15]);
else
strcpy(dst, ptr);
}
else if (radix == 8 || radix == -8)
{
char tmp[23];
char* ptr = &tmp[22];
*ptr-- = 0;
for (int i = 0; i < 22; i++)
{
*ptr-- = '0' + (val & 7);
val >>= 3;
}
ptr = strpbrk(tmp, "1234567");
if (ptr == 0)
strcpy(dst, &tmp[21]);
else
strcpy(dst, ptr);
}
else if (radix == 16 || radix == -16)
{
char tmp[17];
char* ptr = &tmp[16];
*ptr-- = 0;
for (int i = 0; i < 16; i++)
{
int v = val & 0xf;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 4;
}
ptr = strpbrk(tmp, "123456789ABCDEF");
if (ptr == 0)
strcpy(dst, &tmp[15]);
else
strcpy(dst, ptr);
}
#endif
else if (radix == 32 || radix == -32)
{
char tmp[14];
char* ptr = &tmp[13];
*ptr-- = 0;
for (int i = 0; i < 13; i++)
{
int v = val&0x1f;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 5;
}
ptr = strpbrk(tmp, "123456789ABCDEFGHIJKLMNOPQRSTUV");
if (ptr == 0)
strcpy(dst, &tmp[12]);
else
strcpy(dst, ptr);
}
else
*dst = 0;
return dst;
else if (radix == 32 || radix == -32)
{
char tmp[14];
char* ptr = &tmp[13];
*ptr-- = 0;
for (int i = 0; i < 13; i++)
{
int v = val & 0x1f;
if (v > 9)
*ptr-- = 'A' + v - 10;
else
*ptr-- = '0' + v;
val >>= 5;
}
ptr = strpbrk(tmp, "123456789ABCDEFGHIJKLMNOPQRSTUV");
if (ptr == 0)
strcpy(dst, &tmp[12]);
else
strcpy(dst, ptr);
}
else
*dst = 0;
return dst;
}
} //namespace funcexp::helpers
CalpontSystemCatalog::ColType Func_conv::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_conv::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& res= parm[0]->data()->getStrVal(row, isNull);
string str;
char ans[65];
int64_t dec;
int64_t from_base = parm[1]->data()->getIntVal(row, isNull);
int64_t to_base = parm[2]->data()->getIntVal(row, isNull);
const string& res = parm[0]->data()->getStrVal(row, isNull);
string str;
char ans[65];
int64_t dec;
int64_t from_base = parm[1]->data()->getIntVal(row, isNull);
int64_t to_base = parm[2]->data()->getIntVal(row, isNull);
if (isNull || abs(static_cast<int>(to_base)) > 36 || abs(static_cast<int>(to_base)) < 2 ||
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || !(res.length()))
{
isNull = true;
return "";
}
if (isNull || abs(static_cast<int>(to_base)) > 36 || abs(static_cast<int>(to_base)) < 2 ||
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || !(res.length()))
{
isNull = true;
return "";
}
if (from_base < 0)
dec= convStrToNum(res, -from_base, false);
else
dec= (int64_t) convStrToNum( res, from_base, true);
if (from_base < 0)
dec = convStrToNum(res, -from_base, false);
else
dec = (int64_t) convStrToNum( res, from_base, true);
str = helpers::convNumToStr(dec, ans, to_base);
str = helpers::convNumToStr(dec, ans, to_base);
isNull = str.empty();
isNull = str.empty();
return str;
return str;
}

View File

@ -41,17 +41,17 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_crc32::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_crc32::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
return (int64_t) crc32(0L, (unsigned char*)val.c_str(), strlen(val.c_str()));
const string& val = parm[0]->data()->getStrVal(row, isNull);
return (int64_t) crc32(0L, (unsigned char*)val.c_str(), strlen(val.c_str()));
}

View File

@ -44,78 +44,78 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_date::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_date::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
string value = "";
string value = "";
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
return parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
return parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
value = dataconvert::DataConvert::datetimeToString(val1);
value = value.substr(0,10);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
value = dataconvert::DataConvert::datetimeToString(val1);
value = value.substr(0, 10);
break;
}
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
isNull = true;
return 0;
}
break;
{
isNull = true;
return 0;
}
break;
default:
{
std::ostringstream oss;
oss << "date: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "date: datatype of " << execplan::colDataTypeToString(type);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return dataconvert::DataConvert::datetimeToInt(value);
return dataconvert::DataConvert::datetimeToInt(value);
}
string Func_date::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
const string& val = parm[0]->data()->getStrVal(row, isNull);
return val.substr(0,10);
return val.substr(0, 10);
}

File diff suppressed because it is too large Load Diff

View File

@ -40,291 +40,333 @@ namespace helpers
{
const string IDB_date_format(const DateTime& dt, const string& format)
{
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
char* ptr = buf;
uint32_t weekday = 0;
uint32_t dayval = 0;
uint32_t weekval = 0;
uint32_t weekyear = 0;
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
char* ptr = buf;
uint32_t weekday = 0;
uint32_t dayval = 0;
uint32_t weekval = 0;
uint32_t weekyear = 0;
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'M':
sprintf(ptr, "%s", helpers::monthFullNames[dt.month].c_str());
ptr += helpers::monthFullNames[dt.month].length();
break;
case 'b':
sprintf(ptr, "%s", helpers::monthAbNames[dt.month].c_str());
ptr += helpers::monthAbNames[dt.month].length();
break;
case 'W':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayFullNames[weekday].c_str());
ptr += helpers::weekdayFullNames[weekday].length();
break;
case 'w':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, true);
sprintf(ptr, "%01d", weekday);
ptr += 1;
break;
case 'a':
weekday= helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayAbNames[weekday].c_str());
ptr += helpers::weekdayAbNames[weekday].length();
break;
case 'D':
sprintf(ptr, "%s", helpers::dayOfMonth[dt.day].c_str());
ptr += helpers::dayOfMonth[dt.day].length();
break;
case 'Y':
sprintf(ptr, "%04d", dt.year);
ptr += 4;
break;
case 'y':
sprintf(ptr, "%02d", dt.year % 100);
ptr += 2;
break;
case 'm':
sprintf(ptr, "%02d", dt.month);
ptr += 2;
break;
case 'c':
sprintf(ptr, "%d", dt.month);
ptr = ptr + (dt.month >= 10 ? 2 : 1);
break;
case 'd':
sprintf(ptr, "%02d", dt.day);
ptr += 2;
break;
case 'e':
sprintf(ptr, "%d", dt.day);
ptr = ptr + (dt.day >= 10 ? 2 : 1);
break;
case 'f':
sprintf(ptr, "%06d", dt.msecond);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", dt.hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (dt.hour%24 + 11)%12+1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", dt.minute);
ptr += 2;
break;
case 'j':
dayval = helpers::calc_mysql_daynr( dt.year, dt.month, dt.day ) -
helpers::calc_mysql_daynr( dt.year, 1, 1 ) + 1;
sprintf(ptr, "%03d", dayval);
ptr += 3;
break;
case 'k':
sprintf(ptr, "%d", dt.hour);
ptr += (dt.hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (dt.hour%24 + 11)%12+1);
ptr += ((dt.hour%24 + 11)%12+1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (dt.hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (dt.hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(dt.hour + 11) % 12 + 1, dt.minute, dt.second);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", dt.second);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
ptr += 8;
break;
case 'U':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day, 0);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'V':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO );
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'u':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'v':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST| helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'x':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
case 'X':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
default:
*ptr++ = format[i];
}
}
}
*ptr = 0;
return string(buf);
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'M':
sprintf(ptr, "%s", helpers::monthFullNames[dt.month].c_str());
ptr += helpers::monthFullNames[dt.month].length();
break;
case 'b':
sprintf(ptr, "%s", helpers::monthAbNames[dt.month].c_str());
ptr += helpers::monthAbNames[dt.month].length();
break;
case 'W':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayFullNames[weekday].c_str());
ptr += helpers::weekdayFullNames[weekday].length();
break;
case 'w':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, true);
sprintf(ptr, "%01d", weekday);
ptr += 1;
break;
case 'a':
weekday = helpers::calc_mysql_weekday( dt.year, dt.month, dt.day, false);
sprintf(ptr, "%s", helpers::weekdayAbNames[weekday].c_str());
ptr += helpers::weekdayAbNames[weekday].length();
break;
case 'D':
sprintf(ptr, "%s", helpers::dayOfMonth[dt.day].c_str());
ptr += helpers::dayOfMonth[dt.day].length();
break;
case 'Y':
sprintf(ptr, "%04d", dt.year);
ptr += 4;
break;
case 'y':
sprintf(ptr, "%02d", dt.year % 100);
ptr += 2;
break;
case 'm':
sprintf(ptr, "%02d", dt.month);
ptr += 2;
break;
case 'c':
sprintf(ptr, "%d", dt.month);
ptr = ptr + (dt.month >= 10 ? 2 : 1);
break;
case 'd':
sprintf(ptr, "%02d", dt.day);
ptr += 2;
break;
case 'e':
sprintf(ptr, "%d", dt.day);
ptr = ptr + (dt.day >= 10 ? 2 : 1);
break;
case 'f':
sprintf(ptr, "%06d", dt.msecond);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", dt.hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (dt.hour % 24 + 11) % 12 + 1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", dt.minute);
ptr += 2;
break;
case 'j':
dayval = helpers::calc_mysql_daynr( dt.year, dt.month, dt.day ) -
helpers::calc_mysql_daynr( dt.year, 1, 1 ) + 1;
sprintf(ptr, "%03d", dayval);
ptr += 3;
break;
case 'k':
sprintf(ptr, "%d", dt.hour);
ptr += (dt.hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (dt.hour % 24 + 11) % 12 + 1);
ptr += ((dt.hour % 24 + 11) % 12 + 1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (dt.hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (dt.hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(dt.hour + 11) % 12 + 1, dt.minute, dt.second);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", dt.second);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
ptr += 8;
break;
case 'U':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day, 0);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'V':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO );
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'u':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'v':
weekval = helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS);
sprintf(ptr, "%02d", weekval);
ptr += 2;
break;
case 'x':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO | helpers::WEEK_MONDAY_FIRST | helpers::WEEK_GT_THREE_DAYS, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
case 'X':
helpers::calc_mysql_week( dt.year, dt.month, dt.day,
helpers::WEEK_NO_ZERO, &weekyear);
sprintf(ptr, "%04d", weekyear);
ptr += 4;
break;
default:
*ptr++ = format[i];
}
}
}
*ptr = 0;
return string(buf);
}
}
CalpontSystemCatalog::ColType Func_date_format::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_date_format::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
int64_t val = 0;
DateTime dt = 0;
int64_t val = 0;
DateTime dt = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
dt.year = (uint32_t)((val >> 16) & 0xffff);
dt.month = (uint32_t)((val >> 12) & 0xf);
dt.day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
dt.year = (uint32_t)((val >> 16) & 0xffff);
dt.month = (uint32_t)((val >> 12) & 0xf);
dt.day = (uint32_t)((val >> 6) & 0x3f);
break;
const string& format = parm[1]->data()->getStrVal(row, isNull);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
break;
return helpers::IDB_date_format(dt, format);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
dt.year = (uint32_t)((val >> 48) & 0xffff);
dt.month = (uint32_t)((val >> 44) & 0xf);
dt.day = (uint32_t)((val >> 38) & 0x3f);
dt.hour = (uint32_t)((val >> 32) & 0x3f);
dt.minute = (uint32_t)((val >> 26) & 0x3f);
dt.second = (uint32_t)((val >> 20) & 0x3f);
dt.msecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
int32_t Func_date_format::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::dateToInt(getStrVal(row, parm, isNull, ct));
return dataconvert::DataConvert::dateToInt(getStrVal(row, parm, isNull, ct));
}
int64_t Func_date_format::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
}

View File

@ -38,76 +38,87 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_day::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_day::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 6) & 0x3f);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 38) & 0x3f);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 6) & 0x3f);
return -1;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (uint32_t)((val >> 38) & 0x3f);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return -1;
}

View File

@ -39,101 +39,114 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayname::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayname::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
int32_t dayofweek= 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
dayofweek= helpers::calc_mysql_weekday( year, month, day, false);
return dayofweek;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
int32_t dayofweek = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
dayofweek = helpers::calc_mysql_weekday( year, month, day, false);
return dayofweek;
}
string Func_dayname::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t weekday= getIntVal(row, parm, isNull, op_ct);
return helpers::weekdayFullNames[weekday];
uint32_t weekday = getIntVal(row, parm, isNull, op_ct);
return helpers::weekdayFullNames[weekday];
}

View File

@ -39,90 +39,102 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayofweek::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayofweek::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, true) + 1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, true) + 1;
}
} // namespace funcexp

View File

@ -39,91 +39,103 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_dayofyear::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_dayofyear::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_daynr(year, month, day) -
helpers::calc_mysql_daynr(year,1,1) + 1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_daynr(year, month, day) -
helpers::calc_mysql_daynr(year, 1, 1) + 1;
}
} // namespace funcexp

View File

@ -41,64 +41,70 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_div::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_div::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
double val2 = parm[1]->data()->getDoubleVal(row, isNull);
int64_t int_val2 = (int64_t)(val2 > 0 ? val2 + 0.5 : val2 - 0.5);
if (int_val2 == 0)
{
isNull = true;
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
double val2 = parm[1]->data()->getDoubleVal(row, isNull);
int64_t int_val2 = (int64_t)(val2 > 0 ? val2 + 0.5 : val2 - 0.5);
if (int_val2 == 0)
{
isNull = true;
return 0;
}
int64_t int_val1 = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
// MCOL-176 If abs(int_val2) is small enough (like -1), then, this may cause overflow.
// This kludge stops the crash.
if (int_val1 == INT64_MIN)
{
--int_val1;
}
return int_val1 / int_val2;
}
int64_t int_val1 = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
// MCOL-176 If abs(int_val2) is small enough (like -1), then, this may cause overflow.
// This kludge stops the crash.
if (int_val1 == INT64_MIN)
{
--int_val1;
}
return int_val1 / int_val2;
}
uint64_t Func_div::getUintVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint64_t val1 = parm[0]->data()->getUintVal(row, isNull);
uint64_t val2 = parm[1]->data()->getUintVal(row, isNull);
if (val2 == 0)
{
isNull = true;
uint64_t val1 = parm[0]->data()->getUintVal(row, isNull);
uint64_t val2 = parm[1]->data()->getUintVal(row, isNull);
if (val2 == 0)
{
isNull = true;
return 0;
}
return val1 / val2;
}
return val1 / val2;
}
double Func_div::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
return getIntVal(row, parm, isNull, ct);
return getIntVal(row, parm, isNull, ct);
}
string Func_div::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}

View File

@ -39,63 +39,68 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_elt::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_elt::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t number = 0;
uint64_t number = 0;
//get number
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
number = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
number = d.value / helpers::power(d.scale);
int lefto = (d.value - number * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( number >= 0 && lefto > 4 )
number++;
if ( number < 0 && lefto < -4 )
number--;
break;
}
default:
isNull = true;
return "";
}
//get number
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
number = (int64_t) value;
break;
}
if (number < 1)
{
isNull = true;
return "";
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
number = d.value / helpers::power(d.scale);
int lefto = (d.value - number * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if (number > parm.size()-1 )
{
isNull = true;
return "";
}
if ( number >= 0 && lefto > 4 )
number++;
return stringValue(parm[number], row, isNull);
if ( number < 0 && lefto < -4 )
number--;
break;
}
default:
isNull = true;
return "";
}
if (number < 1)
{
isNull = true;
return "";
}
if (number > parm.size() - 1 )
{
isNull = true;
return "";
}
return stringValue(parm[number], row, isNull);
}

View File

@ -43,40 +43,42 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_exp::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
double Func_exp::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
double x = parm[0]->data()->getDoubleVal(row, isNull);
double ret = 0.0;
if (!isNull)
{
errno = 0;
ret = exp(x);
if (errno == ERANGE) // display NULL for out range value
{
if (x > 0)
{
isNull = true;
Message::Args args;
args.add("exp");
args.add(x);
unsigned errcode = ERR_FUNC_OUT_OF_RANGE_RESULT;
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
}
else
ret = 0.0;
}
}
// null value is indicated by isNull
double x = parm[0]->data()->getDoubleVal(row, isNull);
double ret = 0.0;
return ret;
if (!isNull)
{
errno = 0;
ret = exp(x);
if (errno == ERANGE) // display NULL for out range value
{
if (x > 0)
{
isNull = true;
Message::Args args;
args.add("exp");
args.add(x);
unsigned errcode = ERR_FUNC_OUT_OF_RANGE_RESULT;
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
}
else
ret = 0.0;
}
}
return ret;
}

View File

@ -40,56 +40,96 @@ using namespace funcexp;
long long dateGet( uint64_t time, IntervalColumn::interval_type unit, bool dateType )
{
uint64_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0,
msec = 0;
uint64_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0,
msec = 0;
if (dateType)
{
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
}
else
{
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
msec = (uint32_t)((time & 0xfffff));
}
if (dateType)
{
year = (uint32_t)((time >> 16) & 0xffff);
month = (uint32_t)((time >> 12) & 0xf);
day = (uint32_t)((time >> 6) & 0x3f);
}
else
{
year = (uint32_t)((time >> 48) & 0xffff);
month = (uint32_t)((time >> 44) & 0xf);
day = (uint32_t)((time >> 38) & 0x3f);
hour = (uint32_t)((time >> 32) & 0x3f);
min = (uint32_t)((time >> 26) & 0x3f);
sec = (uint32_t)((time >> 20) & 0x3f);
msec = (uint32_t)((time & 0xfffff));
}
switch ( unit )
{
case IntervalColumn::INTERVAL_YEAR:
return year;
case IntervalColumn::INTERVAL_MONTH:
return month;
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:
return month / 4 + 1;
switch( unit ) {
case IntervalColumn::INTERVAL_YEAR: return year;
case IntervalColumn::INTERVAL_MONTH: return month;
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: return month/4+1;
case IntervalColumn::INTERVAL_WEEK:
return helpers::calc_mysql_week(year, month, day, 0);
case IntervalColumn::INTERVAL_YEAR_MONTH: return (year*100)+month;
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;
return helpers::calc_mysql_week(year, month, day, 0);
case IntervalColumn::INTERVAL_YEAR_MONTH:
return (year * 100) + month;
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);
};
throw runtime_error("unit type is not supported: " + unit);
};
}
}
@ -98,49 +138,52 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_extract::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_extract::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
IntervalColumn::interval_type unit = static_cast<IntervalColumn::interval_type>(parm[1]->data()->getIntVal(row, isNull));
uint64_t time;
//@bug4678 handle conversion from non date/datetime datatype
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
time = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val);
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
time = dataconvert::DataConvert::intToDatetime(val);
break;
}
default:
time = parm[0]->data()->getIntVal(row, isNull);
}
uint64_t time;
long long value = dateGet( time, unit, false );
//@bug4678 handle conversion from non date/datetime datatype
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
time = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
return value;
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val);
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
time = dataconvert::DataConvert::intToDatetime(val);
break;
}
default:
time = parm[0]->data()->getIntVal(row, isNull);
}
long long value = dateGet( time, unit, false );
return value;
}

View File

@ -47,70 +47,75 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_find_in_set::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_find_in_set::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
const string& setString = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
if (searchStr.find(",") != string::npos)
return 0;
string newSearchStr(searchStr.substr(0, strlen(searchStr.c_str())));
string newSetString(setString.substr(0, strlen(setString.c_str())));
//tokenize the setStr with comma as seprator.
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep( ",");
tokenizer tokens(newSetString, sep);
unsigned i = 0;
size_t pos = 0;
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
{
pos = (*tok_iter).find(newSearchStr);
i++;
if (( pos != string::npos) && (newSearchStr.length() == (*tok_iter).length()))
return i;
}
return 0;
const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
const string& setString = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
if (searchStr.find(",") != string::npos)
return 0;
string newSearchStr(searchStr.substr(0, strlen(searchStr.c_str())));
string newSetString(setString.substr(0, strlen(setString.c_str())));
//tokenize the setStr with comma as seprator.
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep( ",");
tokenizer tokens(newSetString, sep);
unsigned i = 0;
size_t pos = 0;
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
{
pos = (*tok_iter).find(newSearchStr);
i++;
if (( pos != string::npos) && (newSearchStr.length() == (*tok_iter).length()))
return i;
}
return 0;
}
double Func_find_in_set::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
return (double)getIntVal(row, parm, isNull, ct);
return (double)getIntVal(row, parm, isNull, ct);
}
string Func_find_in_set::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
execplan::IDB_Decimal Func_find_in_set::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal decimal;
decimal.value = getIntVal(row, fp, isNull, op_ct);
decimal.scale = op_ct.scale;
return decimal;
IDB_Decimal decimal;
decimal.value = getIntVal(row, fp, isNull, op_ct);
decimal.scale = op_ct.scale;
return decimal;
}
} // namespace funcexp

View File

@ -43,60 +43,62 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_floor::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType();
return fp[0]->data()->resultType();
}
int64_t Func_floor::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
{
if (op_ct.scale == 0)
{
ret = parm[0]->data()->getIntVal(row, isNull);
break;
}
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
ret = decimal.value;
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
if (isNull)
break;
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
ret = decimal.value;
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// negative scale is not supported by CNX yet
if (decimal.scale > 0)
{
if (decimal.scale >= 19)
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType)
<< " with scale " << (int) decimal.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
int64_t tmp = ret;
ret /= helpers::powerOf10_c[decimal.scale];
// Largest integer value not greater than X.
if (tmp < 0 && tmp < ret)
ret -= 1;
}
}
break;
// Largest integer value not greater than X.
if (tmp < 0 && tmp < ret)
ret -= 1;
}
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -109,77 +111,79 @@ int64_t Func_floor::getIntVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
ret = (int64_t) floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (int64_t) floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t) floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = atoll(str.c_str());
}
break;
if (!isNull)
ret = (int64_t) floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
// strip off micro seconds
str = str.substr(0,14);
if (!isNull)
ret = atoll(str.c_str());
}
break;
if (!isNull)
ret = atoll(str.c_str());
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
// strip off micro seconds
str = str.substr(0, 14);
return ret;
if (!isNull)
ret = atoll(str.c_str());
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
uint64_t Func_floor::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t ret = 0;
int64_t ret = 0;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
ret = parm[0]->data()->getIntVal(row, isNull);
}
break;
{
ret = parm[0]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
@ -192,124 +196,131 @@ uint64_t Func_floor::getUintVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
ret = (uint64_t)floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
{
ret = (uint64_t)floor(parm[0]->data()->getDoubleVal(row, isNull));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t)floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
if (!isNull)
ret = (uint64_t)floor(strtod(str.c_str(), 0));
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
case execplan::CalpontSystemCatalog::DATE:
{
string str = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
// strip off micro seconds
str = str.substr(0,14);
if (!isNull)
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::DATETIME:
{
string str =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
return ret;
// strip off micro seconds
str = str.substr(0, 14);
if (!isNull)
ret = strtoull(str.c_str(), NULL, 10);
}
break;
default:
{
std::ostringstream oss;
oss << "floor: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return ret;
}
double Func_floor::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double ret = 0.0;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT)
{
ret = floor(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
}
else
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
double ret = 0.0;
return ret;
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT)
{
ret = floor(parm[0]->data()->getDoubleVal(row, isNull));
}
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
}
else
{
ret = (double) getIntVal(row, parm, isNull, op_ct);
}
return ret;
}
string Func_floor::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
char tmp[512] = {'\0'};
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
char tmp[512] = {'\0'};
// remove the decimals in the oss string.
char *d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
if (op_ct.colDataType == CalpontSystemCatalog::DOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::UDOUBLE ||
op_ct.colDataType == CalpontSystemCatalog::FLOAT ||
op_ct.colDataType == CalpontSystemCatalog::UFLOAT ||
op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR ||
op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
snprintf(tmp, 511, "%f", getDoubleVal(row, parm, isNull, op_ct));
// remove the decimals in the oss string.
char* d = tmp;
while ((*d != '.') && (*d != '\0'))
d++;
*d = '\0';
}
else if (isUnsigned(op_ct.colDataType))
{
#ifndef __LP64__
snprintf(tmp, 511, "%llu", getUintVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%lu", getUintVal(row, parm, isNull, op_ct));
#endif
}
else
{
else
{
#ifndef __LP64__
snprintf(tmp, 511, "%lld", getIntVal(row, parm, isNull, op_ct));
#else
snprintf(tmp, 511, "%ld", getIntVal(row, parm, isNull, op_ct));
#endif
}
}
return string(tmp);
return string(tmp);
}

View File

@ -40,51 +40,51 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_from_days::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_from_days::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return getDatetimeIntVal(row, parm, isNull, op_ct);
return getDatetimeIntVal(row, parm, isNull, op_ct);
}
string Func_from_days::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
int32_t Func_from_days::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_from_days::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
int64_t daynr = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
double val1 = parm[0]->data()->getDoubleVal(row, isNull);
int64_t daynr = (int64_t)(val1 > 0 ? val1 + 0.5 : val1 - 0.5);
DateTime aDaytime;
helpers::get_date_from_mysql_daynr( daynr, aDaytime );
// to be safe
aDaytime.hour = 0;
aDaytime.minute = 0;
aDaytime.second = 0;
aDaytime.msecond = 0;
DateTime aDaytime;
helpers::get_date_from_mysql_daynr( daynr, aDaytime );
return (*(reinterpret_cast<uint64_t *> (&aDaytime)));
// to be safe
aDaytime.hour = 0;
aDaytime.minute = 0;
aDaytime.second = 0;
aDaytime.msecond = 0;
return (*(reinterpret_cast<uint64_t*> (&aDaytime)));
}

View File

@ -42,46 +42,50 @@ namespace
using namespace funcexp;
DateTime getDateTime(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
int64_t val;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
val = (int64_t)value;
break;
}
default:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
}
if (val < 0 || val > helpers::TIMESTAMP_MAX_VALUE)
return 0;
int64_t val;
DateTime dt;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
struct tm tmp_tm;
time_t tmp_t= (time_t)val;
localtime_r(&tmp_t, &tmp_tm);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
//to->neg=0;
dt.year = (int64_t) ((tmp_tm.tm_year+1900) % 10000);
dt.month = (int64_t) tmp_tm.tm_mon+1;
dt.day = (int64_t) tmp_tm.tm_mday;
dt.hour = (int64_t) tmp_tm.tm_hour;
dt.minute = (int64_t) tmp_tm.tm_min;
dt.second = (int64_t) tmp_tm.tm_sec;
dt.msecond = 0;
return dt;
val = (int64_t)value;
break;
}
default:
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
}
if (val < 0 || val > helpers::TIMESTAMP_MAX_VALUE)
return 0;
DateTime dt;
struct tm tmp_tm;
time_t tmp_t = (time_t)val;
localtime_r(&tmp_t, &tmp_tm);
//to->neg=0;
dt.year = (int64_t) ((tmp_tm.tm_year + 1900) % 10000);
dt.month = (int64_t) tmp_tm.tm_mon + 1;
dt.day = (int64_t) tmp_tm.tm_mday;
dt.hour = (int64_t) tmp_tm.tm_hour;
dt.minute = (int64_t) tmp_tm.tm_min;
dt.second = (int64_t) tmp_tm.tm_sec;
dt.msecond = 0;
return dt;
}
}
@ -90,96 +94,103 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_from_unixtime::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_from_unixtime::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return "";
}
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
DateTime dt = getDateTime(row, parm, isNull);
if (parm.size() == 2)
{
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
char buf[256] = {0};
DataConvert::datetimeToString(*(reinterpret_cast<int64_t*>(&dt)), buf, 255);
return string(buf, 255);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return "";
}
if (parm.size() == 2)
{
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
}
char buf[256] = {0};
DataConvert::datetimeToString(*(reinterpret_cast<int64_t*>(&dt)), buf, 255);
return string(buf, 255);
}
int32_t Func_from_unixtime::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
return (((getDatetimeIntVal(row, parm, isNull, ct) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_from_unixtime::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
return *reinterpret_cast<int64_t*>(&dt);
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
return *reinterpret_cast<int64_t*>(&dt);
}
int64_t Func_from_unixtime::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second );
return atoll(buf);
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second );
return atoll(buf);
}
double Func_from_unixtime::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
if (parm.size() == 1)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
if (parm.size() == 1)
{
DateTime dt = getDateTime(row, parm, isNull);
if (*reinterpret_cast<int64_t*>(&dt) == 0)
{
isNull = true;
return 0;
}
char buf[32]; // actual string guaranteed to be 22
snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d.%06d",
dt.year, dt.month, dt.day, dt.hour,
dt.minute, dt.second, dt.msecond );
return atof(buf);
}
dt.minute, dt.second, dt.msecond );
return atof(buf);
}
return (double) atoi(getStrVal(row, parm, isNull, ct).c_str());
return (double) atoi(getStrVal(row, parm, isNull, ct).c_str());
}

View File

@ -36,81 +36,86 @@ using namespace dataconvert;
class to_upper
{
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
};
namespace funcexp
{
string known_date_time_formats[5][4]=
string known_date_time_formats[5][4] =
{
{"USA", "%m.%d.%Y", "%Y-%m-%d %H.%i.%s", "%h:%i:%s %p" },
{"JIS", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"ISO", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"EUR", "%d.%m.%Y", "%Y-%m-%d %H.%i.%s", "%H.%i.%s" },
{"INTERNAL", "%Y%m%d", "%Y%m%d%H%i%s", "%H%i%s" }
{"USA", "%m.%d.%Y", "%Y-%m-%d %H.%i.%s", "%h:%i:%s %p" },
{"JIS", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"ISO", "%Y-%m-%d", "%Y-%m-%d %H:%i:%s", "%H:%i:%s" },
{"EUR", "%d.%m.%Y", "%Y-%m-%d %H.%i.%s", "%H.%i.%s" },
{"INTERNAL", "%Y%m%d", "%Y%m%d%H%i%s", "%H%i%s" }
};
string know_types[3]=
string know_types[3] =
{
"DATE", "DATETIME", "TIME"
"DATE", "DATETIME", "TIME"
};
CalpontSystemCatalog::ColType Func_get_format::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_get_format::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// parm[0] -- format
// parm[1] -- type
string format = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
// parm[0] -- format
// parm[1] -- type
string format = parm[0]->data()->getStrVal(row, isNull);
transform (format.begin(), format.end(), format.begin(), to_upper());
if (isNull)
return "";
string type = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
return "";
transform (format.begin(), format.end(), format.begin(), to_upper());
transform (type.begin(), type.end(), type.begin(), to_upper());
string type = parm[1]->data()->getStrVal(row, isNull);
int itype = 0;
for ( ; itype < 3 ; itype++ )
{
if ( know_types[itype] == type )
break;
}
if (isNull)
return "";
// check for match
if ( itype == 3 )
return "";
transform (type.begin(), type.end(), type.begin(), to_upper());
for ( int i = 0 ; i < 5 ; i ++ )
{
if ( known_date_time_formats[i][0] == format )
{
switch (itype) {
case 0:
return known_date_time_formats[i][2];
break;
default:
return "";
}
}
}
int itype = 0;
return "";
for ( ; itype < 3 ; itype++ )
{
if ( know_types[itype] == type )
break;
}
// check for match
if ( itype == 3 )
return "";
for ( int i = 0 ; i < 5 ; i ++ )
{
if ( known_date_time_formats[i][0] == format )
{
switch (itype)
{
case 0:
return known_date_time_formats[i][2];
break;
default:
return "";
}
}
}
return "";
}

View File

@ -42,11 +42,11 @@ using namespace funcexp;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -55,146 +55,155 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_greatest::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
int64_t Func_greatest::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
if ( greatestStr < str1 )
greatestStr = str1;
}
if ( greatestStr < str1 )
greatestStr = str1;
}
uint64_t tmp = (uint64_t)greatestStr;
return (int64_t) tmp;
return (int64_t) tmp;
}
uint64_t Func_greatest::getUintVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (uint64_t) greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return (uint64_t) greatestStr;
}
double Func_greatest::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (double) greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return (double) greatestStr;
}
std::string Func_greatest::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str = fp[0]->data()->getStrVal(row, isNull);
string greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
string greatestStr = str;
int tmp = utf8::idb_strcoll(greatestStr.c_str(), str1.c_str());
if ( tmp < 0 )
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(greatestStr.c_str(), str1.c_str());
if ( tmp < 0 )
// if ( greatestStr < str1 )
greatestStr = str1;
}
greatestStr = str1;
}
return greatestStr;
return greatestStr;
}
IDB_Decimal Func_greatest::getDecimalVal(Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
// double str = fp[0]->data()->getDoubleVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
IDB_Decimal greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
int32_t Func_greatest::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
int32_t greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
int64_t Func_greatest::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
int64_t greatestStr = str;
if ( greatestStr < str1 )
greatestStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
return greatestStr;
if ( greatestStr < str1 )
greatestStr = str1;
}
return greatestStr;
}
} // namespace funcexp

View File

@ -41,15 +41,17 @@ namespace
{
char digit_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void octet2hex(char *to, const char *str, uint32_t len)
void octet2hex(char* to, const char* str, uint32_t len)
{
const char *str_end= str + len;
for (; str != str_end; ++str)
{
*to++= digit_upper[((uint8_t) *str) >> 4];
*to++= digit_upper[((uint8_t) *str) & 0x0F];
}
*to = '\0';
const char* str_end = str + len;
for (; str != str_end; ++str)
{
*to++ = digit_upper[((uint8_t) * str) >> 4];
*to++ = digit_upper[((uint8_t) * str) & 0x0F];
}
*to = '\0';
}
}
@ -57,64 +59,70 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_hex::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_hex::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
string retval;
uint64_t dec;
char ans[65];
uint64_t dec;
char ans[65];
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::DATE:
{
const string& arg= parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str())*2+1]);
octet2hex(hexPtr.get(), arg.c_str(), strlen(arg.c_str()));
return string(hexPtr.get(), strlen(arg.c_str())*2);
}
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DECIMAL:
{
/* Return hex of unsigned longlong value */
double val= parm[0]->data()->getDoubleVal(row, isNull);
if ((val <= (double) numeric_limits<int64_t>::min()) ||
(val >= (double) numeric_limits<int64_t>::max()))
dec= ~(int64_t) 0;
else
dec= (uint64_t) (val + (val > 0 ? 0.5 : -0.5));
retval = helpers::convNumToStr(dec, ans, 16);
break;
}
case CalpontSystemCatalog::VARBINARY:
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::DATETIME:
case CalpontSystemCatalog::DATE:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str()) * 2 + 1]);
octet2hex(hexPtr.get(), arg.c_str(), strlen(arg.c_str()));
return string(hexPtr.get(), strlen(arg.c_str()) * 2);
}
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DECIMAL:
{
/* Return hex of unsigned longlong value */
double val = parm[0]->data()->getDoubleVal(row, isNull);
if ((val <= (double) numeric_limits<int64_t>::min()) ||
(val >= (double) numeric_limits<int64_t>::max()))
dec = ~(int64_t) 0;
else
dec = (uint64_t) (val + (val > 0 ? 0.5 : -0.5));
retval = helpers::convNumToStr(dec, ans, 16);
break;
}
case CalpontSystemCatalog::VARBINARY:
case CalpontSystemCatalog::BLOB:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.size() * 2;
scoped_array<char> hexPtr(new char[hexLen + 1]); // "+ 1" for the last \0
octet2hex(hexPtr.get(), arg.data(), arg.size());
return string(hexPtr.get(), hexLen);
}
default:
{
dec= (uint64_t)parm[0]->data()->getIntVal(row, isNull);
retval = helpers::convNumToStr(dec, ans, 16);
if (retval.length() > (uint32_t)ct.colWidth)
retval = retval.substr(retval.length()-ct.colWidth, ct.colWidth);
}
}
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.size() * 2;
scoped_array<char> hexPtr(new char[hexLen + 1]); // "+ 1" for the last \0
octet2hex(hexPtr.get(), arg.data(), arg.size());
return string(hexPtr.get(), hexLen);
}
return retval;
default:
{
dec = (uint64_t)parm[0]->data()->getIntVal(row, isNull);
retval = helpers::convNumToStr(dec, ans, 16);
if (retval.length() > (uint32_t)ct.colWidth)
retval = retval.substr(retval.length() - ct.colWidth, ct.colWidth);
}
}
return retval;
}

View File

@ -38,74 +38,89 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_hour::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_hour::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 32) & 0x3f);
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 32) & 0x3f);
}

View File

@ -45,24 +45,24 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_idbpartition::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// all integer
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
// all integer
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
}
string Func_idbpartition::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
LogicalPartition part(
parm[0]->data()->getIntVal(row, isNull),
parm[1]->data()->getIntVal(row, isNull),
parm[2]->data()->getIntVal(row, isNull));
LogicalPartition part(
parm[0]->data()->getIntVal(row, isNull),
parm[1]->data()->getIntVal(row, isNull),
parm[2]->data()->getIntVal(row, isNull));
return part.toString();
return part.toString();
}

View File

@ -37,45 +37,50 @@ namespace
bool boolVal(SPTP& parm, Row& row)
{
bool ret = true;
bool isNull = false; // Keep it local. We don't want to mess with the global one here.
try
{
ret = parm->getBoolVal(row, isNull);
}
catch (logging::NotImplementedExcept&)
{
switch (parm->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
ret = (atoi((char*)(parm->data()->getStrVal().c_str())) != 0);
bool ret = true;
bool isNull = false; // Keep it local. We don't want to mess with the global one here.
try
{
ret = parm->getBoolVal(row, isNull);
}
catch (logging::NotImplementedExcept&)
{
switch (parm->data()->resultType().colDataType)
{
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
ret = (atoi((char*)(parm->data()->getStrVal().c_str())) != 0);
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
ret = (parm->data()->getFloatVal(row, isNull) != 0);
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UFLOAT:
ret = (parm->data()->getFloatVal(row, isNull) != 0);
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
ret = (parm->data()->getDoubleVal(row, isNull) != 0);
ret = (parm->data()->getDoubleVal(row, isNull) != 0);
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
ret = (parm->data()->getDecimalVal(row, isNull).value != 0);
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
ret = (parm->data()->getDecimalVal(row, isNull).value != 0);
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::USMALLINT:
case CalpontSystemCatalog::UMEDINT:
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
default:
ret = (parm->data()->getIntVal(row, isNull) != 0);
}
}
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::DATETIME:
default:
ret = (parm->data()->getIntVal(row, isNull) != 0);
}
}
return ret;
return ret;
}
}
@ -91,127 +96,127 @@ namespace funcexp
//
CalpontSystemCatalog::ColType Func_if::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
// The result type given by the connector may not be right if there's derived table (MySQL bug?)
// We want to double check on our own.
// If any parm is of string type, the result type should be string.
if (fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
resultType = ct;
return ct;
}
// operation type is not used by this functor
// The result type given by the connector may not be right if there's derived table (MySQL bug?)
// We want to double check on our own.
// If any parm is of string type, the result type should be string.
if (fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR ||
fp[1]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT ||
fp[2]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR)
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
resultType = ct;
return ct;
}
CalpontSystemCatalog::ColType ct = fp[1]->data()->resultType();
PredicateOperator op;
op.setOpType(ct, fp[2]->data()->resultType());
ct = op.operationType();
resultType = ct;
return ct;
CalpontSystemCatalog::ColType ct = fp[1]->data()->resultType();
PredicateOperator op;
op.setOpType(ct, fp[2]->data()->resultType());
ct = op.operationType();
resultType = ct;
return ct;
}
int64_t Func_if::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getIntVal(row, isNull);
}
else
{
return parm[2]->data()->getIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getIntVal(row, isNull);
}
else
{
return parm[2]->data()->getIntVal(row, isNull);
}
}
string Func_if::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getStrVal(row, isNull);
}
else
{
return parm[2]->data()->getStrVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getStrVal(row, isNull);
}
else
{
return parm[2]->data()->getStrVal(row, isNull);
}
}
IDB_Decimal Func_if::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDecimalVal(row, isNull);
}
else
{
return parm[2]->data()->getDecimalVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDecimalVal(row, isNull);
}
else
{
return parm[2]->data()->getDecimalVal(row, isNull);
}
}
double Func_if::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDoubleVal(row, isNull);
}
else
{
return parm[2]->data()->getDoubleVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDoubleVal(row, isNull);
}
else
{
return parm[2]->data()->getDoubleVal(row, isNull);
}
}
int32_t Func_if::getDateIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDateIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDateIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDateIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDateIntVal(row, isNull);
}
}
int64_t Func_if::getDatetimeIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDatetimeIntVal(row, isNull);
}
if (boolVal(parm[0], row))
{
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
else
{
return parm[2]->data()->getDatetimeIntVal(row, isNull);
}
}

View File

@ -45,130 +45,136 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ifnull::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
int64_t Func_ifnull::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getIntVal(row, isNull);
}
return r;
}
string Func_ifnull::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return string();
if (isNull)
return string();
const string& r = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getStrVal(row, isNull);
}
const string& r = parm[0]->data()->getStrVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getStrVal(row, isNull);
}
return r;
}
IDB_Decimal Func_ifnull::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return IDB_Decimal();
if (isNull)
return IDB_Decimal();
IDB_Decimal r = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDecimalVal(row, isNull);
}
IDB_Decimal r = parm[0]->data()->getDecimalVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDecimalVal(row, isNull);
}
return r;
}
double Func_ifnull::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0.0;
if (isNull)
return 0.0;
double r = parm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDoubleVal(row, isNull);
}
double r = parm[0]->data()->getDoubleVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDoubleVal(row, isNull);
}
return r;
}
int32_t Func_ifnull::getDateIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDateIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getDateIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDateIntVal(row, isNull);
}
return r;
}
int64_t Func_ifnull::getDatetimeIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if (isNull)
return 0;
if (isNull)
return 0;
int64_t r = parm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
int64_t r = parm[0]->data()->getDatetimeIntVal(row, isNull);
return r;
if (isNull)
{
isNull = false;
return parm[1]->data()->getDatetimeIntVal(row, isNull);
}
return r;
}
bool Func_ifnull::getBoolVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t ret = getIntVal(row, parm, isNull, ct);
return (ret == 0 ? false : true);
int64_t ret = getIntVal(row, parm, isNull, ct);
return (ret == 0 ? false : true);
}
} // namespace funcexp

View File

@ -45,154 +45,197 @@ using namespace funcexp;
namespace
{
template<typename result_t>
inline bool numericEQ(result_t op1, result_t op2)
{
return op1 == op2;
}
inline bool strEQ(string op1, string op2)
{
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) == 0;
}
inline bool getBoolForIn(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool isNotIn)
{
IDB_Decimal d; // to be removed;
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
template<typename result_t>
inline bool numericEQ(result_t op1, result_t op2)
{
return op1 == op2;
}
inline bool strEQ(string op1, string op2)
{
return utf8::idb_strcoll(op1.c_str(), op2.c_str()) == 0;
}
inline bool getBoolForIn(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct,
bool isNotIn)
{
IDB_Decimal d; // to be removed;
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t val = pm[0]->data()->getIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getUintVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
isNull = false;
if (val == pm[i]->data()->getIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDateIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDatetimeIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDoubleVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDecimalVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( utf8::idb_strcoll(val.c_str(), pm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
default:
{
std::ostringstream oss;
oss << "regexo: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
return false;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t val = pm[0]->data()->getUintVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if (val == pm[i]->data()->getUintVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = pm[0]->data()->getDateIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDateIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = pm[0]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDatetimeIntVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
double val = pm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDoubleVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = pm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( val == pm[i]->data()->getDecimalVal(row, isNull) && !isNull )
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
if ( utf8::idb_strcoll(val.c_str(), pm[i]->data()->getStrVal(row, isNull).c_str()) == 0 && !isNull)
return true;
if (isNull && isNotIn)
return true; // will be reversed to false by the caller
}
return false;
}
default:
{
std::ostringstream oss;
oss << "regexo: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
}
}
namespace funcexp
@ -200,89 +243,95 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_in::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator op;
CalpontSystemCatalog::ColType ct;
// @bug 4230. Initialize ct to be the first argument.
if (!fp.empty())
ct = fp[0]->data()->resultType();
bool allString = true;
bool allNonToken = true;
for (uint32_t i = 0; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT)
{
allString = false;
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
}
else
{
if ((fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colWidth > 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colWidth >= 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colWidth >= 8))
allNonToken = false;
}
}
if (allString && !allNonToken)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (allString && allNonToken)
{
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
}
PredicateOperator op;
CalpontSystemCatalog::ColType ct;
// convert date const value according to the compare type here.
if (op.operationType().colDataType == CalpontSystemCatalog::DATE)
{
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::dateToInt(result.strVal);
cc->result(result);
}
}
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
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::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
// @bug 4230. Initialize ct to be the first argument.
if (!fp.empty())
ct = fp[0]->data()->resultType();
bool allString = true;
bool allNonToken = true;
for (uint32_t i = 0; i < fp.size(); i++)
{
//op.setOpType(op.operationType(), fp[i]->data()->resultType());
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT)
{
allString = false;
op.setOpType(ct, fp[i]->data()->resultType());
ct = op.operationType();
}
else
{
if ((fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colWidth > 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::VARCHAR &&
fp[i]->data()->resultType().colWidth >= 8) ||
(fp[i]->data()->resultType().colDataType == CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colWidth >= 8))
allNonToken = false;
}
}
if (allString && !allNonToken)
{
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
}
else if (allString && allNonToken)
{
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
}
// convert date const value according to the compare type here.
if (op.operationType().colDataType == CalpontSystemCatalog::DATE)
{
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::dateToInt(result.strVal);
cc->result(result);
}
}
}
else if (op.operationType().colDataType == CalpontSystemCatalog::DATETIME)
{
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::datetimeToInt(result.strVal);
cc->result(result);
}
}
}
return ct;
}
bool Func_in::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBoolForIn(row, pm, isNull, ct, false) && !isNull;
return getBoolForIn(row, pm, isNull, ct, false) && !isNull;
}
@ -291,18 +340,18 @@ bool Func_in::getBoolVal(rowgroup::Row& row,
CalpontSystemCatalog::ColType Func_notin::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
PredicateOperator *op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
return op->operationType();
PredicateOperator* op = new PredicateOperator();
CalpontSystemCatalog::ColType ct;
op->setOpType(fp[0]->data()->resultType(), fp[1]->data()->resultType());
return op->operationType();
}
bool Func_notin::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return (!getBoolForIn(row, pm, isNull, ct, true) && !isNull);
return (!getBoolForIn(row, pm, isNull, ct, true) && !isNull);
}

View File

@ -37,10 +37,10 @@ namespace funcexp
// See mcs_add in udfsdk.h for explanation of this function.
//------------------------------------------------------------------------------
execplan::CalpontSystemCatalog::ColType Func_inet_aton::operationType(
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType(); // input type
return fp[0]->data()->resultType(); // input type
}
//------------------------------------------------------------------------------
@ -48,23 +48,25 @@ execplan::CalpontSystemCatalog::ColType Func_inet_aton::operationType(
// SELECT ... WHERE inet_aton(ipstring) = 11111111 will call getIntVal()
//------------------------------------------------------------------------------
int64_t Func_inet_aton::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getIntVal" << std::endl;
int64_t iValue = joblist::NULL_INT64;
int64_t iValue = joblist::NULL_INT64;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -72,23 +74,25 @@ int64_t Func_inet_aton::getIntVal(rowgroup::Row& row,
// SELECT ... WHERE inet_aton(ipstring) = '11111111' will call getDoubleVal()
//------------------------------------------------------------------------------
double Func_inet_aton::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getDoubleVal" << std::endl;
double dValue = doubleNullVal();
double dValue = doubleNullVal();
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
dValue = iValue;
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return dValue;
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
dValue = iValue;
}
return dValue;
}
//------------------------------------------------------------------------------
@ -100,19 +104,20 @@ double Func_inet_aton::getDoubleVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
std::string Func_inet_aton::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getStrVal" << std::endl;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
convertAton( sValue, isNull ); // ignore return value
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return sValue;
if (!isNull)
{
convertAton( sValue, isNull ); // ignore return value
}
return sValue;
}
//------------------------------------------------------------------------------
@ -121,21 +126,23 @@ std::string Func_inet_aton::getStrVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
bool Func_inet_aton::getBoolVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
bool bValue = false;
bool bValue = false;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if ((!isNull) && (iVal != 0))
bValue = true;
}
return bValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if ((!isNull) && (iVal != 0))
bValue = true;
}
return bValue;
}
//------------------------------------------------------------------------------
@ -143,23 +150,25 @@ bool Func_inet_aton::getBoolVal(rowgroup::Row& row,
// SELECT ... WHERE inet_aton(ipstring) = 11111111. will call getDecimalVal()
//------------------------------------------------------------------------------
execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_aton::getDecimalVal" << std::endl;
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
return execplan::IDB_Decimal( iValue, 0, 0 );
}
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
return dValue;
if (!isNull)
{
int64_t iValue = convertAton( sValue, isNull );
if (!isNull)
return execplan::IDB_Decimal( iValue, 0, 0 );
}
return dValue;
}
//------------------------------------------------------------------------------
@ -168,21 +177,23 @@ execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
int32_t Func_inet_aton::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int32_t iValue = joblist::DATENULL;
int32_t iValue = joblist::DATENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -192,21 +203,23 @@ int32_t Func_inet_aton::getDateIntVal(rowgroup::Row& row,
// Don't know if this function will ever be called.
//------------------------------------------------------------------------------
int64_t Func_inet_aton::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int64_t iValue = joblist::DATETIMENULL;
int64_t iValue = joblist::DATETIMENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
{
int64_t iVal = convertAton( sValue, isNull );
if (!isNull)
iValue = iVal;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -215,78 +228,82 @@ int64_t Func_inet_aton::getDatetimeIntVal(rowgroup::Row& row,
// Source code based on MySQL source (Item_func_inet_aton() in item_func.cc).
//------------------------------------------------------------------------------
int64_t Func_inet_aton::convertAton(
const std::string& ipString,
bool& isNull )
const std::string& ipString,
bool& isNull )
{
char c = '.';
int dot_count = 0;
unsigned int byte_result = 0;
unsigned long long result = 0;
char c = '.';
int dot_count = 0;
unsigned int byte_result = 0;
unsigned long long result = 0;
const char* p = ipString.c_str();
const char* end = p + ipString.length();
const char* p = ipString.c_str();
const char* end = p + ipString.length();
// Loop through bytes in the IP address string
while (p < end)
{
c = *p++;
// Loop through bytes in the IP address string
while (p < end)
{
c = *p++;
int digit = (int) (c - '0'); // Assume ascii
if (digit >= 0 && digit <= 9)
{
// Add the next digit from the string to byte_result
if ((byte_result = byte_result * 10 + digit) > 255)
{
// Wrong address
isNull = true;
return 0;
}
}
// Detect end of one portion of the IP address.
// Shift current result over 8 bits, and add next byte (byte_result)
else if (c == '.')
{
dot_count++;
result= (result << 8) + (unsigned long long) byte_result;
byte_result = 0;
}
// Exit loop if/when we encounter end of string for fixed length column,
// that is padded with '\0' at the end.
else if (c == '\0')
{
break;
}
else
{
// Invalid character
isNull = true;
return 0;
}
}
int digit = (int) (c - '0'); // Assume ascii
if (c != '.') // IP number can't end on '.'
{
//
// Handle short-forms addresses according to standard. Examples:
// 127 -> 0.0.0.127
// 127.1 -> 127.0.0.1
// 127.2.1 -> 127.2.0.1
//
switch (dot_count)
{
case 1: result<<= 8; /* Fall through */
case 2: result<<= 8; /* Fall through */
}
if (digit >= 0 && digit <= 9)
{
// Add the next digit from the string to byte_result
if ((byte_result = byte_result * 10 + digit) > 255)
{
// Wrong address
isNull = true;
return 0;
}
}
// Detect end of one portion of the IP address.
// Shift current result over 8 bits, and add next byte (byte_result)
else if (c == '.')
{
dot_count++;
result = (result << 8) + (unsigned long long) byte_result;
byte_result = 0;
}
// Exit loop if/when we encounter end of string for fixed length column,
// that is padded with '\0' at the end.
else if (c == '\0')
{
break;
}
else
{
// Invalid character
isNull = true;
return 0;
}
}
if (c != '.') // IP number can't end on '.'
{
//
// Handle short-forms addresses according to standard. Examples:
// 127 -> 0.0.0.127
// 127.1 -> 127.0.0.1
// 127.2.1 -> 127.2.0.1
//
switch (dot_count)
{
case 1:
result <<= 8; /* Fall through */
case 2:
result <<= 8; /* Fall through */
}
// std::cout << "aton: " <<
// (result << 8) + (unsigned long long) byte_result << std::endl;
return (result << 8) + (unsigned long long) byte_result;
}
return (result << 8) + (unsigned long long) byte_result;
}
// Invalid IP address ended in '.'
isNull = true;
return 0;
// Invalid IP address ended in '.'
isNull = true;
return 0;
}
}

View File

@ -57,10 +57,10 @@ namespace funcexp
// See mcs_add in udfsdk.h for explanation of this function.
//------------------------------------------------------------------------------
execplan::CalpontSystemCatalog::ColType Func_inet_ntoa::operationType(
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
FunctionParm& fp,
execplan::CalpontSystemCatalog::ColType& resultType)
{
return fp[0]->data()->resultType(); // input type
return fp[0]->data()->resultType(); // input type
}
//------------------------------------------------------------------------------
@ -69,30 +69,33 @@ execplan::CalpontSystemCatalog::ColType Func_inet_ntoa::operationType(
// to be safe. (See getDoubleVal() description)
//------------------------------------------------------------------------------
int64_t Func_inet_ntoa::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getIntVal" << std::endl;
std::string sValue = getStrVal( row, fp, isNull, op_ct );
int64_t iValue = joblist::NULL_INT64;
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
if (dot1 != std::string::npos)
{
newLength = dot1;
}
std::string sValue = getStrVal( row, fp, isNull, op_ct );
int64_t iValue = joblist::NULL_INT64;
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> iValue;
}
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
return iValue;
if (dot1 != std::string::npos)
{
newLength = dot1;
}
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> iValue;
}
return iValue;
}
//------------------------------------------------------------------------------
@ -101,34 +104,38 @@ int64_t Func_inet_ntoa::getIntVal(rowgroup::Row& row,
// SELECT ... WHERE inet_ntoa(ipstring) = 1 will also call getDoubleVal()
//------------------------------------------------------------------------------
double Func_inet_ntoa::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDoubleVal" << std::endl;
std::string sValue = getStrVal( row, fp, isNull, op_ct );
double dValue = doubleNullVal();
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
if ((dot1 != std::string::npos) && (sValue.length() > dot1+1))
{
std::string::size_type dot2 = sValue.find('.', dot1+1);
if (dot2 != std::string::npos)
{
newLength = dot2;
}
}
std::string sValue = getStrVal( row, fp, isNull, op_ct );
double dValue = doubleNullVal();
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> dValue;
}
if ( !isNull )
{
unsigned int newLength = sValue.length();
std::string::size_type dot1 = sValue.find('.');
return dValue;
if ((dot1 != std::string::npos) && (sValue.length() > dot1 + 1))
{
std::string::size_type dot2 = sValue.find('.', dot1 + 1);
if (dot2 != std::string::npos)
{
newLength = dot2;
}
}
if (newLength != sValue.length())
sValue.resize(newLength);
std::istringstream iss( sValue );
iss >> dValue;
}
return dValue;
}
//------------------------------------------------------------------------------
@ -136,46 +143,47 @@ double Func_inet_ntoa::getDoubleVal(rowgroup::Row& row,
// This is the get function that makes sense to use.
//------------------------------------------------------------------------------
std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getStrVal" << std::endl;
std::string sValue;
std::string sValue;
int64_t iValue = 0;
int64_t iValue = 0;
// @bug 3628 reopened: get double and round up, if necessary;
// else just get integer value
if ((fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::FLOAT) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DOUBLE))
{
double d = fp[0]->data()->getDoubleVal(row, isNull);
if (d >= 0.0)
iValue = (int64_t)(d + 0.5);
else
iValue = (int64_t)(d - 0.5);
}
else
{
iValue = fp[0]->data()->getIntVal(row, isNull);
}
// @bug 3628 reopened: get double and round up, if necessary;
// else just get integer value
if ((fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DECIMAL) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::FLOAT) ||
(fp[0]->data()->resultType().colDataType ==
execplan::CalpontSystemCatalog::DOUBLE))
{
double d = fp[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
// @bug 3628 reopened: add check for out of range values
if ((iValue < 0) || (iValue > UINT_MAX))
isNull = true;
else
convertNtoa( iValue, sValue );
}
if (d >= 0.0)
iValue = (int64_t)(d + 0.5);
else
iValue = (int64_t)(d - 0.5);
}
else
{
iValue = fp[0]->data()->getIntVal(row, isNull);
}
return sValue;
if (!isNull)
{
// @bug 3628 reopened: add check for out of range values
if ((iValue < 0) || (iValue > UINT_MAX))
isNull = true;
else
convertNtoa( iValue, sValue );
}
return sValue;
}
//------------------------------------------------------------------------------
@ -183,15 +191,15 @@ std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
bool Func_inet_ntoa::getBoolVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getBoolVal" << std::endl;
bool bValue = false;
isNull = true;
bool bValue = false;
isNull = true;
return bValue;
return bValue;
}
//------------------------------------------------------------------------------
@ -199,17 +207,17 @@ bool Func_inet_ntoa::getBoolVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
execplan::IDB_Decimal Func_inet_ntoa::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDecimalVal" << std::endl;
// IDB_Decimal dValue = fp[0]->data()->getDecimalVal(row, isNull);
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
isNull = true;
execplan::IDB_Decimal dValue ( joblist::NULL_INT64, 0, 0 );
isNull = true;
return dValue;
return dValue;
}
//------------------------------------------------------------------------------
@ -217,17 +225,17 @@ execplan::IDB_Decimal Func_inet_ntoa::getDecimalVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
int32_t Func_inet_ntoa::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDateIntVal" << std::endl;
// int32_t iValue = fp[0]->data()->getDateIntVal(row, isNull);
int32_t iValue = joblist::DATENULL;
isNull = true;
int32_t iValue = joblist::DATENULL;
isNull = true;
return iValue;
return iValue;
}
//------------------------------------------------------------------------------
@ -235,17 +243,17 @@ int32_t Func_inet_ntoa::getDateIntVal(rowgroup::Row& row,
// N/A so returning null. See explanation at the top of this source file.
//------------------------------------------------------------------------------
int64_t Func_inet_ntoa::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// std::cout << "In Func_inet_ntoa::getDatetimeVal" << std::endl;
// int64t iValue = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t iValue = joblist::DATETIMENULL;
isNull = true;
int64_t iValue = joblist::DATETIMENULL;
isNull = true;
return iValue;
return iValue;
}
//------------------------------------------------------------------------------
@ -253,8 +261,8 @@ int64_t Func_inet_ntoa::getDatetimeIntVal(rowgroup::Row& row,
// Source code based on MySQL source (Item_func_inet_ntoa() in item_strfunc.cc).
//------------------------------------------------------------------------------
void Func_inet_ntoa::convertNtoa(
int64_t ipNum,
std::string& ipString )
int64_t ipNum,
std::string& ipString )
{
struct sockaddr_in sa;
sa.sin_addr.s_addr = htonl(ipNum);

View File

@ -44,66 +44,71 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_insert::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string insertStr(const string& src, int pos, int len, const string& targ)
{
int64_t strLen = static_cast<int64_t>(src.length());
int64_t strLen = static_cast<int64_t>(src.length());
if ((pos <= 0) || ((pos-1) >= strLen))
if ((pos <= 0) || ((pos - 1) >= strLen))
return src;
if ((len < 0) || (len > strLen))
len = strLen;
const char* srcptr = src.c_str();
advance(srcptr,pos-1,srcptr+strLen);
advance(srcptr, pos - 1, srcptr + strLen);
// srcptr now pointing to where we need to insert targ string
uint32_t srcPos = srcptr - src.c_str();
uint32_t finPos = strLen;
const char* finptr = src.c_str();
if ((strLen - (pos-1+len)) >= 0)
const char* finptr = src.c_str();
if ((strLen - (pos - 1 + len)) >= 0)
{
advance(finptr,(pos-1+len),finptr+strLen);
// finptr now pointing to the end of the string to replace
finPos = finptr - src.c_str();
advance(finptr, (pos - 1 + len), finptr + strLen);
// finptr now pointing to the end of the string to replace
finPos = finptr - src.c_str();
}
string out;
out.reserve(srcPos + targ.length() + strLen-finPos + 1);
out.reserve(srcPos + targ.length() + strLen - finPos + 1);
out.append( src.c_str(), srcPos );
out.append( targ.c_str(), targ.length() );
out.append( src.c_str() + finPos, strLen-finPos );
out.append( src.c_str() + finPos, strLen - finPos );
return out;
}
std::string Func_insert::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = stringValue(fp[0], row, isNull);
if (isNull)
return "";
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = stringValue(fp[0], row, isNull);
const string& tnewstr = stringValue(fp[3], row, isNull);
if (isNull)
return "";
if (isNull)
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
const string& tnewstr = stringValue(fp[3], row, isNull);
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (isNull)
return "";
if (isNull)
return "";
return insertStr( tstr, pos, len, tnewstr );
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (isNull)
return "";
return insertStr( tstr, pos, len, tnewstr );
}

View File

@ -36,41 +36,42 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_instr::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
size_t Func_instr::in_str(const string& str, const string& substr, size_t start)
{
// convert both inputs to wide character strings
std::wstring wcstr = utf8::utf8_to_wstring(str);
std::wstring wcsubstr = utf8::utf8_to_wstring(substr);
// convert both inputs to wide character strings
std::wstring wcstr = utf8::utf8_to_wstring(str);
std::wstring wcsubstr = utf8::utf8_to_wstring(substr);
if ((str.length() && !wcstr.length()) ||
(substr.length() && !wcsubstr.length()))
// this means one or both of the strings had conversion errors to wide character
return 0;
if ((str.length() && !wcstr.length()) ||
(substr.length() && !wcsubstr.length()))
// this means one or both of the strings had conversion errors to wide character
return 0;
size_t pos = wcstr.find(wcsubstr, start-1);
return (pos != string::npos ? pos+1 : 0);
size_t pos = wcstr.find(wcsubstr, start - 1);
return (pos != string::npos ? pos + 1 : 0);
}
int64_t Func_instr::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t start = 1;
if (parm.size() == 3)
start = parm[2]->data()->getIntVal(row, isNull);
uint64_t start = 1;
if (isNull || start == 0)
return 0;
if (parm.size() == 3)
start = parm[2]->data()->getIntVal(row, isNull);
//Bug 5110 : to support utf8 char type, we have to convert and search
return in_str(parm[0]->data()->getStrVal(row, isNull), parm[1]->data()->getStrVal(row, isNull), start);
if (isNull || start == 0)
return 0;
//Bug 5110 : to support utf8 char type, we have to convert and search
return in_str(parm[0]->data()->getStrVal(row, isNull), parm[1]->data()->getStrVal(row, isNull), start);
}

View File

@ -37,12 +37,12 @@ using namespace rowgroup;
namespace funcexp
{
CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType)
CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType)
{
// operation type of idb_isnull should be the same as the argument type
assert (fp.size() == 1);
return fp[0]->data()->resultType();
// operation type of idb_isnull should be the same as the argument type
assert (fp.size() == 1);
return fp[0]->data()->resultType();
}
/**
@ -51,34 +51,37 @@ CalpontSystemCatalog::ColType Func_isnull::operationType (FunctionParm& fp,
* This would be the most commonly called API for idb_isnull function
*/
bool Func_isnull::getBoolVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
switch (op_ct.colDataType)
{
// For the purpose of this function, one does not need to get the value of
// the argument. One only need to know if the argument is NULL. The passed
// in parameter isNull will be set if the parameter is evaluated NULL.
// Please note that before this function returns, isNull should be set to
// false, otherwise the result of the function would be considered NULL,
// which is not possible for idb_isnull().
switch (op_ct.colDataType)
{
// For the purpose of this function, one does not need to get the value of
// the argument. One only need to know if the argument is NULL. The passed
// in parameter isNull will be set if the parameter is evaluated NULL.
// Please note that before this function returns, isNull should be set to
// false, otherwise the result of the function would be considered NULL,
// which is not possible for idb_isnull().
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
parm[0]->data()->getDecimalVal(row, isNull);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
parm[0]->data()->getStrVal(row, isNull);
break;
default:
parm[0]->data()->getIntVal(row, isNull);
}
bool ret = isNull;
// It's important to reset isNull indicator.
isNull = false;
return (fIsNotNull? !ret : ret);
case CalpontSystemCatalog::UDECIMAL:
parm[0]->data()->getDecimalVal(row, isNull);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
parm[0]->data()->getStrVal(row, isNull);
break;
default:
parm[0]->data()->getIntVal(row, isNull);
}
bool ret = isNull;
// It's important to reset isNull indicator.
isNull = false;
return (fIsNotNull ? !ret : ret);
}

View File

@ -40,117 +40,132 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_last_day::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_last_day::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
uint32_t lastday = day;
if (isLeapYear(year) && (month == 2))
{
lastday = 29;
}
else if ( month == 2)
{
lastday = 28;
}
else
{
lastday = daysInMonth[month-1];
}
if (day > lastday)
{
isNull = true;
return -1;
}
dataconvert::DateTime aDay;
aDay.year = year;
aDay.month = month;
aDay.day = lastday;
aDay.hour = 0;
aDay.minute = 0;
aDay.second = 0;
aDay.msecond = 0;
val = *(reinterpret_cast<uint64_t*>(&aDay));
return val;
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
uint32_t lastday = day;
if (isLeapYear(year) && (month == 2))
{
lastday = 29;
}
else if ( month == 2)
{
lastday = 28;
}
else
{
lastday = daysInMonth[month - 1];
}
if (day > lastday)
{
isNull = true;
return -1;
}
dataconvert::DateTime aDay;
aDay.year = year;
aDay.month = month;
aDay.day = lastday;
aDay.hour = 0;
aDay.minute = 0;
aDay.second = 0;
aDay.msecond = 0;
val = *(reinterpret_cast<uint64_t*>(&aDay));
return val;
}

View File

@ -37,47 +37,49 @@ using namespace joblist;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
namespace funcexp
{
CalpontSystemCatalog::ColType Func_lcase::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType){
// operation type is not used by this functor
return fp[0]->data()->resultType();
CalpontSystemCatalog::ColType Func_lcase::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_lcase::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// string str = fp[0]->data()->getStrVal(row, isNull);
// transform (str.begin(), str.end(), str.begin(), to_lower());
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
if (isNull)
return "";
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towlower(wstr[i]);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towlower(wstr[i]);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
} // namespace funcexp

View File

@ -41,11 +41,11 @@ using namespace funcexp;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -55,124 +55,131 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_least::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
int64_t Func_least::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (int64_t) leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return (int64_t) leastStr;
}
double Func_least::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double str = fp[0]->data()->getDoubleVal(row, isNull);
double str = fp[0]->data()->getDoubleVal(row, isNull);
double leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
double leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
double str1 = fp[i]->data()->getDoubleVal(row, isNull);
return (double) leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return (double) leastStr;
}
std::string Func_least::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
string leastStr = fp[0]->data()->getStrVal(row, isNull);
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
string leastStr = fp[0]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(leastStr.c_str(), str1.c_str());
if ( tmp > 0 )
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
int tmp = utf8::idb_strcoll(leastStr.c_str(), str1.c_str());
if ( tmp > 0 )
// if ( leastStr > str1 )
leastStr = str1;
}
leastStr = str1;
}
return leastStr;
return leastStr;
}
IDB_Decimal Func_least::getDecimalVal(Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull);
IDB_Decimal leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
IDB_Decimal leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}
int32_t Func_least::getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t str = fp[0]->data()->getDateIntVal(row, isNull);
int32_t leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
int32_t leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}
int64_t Func_least::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull);
int64_t leastStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
int64_t leastStr = str;
if ( leastStr > str1 )
leastStr = str1;
}
for (uint32_t i = 1; i < fp.size(); i++)
{
int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull);
return leastStr;
if ( leastStr > str1 )
leastStr = str1;
}
return leastStr;
}

View File

@ -40,40 +40,42 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_left::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_left::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (isNull)
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull) - 1;
if (isNull)
return "";
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (pos == -1) // pos == 0
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull) - 1;
wstring out = str.substr(0, pos+1);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
if (isNull)
return "";
if (pos == -1) // pos == 0
return "";
wstring out = str.substr(0, pos + 1);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
// return str.substr(0, pos+1);
}
}
} // namespace funcexp

View File

@ -37,22 +37,22 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_length::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
int64_t Func_length::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
if ((fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::VARBINARY) ||
(fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::BLOB))
return fp[0]->data()->getStrVal(row, isNull).length();
if ((fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::VARBINARY) ||
(fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::BLOB))
return fp[0]->data()->getStrVal(row, isNull).length();
return strlen(fp[0]->data()->getStrVal(row, isNull).c_str());
return strlen(fp[0]->data()->getStrVal(row, isNull).c_str());
}

156
utils/funcexp/func_lpad.cpp Executable file → Normal file
View File

@ -41,21 +41,21 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_lpad::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_lpad::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
unsigned i;
// The number of characters (not bytes) in our input str.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in our pad str.
size_t padwclen;
@ -64,59 +64,63 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// The result length in number of characters
size_t len = 0;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min()+2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
if (len < 1)
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min() + 2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (len < 1)
return "";
// The pad characters.
@ -125,24 +129,28 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
size_t alen = len;
if(strwclen > len)
alen = strwclen;
size_t bufsize = (alen+1) * sizeof(wchar_t);
if (strwclen > len)
alen = strwclen;
size_t bufsize = (alen + 1) * sizeof(wchar_t);
// Convert to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
size_t strSize = strwclen; // The number of significant characters
const wchar_t* pWChar = wcbuf;
for (i = 0; *pWChar != '\0' && i < strwclen; ++pWChar, ++i)
{
}
strSize = i;
// If the incoming str is exactly the len of the result str,
@ -154,22 +162,22 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// If the incoming str is too big for the result str
// truncate the widechar buffer and return as a string
if (strSize > len)
if (strSize > len)
{
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
}
// This is the case where there's room to pad.
// Convert the pad string to wide
padwclen = pad.length(); // A guess to start.
size_t padbufsize = (padwclen+1) * sizeof(wchar_t);
size_t padbufsize = (padwclen + 1) * sizeof(wchar_t);
wchar_t* wcpad = (wchar_t*)alloca(padbufsize);
// padwclen+1 is for giving count for the terminating null
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen+1);
// padwclen+1 is for giving count for the terminating null
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen + 1);
// How many chars do we need?
size_t padspace = len - strSize;
@ -180,6 +188,7 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// Testing has shown that this loop is faster than memmove
wchar_t* newchar = wcbuf + len; // Last spot to put a char in buf
wchar_t* pChar = wcbuf + strSize; // terminal NULL of our str
while (pChar >= wcbuf)
{
*newchar-- = *pChar--;
@ -187,25 +196,28 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row,
// Fill in the front of the buffer with the pad chars
wchar_t* firstpadchar = wcbuf;
for (wchar_t* pch = wcbuf; pch < startofstr && padlen > 0;)
for (wchar_t* pch = wcbuf; pch < startofstr && padlen > 0;)
{
// Truncate the number of fill chars if running out of space
if (padlen > padspace)
{
padlen = padspace;
}
// Move the fill chars to buffer
for (wchar_t* padchar = wcpad; padchar < wcpad + padlen; ++padchar)
{
*firstpadchar++ = *padchar;
}
padspace -= padlen;
pch += padlen;
}
wstring padded = wstring(wcbuf, len);
// Turn back to a string
return utf8::wstring_to_utf8(padded.c_str());
wstring padded = wstring(wcbuf, len);
// Turn back to a string
return utf8::wstring_to_utf8(padded.c_str());
}

View File

@ -41,20 +41,20 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_ltrim::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_ltrim::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// The number of characters (not bytes) in our input tstr.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in ourtrim tstr.
size_t trimwclen;
@ -66,59 +66,65 @@ std::string Func_ltrim::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
if (tstr.empty() || tstr.length() == 0)
return tstr;
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than:
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
int bufsize = (strwclen+1) * sizeof(wchar_t);
int bufsize = (strwclen + 1) * sizeof(wchar_t);
// Convert the string to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if(strwclen == static_cast<size_t>(-1))
strwclen = 0;
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if (strwclen == static_cast<size_t>(-1))
strwclen = 0;
// Convert the trim string to wide
trimwclen = trim.length(); // A guess to start.
int trimbufsize = (trimwclen+1) * sizeof(wchar_t);
int trimbufsize = (trimwclen + 1) * sizeof(wchar_t);
wchar_t* wctrim = (wchar_t*)alloca(trimbufsize);
size_t trimlen = utf8::idb_mbstowcs(wctrim,trim.c_str(), trimwclen+1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if(trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimlen = utf8::idb_mbstowcs(wctrim, trim.c_str(), trimwclen + 1);
// idb_mbstowcs can return -1 if there is bad mbs char in tstr
if (trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimCmpLen = trimlen * sizeof(wchar_t);
const wchar_t* oPtr = wcbuf; // To remember the start of the string
const wchar_t* aPtr = oPtr;
const wchar_t* aEnd = wcbuf+strwclen-1;
const wchar_t* aEnd = wcbuf + strwclen - 1;
if(trimlen>0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr=wctrim[0];
while (aPtr <= aEnd && *aPtr == chr)
aPtr++;
}
else
{
aEnd-=(trimlen-1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
aPtr+=trimlen;
}
}
if (trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr = wctrim[0];
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen-(aPtr-oPtr);
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
while (aPtr <= aEnd && *aPtr == chr)
aPtr++;
}
else
{
aEnd -= (trimlen - 1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
aPtr += trimlen;
}
}
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen - (aPtr - oPtr);
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
} // namespace funcexp

View File

@ -40,45 +40,51 @@ using namespace funcexp;
namespace
{
uint64_t makedate(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull)
FunctionParm& parm,
bool& isNull)
{
int64_t year = 0;
string dayofyear;
int64_t year = 0;
string dayofyear;
//get year
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
year = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
year = d.value / helpers::power(d.scale);
int lefto = (d.value - year * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( year >= 0 && lefto > 4 )
year++;
if ( year < 0 && lefto < -4 )
year--;
break;
}
default:
isNull = true;
return 0;
}
//get year
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
year = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
year = d.value / helpers::power(d.scale);
int lefto = (d.value - year * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( year >= 0 && lefto > 4 )
year++;
if ( year < 0 && lefto < -4 )
year--;
break;
}
default:
isNull = true;
return 0;
}
if (year < 70)
{
year = 2000 + year;
@ -87,74 +93,80 @@ uint64_t makedate(rowgroup::Row& row,
{
year = 1900 + year;
}
else if (year < 1000 || year > 9999) {
isNull = true;
return 0;
}
else if (year < 1000 || year > 9999)
{
isNull = true;
return 0;
}
//get dayofyear
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
dayofyear = parm[1]->data()->getStrVal(row, isNull);
//get dayofyear
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
dayofyear = parm[1]->data()->getStrVal(row, isNull);
if (atoi(dayofyear.c_str()) < 1)
{
isNull = true;
return 0;
}
if (atoi(dayofyear.c_str()) < 1)
{
isNull = true;
return 0;
}
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
int64_t tmp = d.value / helpers::power(d.scale);
int lefto = (d.value - tmp * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( tmp >= 0 && lefto > 4 )
tmp++;
if ( tmp < 0 && lefto < -4 )
tmp--;
break;
}
if (tmp < 1)
{
isNull = true;
return 0;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
int64_t tmp = d.value / helpers::power(d.scale);
int lefto = (d.value - tmp * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( tmp >= 0 && lefto > 4 )
tmp++;
if ( tmp < 0 && lefto < -4 )
tmp--;
if (tmp < 1)
{
isNull = true;
return 0;
}
dayofyear = helpers::intToString(tmp);
break;
}
default:
isNull = true;
return 0;
}
break;
}
default:
isNull = true;
return 0;
}
// convert the year to a date in our internal format, then subtract
// one since we are about to add the day of year back in
Date d(year,1,1);
Date d(year, 1, 1);
//@Bug 5232. spare bit is set, cannot use regular substraction
d.day -= 1;
//uint64_t intDate = ((*(reinterpret_cast<uint32_t *> (&d))) & 0xFFFFFFC) - 1;
uint64_t intDate = *(reinterpret_cast<uint32_t *> (&d));
uint64_t intDate = *(reinterpret_cast<uint32_t*> (&d));
uint64_t value = helpers::dateAdd( intDate, dayofyear, IntervalColumn::INTERVAL_DAY, true, OP_ADD );
uint64_t value = helpers::dateAdd( intDate, dayofyear, IntervalColumn::INTERVAL_DAY, true, OP_ADD );
if ( value == 0 ) {
isNull = true;
}
if ( value == 0 )
{
isNull = true;
}
return value;
return value;
}
}
@ -165,29 +177,30 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_makedate::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_makedate::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
return makedate(row, parm, isNull);
return makedate(row, parm, isNull);
}
string Func_makedate::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
uint64_t value = makedate(row, parm, isNull);
if (isNull)
return "";
uint64_t value = makedate(row, parm, isNull);
return dataconvert::DataConvert::dateToString(value);
if (isNull)
return "";
return dataconvert::DataConvert::dateToString(value);
}

View File

@ -40,147 +40,162 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_maketime::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_maketime::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
int64_t hour = 0;
int64_t min = 0;
int64_t sec = 0;
int64_t hour = 0;
int64_t min = 0;
int64_t sec = 0;
//get hour
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
hour = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
hour = d.value / helpers::power(d.scale);
int lefto = (d.value - hour * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( hour >= 0 && lefto > 4 )
hour++;
if ( hour < 0 && lefto < -4 )
hour--;
break;
}
default:
isNull = true;
return "";
}
//get hour
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
hour = (int64_t) value;
break;
}
//get minute
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[1]->data()->getDoubleVal(row, isNull);
min = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
min = d.value / helpers::power(d.scale);
int lefto = (d.value - min * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( min >= 0 && lefto > 4 )
min++;
if ( min < 0 && lefto < -4 )
min--;
break;
}
default:
isNull = true;
return "";
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
hour = d.value / helpers::power(d.scale);
int lefto = (d.value - hour * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if (min < 0 || min > 59)
{
isNull = true;
return "";
}
if ( hour >= 0 && lefto > 4 )
hour++;
//get second
switch (parm[2]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[2]->data()->getDoubleVal(row, isNull);
sec = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[2]->data()->getDecimalVal(row, isNull);
sec = d.value / helpers::power(d.scale);
int lefto = (d.value - sec * helpers::power(d.scale)) / helpers::power(d.scale-1);
if ( sec >= 0 && lefto > 4 )
sec++;
if ( sec < 0 && lefto < -4 )
sec--;
break;
}
default:
isNull = true;
return "";
}
if ( hour < 0 && lefto < -4 )
hour--;
if (sec < 0 || sec > 59)
{
isNull = true;
return "";
}
break;
}
if (hour > 838)
{
hour = 838;
min = 59;
sec = 59;
}
default:
isNull = true;
return "";
}
if (hour < -838)
{
hour = -838;
min = 59;
sec = 59;
}
//get minute
switch (parm[1]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[1]->data()->getDoubleVal(row, isNull);
min = (int64_t) value;
break;
}
// in worst case hour is 4 characters (3 digits + '-') so max
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
min = d.value / helpers::power(d.scale);
int lefto = (d.value - min * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( min >= 0 && lefto > 4 )
min++;
if ( min < 0 && lefto < -4 )
min--;
break;
}
default:
isNull = true;
return "";
}
if (min < 0 || min > 59)
{
isNull = true;
return "";
}
//get second
switch (parm[2]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
double value = parm[2]->data()->getDoubleVal(row, isNull);
sec = (int64_t) value;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
IDB_Decimal d = parm[2]->data()->getDecimalVal(row, isNull);
sec = d.value / helpers::power(d.scale);
int lefto = (d.value - sec * helpers::power(d.scale)) / helpers::power(d.scale - 1);
if ( sec >= 0 && lefto > 4 )
sec++;
if ( sec < 0 && lefto < -4 )
sec--;
break;
}
default:
isNull = true;
return "";
}
if (sec < 0 || sec > 59)
{
isNull = true;
return "";
}
if (hour > 838)
{
hour = 838;
min = 59;
sec = 59;
}
if (hour < -838)
{
hour = -838;
min = 59;
sec = 59;
}
// in worst case hour is 4 characters (3 digits + '-') so max
// string length is 11 (4:2:2 + '\0')
char buf[11];
snprintf(buf, 11, "%02d:%02d:%02d", (int) hour, (int) min, (int) sec);

File diff suppressed because it is too large Load Diff

View File

@ -88,53 +88,85 @@ class md5
{
// Methods
public:
md5() { Init(); }
void Init();
void Update(uchar* chInput, uint4 nInputLen);
void Finalize();
uchar* Digest() { return m_Digest; }
md5()
{
Init();
}
void Init();
void Update(uchar* chInput, uint4 nInputLen);
void Finalize();
uchar* Digest()
{
return m_Digest;
}
private:
void Transform(uchar* block);
void Encode(uchar* dest, uint4* src, uint4 nLength);
void Decode(uint4* dest, uchar* src, uint4 nLength);
void Transform(uchar* block);
void Encode(uchar* dest, uint4* src, uint4 nLength);
void Decode(uint4* dest, uchar* src, uint4 nLength);
inline uint4 rotate_left(uint4 x, uint4 n)
{ return ((x << n) | (x >> (32-n))); }
inline uint4 rotate_left(uint4 x, uint4 n)
{
return ((x << n) | (x >> (32 - n)));
}
inline uint4 F(uint4 x, uint4 y, uint4 z)
{ return ((x & y) | (~x & z)); }
inline uint4 F(uint4 x, uint4 y, uint4 z)
{
return ((x & y) | (~x & z));
}
inline uint4 G(uint4 x, uint4 y, uint4 z)
{ return ((x & z) | (y & ~z)); }
inline uint4 G(uint4 x, uint4 y, uint4 z)
{
return ((x & z) | (y & ~z));
}
inline uint4 H(uint4 x, uint4 y, uint4 z)
{ return (x ^ y ^ z); }
inline uint4 H(uint4 x, uint4 y, uint4 z)
{
return (x ^ y ^ z);
}
inline uint4 I(uint4 x, uint4 y, uint4 z)
{ return (y ^ (x | ~z)); }
inline uint4 I(uint4 x, uint4 y, uint4 z)
{
return (y ^ (x | ~z));
}
inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += F(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += F(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += G(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += G(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += H(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += H(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{ a += I(b, c, d) + x + ac; a = rotate_left(a, s); a += b; }
inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
{
a += I(b, c, d) + x + ac;
a = rotate_left(a, s);
a += b;
}
// Data
private:
uint4 m_State[4];
uint4 m_Count[2];
uchar m_Buffer[64];
uchar m_Digest[16];
uchar m_Finalized;
uint4 m_State[4];
uint4 m_Count[2];
uchar m_Buffer[64];
uchar m_Digest[16];
uchar m_Finalized;
};
@ -175,9 +207,9 @@ private:
static unsigned char PADDING[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define S11 7
@ -201,33 +233,33 @@ static unsigned char PADDING[64] =
// PrintMD5: Converts a completed md5 digest into a char* string.
char* PrintMD5(uchar md5Digest[16])
{
char chBuffer[256];
char chEach[10];
int nCount;
char chBuffer[256];
char chEach[10];
int nCount;
memset(chBuffer,0,256);
memset(chEach, 0, 10);
memset(chBuffer, 0, 256);
memset(chEach, 0, 10);
for (nCount = 0; nCount < 16; nCount++)
{
sprintf(chEach, "%02x", md5Digest[nCount]);
strncat(chBuffer, chEach, sizeof(chEach));
}
for (nCount = 0; nCount < 16; nCount++)
{
sprintf(chEach, "%02x", md5Digest[nCount]);
strncat(chBuffer, chEach, sizeof(chEach));
}
return strdup(chBuffer);
return strdup(chBuffer);
}
// MD5String: Performs the MD5 algorithm on a char* string, returning
// the results as a char*.
char* MD5String(const char* szString)
{
int nLen = strlen(szString);
md5 alg;
int nLen = strlen(szString);
md5 alg;
alg.Update((unsigned char*)szString, (unsigned int)nLen);
alg.Finalize();
alg.Update((unsigned char*)szString, (unsigned int)nLen);
alg.Finalize();
return PrintMD5(alg.Digest());
return PrintMD5(alg.Digest());
}
@ -235,33 +267,33 @@ char* MD5String(const char* szString)
// returning the results as a char*. Returns NULL if it fails.
char* MD5File(char* szFilename)
{
FILE* file;
md5 alg;
int nLen;
unsigned char chBuffer[1024];
FILE* file;
md5 alg;
int nLen;
unsigned char chBuffer[1024];
try
{
memset(chBuffer, 0, 1024);
try
{
memset(chBuffer, 0, 1024);
if ((file = fopen (szFilename, "rb")) != NULL)
{
while ((nLen = fread (chBuffer, 1, 1024, file)))
alg.Update(chBuffer, nLen);
if ((file = fopen (szFilename, "rb")) != NULL)
{
while ((nLen = fread (chBuffer, 1, 1024, file)))
alg.Update(chBuffer, nLen);
alg.Finalize();
alg.Finalize();
fclose (file);
fclose (file);
return PrintMD5(alg.Digest());
}
}
catch(...)
{
return PrintMD5(alg.Digest());
}
}
catch (...)
{
}
}
return NULL; // failed
return NULL; // failed
}
@ -269,12 +301,12 @@ char* MD5File(char* szFilename)
// Initializes a new context.
void md5::Init()
{
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_Count, 0, 2 * sizeof(uint4));
m_State[0] = 0x67452301;
m_State[1] = 0xefcdab89;
m_State[2] = 0x98badcfe;
m_State[3] = 0x10325476;
m_State[0] = 0x67452301;
m_State[1] = 0xefcdab89;
m_State[2] = 0x98badcfe;
m_State[3] = 0x10325476;
}
// md5::Update
@ -283,35 +315,35 @@ void md5::Init()
// context.
void md5::Update(uchar* chInput, uint4 nInputLen)
{
uint4 i, index, partLen;
uint4 i, index, partLen;
// Compute number of bytes mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3F);
// Compute number of bytes mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3F);
// Update number of bits
if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3))
m_Count[1]++;
// Update number of bits
if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3))
m_Count[1]++;
m_Count[1] += (nInputLen >> 29);
m_Count[1] += (nInputLen >> 29);
partLen = 64 - index;
partLen = 64 - index;
// Transform as many times as possible.
if (nInputLen >= partLen)
{
memcpy( &m_Buffer[index], chInput, partLen );
Transform(m_Buffer);
// Transform as many times as possible.
if (nInputLen >= partLen)
{
memcpy( &m_Buffer[index], chInput, partLen );
Transform(m_Buffer);
for (i = partLen; i + 63 < nInputLen; i += 64)
Transform(&chInput[i]);
for (i = partLen; i + 63 < nInputLen; i += 64)
Transform(&chInput[i]);
index = 0;
}
else
i = 0;
index = 0;
}
else
i = 0;
// Buffer remaining input
memcpy( &m_Buffer[index], &chInput[i], nInputLen-i );
// Buffer remaining input
memcpy( &m_Buffer[index], &chInput[i], nInputLen - i );
}
// md5::Finalize
@ -319,114 +351,114 @@ void md5::Update(uchar* chInput, uint4 nInputLen)
// the message digest and zeroizing the context.
void md5::Finalize()
{
uchar bits[8];
uint4 index, padLen;
uchar bits[8];
uint4 index, padLen;
// Save number of bits
Encode (bits, m_Count, 8);
// Save number of bits
Encode (bits, m_Count, 8);
// Pad out to 56 mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
Update(PADDING, padLen);
// Pad out to 56 mod 64
index = (unsigned int)((m_Count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
Update(PADDING, padLen);
// Append length (before padding)
Update (bits, 8);
// Append length (before padding)
Update (bits, 8);
// Store state in digest
Encode (m_Digest, m_State, 16);
// Store state in digest
Encode (m_Digest, m_State, 16);
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_State, 0, 4 * sizeof(uint4));
memset(m_Buffer,0, 64 * sizeof(uchar));
memset(m_Count, 0, 2 * sizeof(uint4));
memset(m_State, 0, 4 * sizeof(uint4));
memset(m_Buffer, 0, 64 * sizeof(uchar));
}
// md5::Transform
// MD5 basic transformation. Transforms state based on block.
void md5::Transform (uchar* block)
{
uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16];
uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16];
Decode (x, block, 64);
Decode (x, block, 64);
// Round 1
FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
FF (c, d, a, b, x[ 2], S13, 0x242070db);
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
FF (c, d, a, b, x[ 6], S13, 0xa8304613);
FF (b, c, d, a, x[ 7], S14, 0xfd469501);
FF (a, b, c, d, x[ 8], S11, 0x698098d8);
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
FF (c, d, a, b, x[10], S13, 0xffff5bb1);
FF (b, c, d, a, x[11], S14, 0x895cd7be);
FF (a, b, c, d, x[12], S11, 0x6b901122);
FF (d, a, b, c, x[13], S12, 0xfd987193);
FF (c, d, a, b, x[14], S13, 0xa679438e);
FF (b, c, d, a, x[15], S14, 0x49b40821);
// Round 1
FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
FF (c, d, a, b, x[ 2], S13, 0x242070db);
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
FF (c, d, a, b, x[ 6], S13, 0xa8304613);
FF (b, c, d, a, x[ 7], S14, 0xfd469501);
FF (a, b, c, d, x[ 8], S11, 0x698098d8);
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
FF (c, d, a, b, x[10], S13, 0xffff5bb1);
FF (b, c, d, a, x[11], S14, 0x895cd7be);
FF (a, b, c, d, x[12], S11, 0x6b901122);
FF (d, a, b, c, x[13], S12, 0xfd987193);
FF (c, d, a, b, x[14], S13, 0xa679438e);
FF (b, c, d, a, x[15], S14, 0x49b40821);
// Round 2
GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
GG (d, a, b, c, x[ 6], S22, 0xc040b340);
GG (c, d, a, b, x[11], S23, 0x265e5a51);
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
GG (d, a, b, c, x[10], S22, 0x2441453);
GG (c, d, a, b, x[15], S23, 0xd8a1e681);
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
GG (d, a, b, c, x[14], S22, 0xc33707d6);
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
GG (a, b, c, d, x[13], S21, 0xa9e3e905);
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
// Round 2
GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
GG (d, a, b, c, x[ 6], S22, 0xc040b340);
GG (c, d, a, b, x[11], S23, 0x265e5a51);
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
GG (d, a, b, c, x[10], S22, 0x2441453);
GG (c, d, a, b, x[15], S23, 0xd8a1e681);
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
GG (d, a, b, c, x[14], S22, 0xc33707d6);
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
GG (a, b, c, d, x[13], S21, 0xa9e3e905);
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
// Round 3
HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
HH (d, a, b, c, x[ 8], S32, 0x8771f681);
HH (c, d, a, b, x[11], S33, 0x6d9d6122);
HH (b, c, d, a, x[14], S34, 0xfde5380c);
HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
HH (b, c, d, a, x[10], S34, 0xbebfbc70);
HH (a, b, c, d, x[13], S31, 0x289b7ec6);
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
HH (b, c, d, a, x[ 6], S34, 0x4881d05);
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
HH (d, a, b, c, x[12], S32, 0xe6db99e5);
HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
// Round 3
HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
HH (d, a, b, c, x[ 8], S32, 0x8771f681);
HH (c, d, a, b, x[11], S33, 0x6d9d6122);
HH (b, c, d, a, x[14], S34, 0xfde5380c);
HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
HH (b, c, d, a, x[10], S34, 0xbebfbc70);
HH (a, b, c, d, x[13], S31, 0x289b7ec6);
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
HH (b, c, d, a, x[ 6], S34, 0x4881d05);
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
HH (d, a, b, c, x[12], S32, 0xe6db99e5);
HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
// Round 4
II (a, b, c, d, x[ 0], S41, 0xf4292244);
II (d, a, b, c, x[ 7], S42, 0x432aff97);
II (c, d, a, b, x[14], S43, 0xab9423a7);
II (b, c, d, a, x[ 5], S44, 0xfc93a039);
II (a, b, c, d, x[12], S41, 0x655b59c3);
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
II (c, d, a, b, x[10], S43, 0xffeff47d);
II (b, c, d, a, x[ 1], S44, 0x85845dd1);
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
II (c, d, a, b, x[ 6], S43, 0xa3014314);
II (b, c, d, a, x[13], S44, 0x4e0811a1);
II (a, b, c, d, x[ 4], S41, 0xf7537e82);
II (d, a, b, c, x[11], S42, 0xbd3af235);
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
II (b, c, d, a, x[ 9], S44, 0xeb86d391);
// Round 4
II (a, b, c, d, x[ 0], S41, 0xf4292244);
II (d, a, b, c, x[ 7], S42, 0x432aff97);
II (c, d, a, b, x[14], S43, 0xab9423a7);
II (b, c, d, a, x[ 5], S44, 0xfc93a039);
II (a, b, c, d, x[12], S41, 0x655b59c3);
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
II (c, d, a, b, x[10], S43, 0xffeff47d);
II (b, c, d, a, x[ 1], S44, 0x85845dd1);
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
II (c, d, a, b, x[ 6], S43, 0xa3014314);
II (b, c, d, a, x[13], S44, 0x4e0811a1);
II (a, b, c, d, x[ 4], S41, 0xf7537e82);
II (d, a, b, c, x[11], S42, 0xbd3af235);
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
II (b, c, d, a, x[ 9], S44, 0xeb86d391);
m_State[0] += a;
m_State[1] += b;
m_State[2] += c;
m_State[3] += d;
m_State[0] += a;
m_State[1] += b;
m_State[2] += c;
m_State[3] += d;
memset(x, 0, sizeof(x));
memset(x, 0, sizeof(x));
}
// md5::Encode
@ -434,17 +466,17 @@ void md5::Transform (uchar* block)
// a multiple of 4.
void md5::Encode(uchar* dest, uint4* src, uint4 nLength)
{
uint4 i, j;
uint4 i, j;
idbassert(nLength % 4 == 0);
idbassert(nLength % 4 == 0);
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[j] = (uchar)(src[i] & 0xff);
dest[j+1] = (uchar)((src[i] >> 8) & 0xff);
dest[j+2] = (uchar)((src[i] >> 16) & 0xff);
dest[j+3] = (uchar)((src[i] >> 24) & 0xff);
}
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[j] = (uchar)(src[i] & 0xff);
dest[j + 1] = (uchar)((src[i] >> 8) & 0xff);
dest[j + 2] = (uchar)((src[i] >> 16) & 0xff);
dest[j + 3] = (uchar)((src[i] >> 24) & 0xff);
}
}
// md5::Decode
@ -452,38 +484,38 @@ void md5::Encode(uchar* dest, uint4* src, uint4 nLength)
// a multiple of 4.
void md5::Decode(uint4* dest, uchar* src, uint4 nLength)
{
uint4 i, j;
uint4 i, j;
idbassert(nLength % 4 == 0);
idbassert(nLength % 4 == 0);
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[i] = ((uint4)src[j]) | (((uint4)src[j+1])<<8) |
(((uint4)src[j+2])<<16) | (((uint4)src[j+3])<<24);
}
for (i = 0, j = 0; j < nLength; i++, j += 4)
{
dest[i] = ((uint4)src[j]) | (((uint4)src[j + 1]) << 8) |
(((uint4)src[j + 2]) << 16) | (((uint4)src[j + 3]) << 24);
}
}
}
namespace funcexp
namespace funcexp
{
CalpontSystemCatalog::ColType Func_md5::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
string Func_md5::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
return MD5String(arg.c_str());
//return str;
const string& arg = parm[0]->data()->getStrVal(row, isNull);
return MD5String(arg.c_str());
//return str;
}

View File

@ -39,79 +39,90 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_microsecond::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_microsecond::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
uint32_t microSecond = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = 0;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return -1;
}
return microSecond;
int64_t val = 0;
uint32_t microSecond = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = 0;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
microSecond = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
microSecond = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return -1;
}
return microSecond;
}

View File

@ -38,75 +38,89 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_minute::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_minute::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
int64_t val = 0;
return (unsigned)((val >> 26) & 0x3f);
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (unsigned)((val >> 26) & 0x3f);
}

View File

@ -44,77 +44,81 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_mod::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
IDB_Decimal Func_mod::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
IDB_Decimal retValue;
retValue.value = 0;
retValue.scale = 0;
IDB_Decimal retValue;
retValue.value = 0;
retValue.scale = 0;
if ( parm.size() < 2 ) {
isNull = true;
return retValue;
}
if ( parm.size() < 2 )
{
isNull = true;
return retValue;
}
int64_t div = parm[1]->data()->getIntVal(row, isNull);
int64_t div = parm[1]->data()->getIntVal(row, isNull);
if ( div == 0 ) {
isNull = true;
return retValue;
}
if ( div == 0 )
{
isNull = true;
return retValue;
}
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
int lefto = d.value % helpers::power(d.scale);
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
int lefto = d.value % helpers::power(d.scale);
int64_t mod = (value % div) * helpers::power(d.scale) + lefto;
int64_t mod = (value % div) * helpers::power(d.scale) + lefto;
retValue.value = mod;
retValue.scale = d.scale;
retValue.value = mod;
retValue.scale = d.scale;
return retValue;
return retValue;
}
double Func_mod::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
int64_t div = parm[1]->data()->getIntVal(row, isNull);
int64_t div = parm[1]->data()->getIntVal(row, isNull);
if ( div == 0 ) {
isNull = true;
return 0;
}
if ( div == 0 )
{
isNull = true;
return 0;
}
double mod = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
double mod = 0;
mod = value % div;
}
break;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
mod = value % div;
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -131,87 +135,89 @@ double Func_mod::getDoubleVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
{
float value = parm[0]->data()->getFloatVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
mod = value % div;
}
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
mod = fmod(value,div);
break;
}
mod = value % div;
}
break;
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
mod = fmod(value, div);
break;
}
return mod;
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return mod;
}
int64_t Func_mod::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
int64_t div = parm[1]->data()->getIntVal(row, isNull);
int64_t div = parm[1]->data()->getIntVal(row, isNull);
if ( div == 0 ) {
isNull = true;
return 0;
}
if ( div == 0 )
{
isNull = true;
return 0;
}
int64_t mod = 0;
int64_t mod = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
mod = value % div;
}
break;
mod = value % div;
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -228,78 +234,80 @@ int64_t Func_mod::getIntVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
{
float value = parm[0]->data()->getFloatVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
mod = value % div;
}
break;
mod = value % div;
}
break;
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return mod;
return mod;
}
uint64_t Func_mod::getUIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
if ( parm.size() < 2 ) {
isNull = true;
return 0;
}
if ( parm.size() < 2 )
{
isNull = true;
return 0;
}
int64_t div = parm[1]->data()->getIntVal(row, isNull);
int64_t div = parm[1]->data()->getIntVal(row, isNull);
if ( div == 0 ) {
isNull = true;
return 0;
}
if ( div == 0 )
{
isNull = true;
return 0;
}
uint64_t mod = 0;
uint64_t mod = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
int64_t value = parm[0]->data()->getIntVal(row, isNull);
mod = value % div;
}
break;
mod = value % div;
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
@ -316,72 +324,73 @@ uint64_t Func_mod::getUIntVal(Row& row,
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
{
double value = parm[0]->data()->getDoubleVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float value = parm[0]->data()->getFloatVal(row, isNull);
{
float value = parm[0]->data()->getFloatVal(row, isNull);
mod = fmod(value,div);
}
break;
mod = fmod(value, div);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
int64_t value = d.value / helpers::power(d.scale);
mod = value % div;
}
break;
mod = value % div;
}
break;
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "mod: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return mod;
return mod;
}
std::string Func_mod::getStrVal(Row& row,
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
if ( fp.size() < 2 ) {
isNull = true;
return std::string();
}
if ( fp.size() < 2 )
{
isNull = true;
return std::string();
}
switch (fp[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
switch (fp[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
return intToString(getIntVal(row, fp, isNull, op_ct));
break;
return intToString(getIntVal(row, fp, isNull, op_ct));
break;
default:
return doubleToString(getDoubleVal(row, fp, isNull, op_ct));
break;
}
default:
return doubleToString(getDoubleVal(row, fp, isNull, op_ct));
break;
}
}
} // namespace funcexp

View File

@ -38,76 +38,87 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_month::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_month::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 12) & 0xf);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 12) & 0xf);
return -1;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
}
break;
default:
isNull = true;
return -1;
}
return -1;
}

View File

@ -39,121 +39,132 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_monthname::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_monthname::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t month= getIntVal(row, parm, isNull, op_ct);
return helpers::monthFullNames[month];
uint32_t month = getIntVal(row, parm, isNull, op_ct);
return helpers::monthFullNames[month];
}
int32_t Func_monthname::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t val = getIntVal(row, parm, isNull, ct);
return val;
}
uint32_t val = getIntVal(row, parm, isNull, ct);
return val;
}
int64_t Func_monthname::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
uint32_t val = getIntVal(row, parm, isNull, ct);
return val;
uint32_t val = getIntVal(row, parm, isNull, ct);
return val;
}
int64_t Func_monthname::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 12) & 0xf);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 12) & 0xf);
return -1;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 44) & 0xf);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 44) & 0xf);
}
}
break;
default:
isNull = true;
return -1;
}
return -1;
}
double Func_monthname::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
return 0;
}
execplan::IDB_Decimal Func_monthname::getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal d;
d.value = getIntVal(row, fp, isNull, op_ct);
d.scale = 0;
return d;
IDB_Decimal d;
d.value = getIntVal(row, fp, isNull, op_ct);
d.scale = 0;
return d;
}

File diff suppressed because it is too large Load Diff

View File

@ -39,58 +39,61 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_period_add::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_period_add::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t period = parm[0]->data()->getIntVal(row, isNull);
int64_t period = parm[0]->data()->getIntVal(row, isNull);
if ( period < 10000 ) {
//get first 2 digits of year
time_t now;
now = time(NULL);
struct tm tm;
localtime_r(&now, &tm);
char timestamp[10];
strftime (timestamp, 10, "%Y", &tm);
string Syear = timestamp;
Syear = Syear.substr(0,2);
int topyear = atoi(Syear.c_str());
period = (topyear * 10000) + period;
}
if ( period < 10000 )
{
//get first 2 digits of year
time_t now;
now = time(NULL);
struct tm tm;
localtime_r(&now, &tm);
char timestamp[10];
strftime (timestamp, 10, "%Y", &tm);
string Syear = timestamp;
Syear = Syear.substr(0, 2);
int topyear = atoi(Syear.c_str());
period = (topyear * 10000) + period;
}
int64_t year = period / 100;
int64_t year = period / 100;
int64_t month = period - (year * 100);
int64_t month = period - (year * 100);
int64_t months = parm[1]->data()->getIntVal(row, isNull);
int64_t months = parm[1]->data()->getIntVal(row, isNull);
int64_t yearsAdd = months / 12;
int64_t yearsAdd = months / 12;
int64_t monthsAdd = months - (yearsAdd * 12) ;
int64_t monthsAdd = months - (yearsAdd * 12) ;
year = year + yearsAdd;
month = month + monthsAdd;
year = year + yearsAdd;
month = month + monthsAdd;
if ( month > 12 ) {
year++;
month = month - 12;
}
else
{
if ( month < 1 ) {
year--;
month = month + 12;
}
}
if ( month > 12 )
{
year++;
month = month - 12;
}
else
{
if ( month < 1 )
{
year--;
month = month + 12;
}
}
int64_t value = (year * 100) + month;
return value;
int64_t value = (year * 100) + month;
return value;
}

View File

@ -40,117 +40,128 @@ namespace funcexp
inline int64_t convert_period_to_month(int64_t period)
{
int64_t a,b;
if (period == 0)
return 0L;
if ((a=period/100) < YY_PART_YEAR)
a+=2000;
else if (a < 100)
a+=1900;
b=period%100;
return a*12+b-1;
int64_t a, b;
if (period == 0)
return 0L;
if ((a = period / 100) < YY_PART_YEAR)
a += 2000;
else if (a < 100)
a += 1900;
b = period % 100;
return a * 12 + b - 1;
}
CalpontSystemCatalog::ColType Func_period_diff::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_period_diff::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t period1 = 0;
int64_t period1 = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
period1 = parm[0]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
period1 = parm[0]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
period1 = d.value / helpers::power(d.scale);
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period1 = atoi(parm[0]->data()->getStrVal(row, isNull).c_str());
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period1 = (int64_t) parm[0]->data()->getDoubleVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
{
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
period1 = d.value / helpers::power(d.scale);
break;
}
if (isNull)
return 0;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period1 = atoi(parm[0]->data()->getStrVal(row, isNull).c_str());
break;
}
int64_t period2 = 0;
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period1 = (int64_t) parm[0]->data()->getDoubleVal(row, isNull);
break;
}
switch (parm[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
period2 = parm[1]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
default:
{
isNull = true;
}
}
if (isNull)
return 0;
int64_t period2 = 0;
switch (parm[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
period2 = parm[1]->data()->getIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
period2 = d.value / helpers::power(d.scale);
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period2 = atoi(parm[1]->data()->getStrVal(row, isNull).c_str());
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period2 = (int64_t) parm[1]->data()->getDoubleVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
{
IDB_Decimal d = parm[1]->data()->getDecimalVal(row, isNull);
period2 = d.value / helpers::power(d.scale);
break;
}
if (isNull)
return 0;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
period2 = atoi(parm[1]->data()->getStrVal(row, isNull).c_str());
break;
}
return convert_period_to_month(period1) - convert_period_to_month(period2);
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
period2 = (int64_t) parm[1]->data()->getDoubleVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return 0;
return convert_period_to_month(period1) - convert_period_to_month(period2);
}

View File

@ -47,45 +47,46 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_pow::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
double Func_pow::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// null value is indicated by isNull
double base = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
double exponent = parm[1]->data()->getDoubleVal(row, isNull);
// null value is indicated by isNull
double base = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
errno = 0;
double x = pow(base, exponent);
if (!isNull)
{
double exponent = parm[1]->data()->getDoubleVal(row, isNull);
// @bug3490, 4461, rule out domain error, pole error and overflow range error.
if (!isfinite(x))
{
isNull = true;
if (!isNull)
{
errno = 0;
double x = pow(base, exponent);
// @bug3490, 4461, rule out domain error, pole error and overflow range error.
if (!isfinite(x))
{
isNull = true;
Message::Args args;
args.add("pow");
args.add(base);
args.add(exponent);
unsigned errcode = ERR_FUNC_OUT_OF_RANGE_RESULT;
throw IDBExcept(IDBErrorInfo::instance()->errorMsg(errcode, args), errcode);
}
}
return x;
}
}
return x;
}
}
return 0.0;
return 0.0;
}

View File

@ -39,71 +39,84 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_quarter::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_quarter::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
// try to cast to date/datetime
int64_t val = 0, month = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
month = (val >> 12) & 0xf;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
month = (val >> 44) & 0xf;
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 44) & 0xf;
break;
}
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 44) & 0xf;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDate(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 12) & 0xf;
break;
}
else
{
isNull = true;
}
}
default:
isNull = true;
}
return (int64_t)((month+2)/3);
// try to cast to date/datetime
int64_t val = 0, month = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
month = (val >> 12) & 0xf;
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
month = (val >> 44) & 0xf;
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 44) & 0xf;
break;
}
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 44) & 0xf;
break;
}
case CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDate(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
else
month = (val >> 12) & 0xf;
break;
}
else
{
isNull = true;
}
}
default:
isNull = true;
}
return (int64_t)((month + 2) / 3);
}

View File

@ -45,53 +45,59 @@ uint64_t maxValue = 0x3FFFFFFFL;
*/
double Func_rand::getRand()
{
uint64_t fSeed1_save = fSeed1;
fSeed1 = (fSeed1 * 3 + fSeed2) % maxValue;
// prevent the seed to repeat itself. e.g. seed1 = 1073741790; seed2 = 66;
if (fSeed1_save == fSeed1)
fSeed1 += 23;
fSeed2 = (fSeed1 + fSeed2 + 33) % maxValue;
return (((double) fSeed1) / (double)maxValue);
uint64_t fSeed1_save = fSeed1;
fSeed1 = (fSeed1 * 3 + fSeed2) % maxValue;
// prevent the seed to repeat itself. e.g. seed1 = 1073741790; seed2 = 66;
if (fSeed1_save == fSeed1)
fSeed1 += 23;
fSeed2 = (fSeed1 + fSeed2 + 33) % maxValue;
return (((double) fSeed1) / (double)maxValue);
}
CalpontSystemCatalog::ColType Func_rand::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
double Func_rand::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// NOTE: this function needs to use 32bit ints otherwise it will break for negative values
uint32_t seedParm = 0;
// rand with parameter. if the parm is constanct, then a column is attached for fetching
if (parm.size() == 1 || parm.size() == 2)
{
execplan::ConstantColumn *cc = dynamic_cast<execplan::ConstantColumn*>(parm[0].get()->data());
if (!fSeedSet || !cc)
{
/* Copied from item_func.cpp */
seedParm = parm[0]->data()->getIntVal(row, isNull);
fSeed1 = (uint32_t)(seedParm*0x10001L+55555555L);
fSeed2 = (uint32_t)(seedParm*0x10000001L);
fSeedSet = true;
}
}
// rand without parameter. thd->rand are passed in. The 3rd is a simple column for fetching
else
{
idbassert(parm.size() == 3);
if (fSeed1 == 0)
{
fSeed1 = parm[0]->data()->getIntVal(row, isNull);
fSeed2 = parm[1]->data()->getIntVal(row, isNull);
fSeedSet = true;
}
}
return getRand();
uint32_t seedParm = 0;
// rand with parameter. if the parm is constanct, then a column is attached for fetching
if (parm.size() == 1 || parm.size() == 2)
{
execplan::ConstantColumn* cc = dynamic_cast<execplan::ConstantColumn*>(parm[0].get()->data());
if (!fSeedSet || !cc)
{
/* Copied from item_func.cpp */
seedParm = parm[0]->data()->getIntVal(row, isNull);
fSeed1 = (uint32_t)(seedParm * 0x10001L + 55555555L);
fSeed2 = (uint32_t)(seedParm * 0x10000001L);
fSeedSet = true;
}
}
// rand without parameter. thd->rand are passed in. The 3rd is a simple column for fetching
else
{
idbassert(parm.size() == 3);
if (fSeed1 == 0)
{
fSeed1 = parm[0]->data()->getIntVal(row, isNull);
fSeed2 = parm[1]->data()->getIntVal(row, isNull);
fSeedSet = true;
}
}
return getRand();
}

View File

@ -26,7 +26,7 @@
using namespace std;
#ifdef __linux__
#include <regex.h>
#include <regex.h>
#else
#include <boost/regex.hpp>
using namespace boost;
@ -47,146 +47,155 @@ using namespace logging;
namespace
{
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
string expr;
string pattern;
inline bool getBool(rowgroup::Row& row,
funcexp::FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
switch (pm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
expr = pm[0]->data()->getStrVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
expr = dataconvert::DataConvert::dateToString(pm[0]->data()->getDateIntVal(row, isNull));
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
expr = dataconvert::DataConvert::datetimeToString(pm[0]->data()->getDatetimeIntVal(row, isNull));
//strip off micro seconds
expr = expr.substr(0,19);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = pm[0]->data()->getDecimalVal(row, isNull);
char buf[80];
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
expr = buf;
break;
}
string expr;
string pattern;
default:
{
std::ostringstream oss;
oss << "regexp: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
switch (pm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
expr = pm[0]->data()->getStrVal(row, isNull);
break;
}
switch (pm[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
pattern = pm[1]->data()->getStrVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
pattern = dataconvert::DataConvert::dateToString(pm[1]->data()->getDateIntVal(row, isNull));
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
pattern = dataconvert::DataConvert::datetimeToString(pm[1]->data()->getDatetimeIntVal(row, isNull));
//strip off micro seconds
pattern = pattern.substr(0,19);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = pm[1]->data()->getDecimalVal(row, isNull);
char buf[80];
dataconvert::DataConvert::decimalToString( d.value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
pattern = buf;
break;
}
default:
{
std::ostringstream oss;
oss << "regexp: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
case execplan::CalpontSystemCatalog::DATE:
{
expr = dataconvert::DataConvert::dateToString(pm[0]->data()->getDateIntVal(row, isNull));
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
expr = dataconvert::DataConvert::datetimeToString(pm[0]->data()->getDatetimeIntVal(row, isNull));
//strip off micro seconds
expr = expr.substr(0, 19);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = pm[0]->data()->getDecimalVal(row, isNull);
char buf[80];
dataconvert::DataConvert::decimalToString(d.value, d.scale, buf, 80, pm[0]->data()->resultType().colDataType);
expr = buf;
break;
}
default:
{
std::ostringstream oss;
oss << "regexp: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
switch (pm[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
pattern = pm[1]->data()->getStrVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
pattern = dataconvert::DataConvert::dateToString(pm[1]->data()->getDateIntVal(row, isNull));
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
pattern = dataconvert::DataConvert::datetimeToString(pm[1]->data()->getDatetimeIntVal(row, isNull));
//strip off micro seconds
pattern = pattern.substr(0, 19);
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal d = pm[1]->data()->getDecimalVal(row, isNull);
char buf[80];
dataconvert::DataConvert::decimalToString( d.value, d.scale, buf, 80, pm[1]->data()->resultType().colDataType);
pattern = buf;
break;
}
default:
{
std::ostringstream oss;
oss << "regexp: datatype of " << execplan::colDataTypeToString(ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
#ifdef __linux__
regex_t re;
regex_t re;
regcomp(&re, pattern.c_str(), REG_EXTENDED | REG_NOSUB );
regcomp(&re, pattern.c_str(), REG_EXTENDED | REG_NOSUB );
int res = regexec(&re, expr.c_str(), 0, NULL, 0);
regfree(&re);
if (res == 0)
return true;
else
return false;
int res = regexec(&re, expr.c_str(), 0, NULL, 0);
regfree(&re);
if (res == 0)
return true;
else
return false;
#else
regex pat(pattern.c_str());
return regex_search(expr.c_str(), pat);
regex pat(pattern.c_str());
return regex_search(expr.c_str(), pat);
#endif
}
}
}
namespace funcexp
@ -194,15 +203,15 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_regexp::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
bool Func_regexp::getBoolVal(rowgroup::Row& row,
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& pm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getBool(row, pm, isNull, ct) && !isNull;
return getBool(row, pm, isNull, ct) && !isNull;
}

View File

@ -38,11 +38,11 @@ using namespace joblist;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -51,48 +51,51 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_repeat::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
std::string Func_repeat::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
string str = stringValue(fp[0], row, isNull);
string str = stringValue(fp[0], row, isNull);
if (str.empty() || str == "")
return "";
if (str.empty() || str == "")
return "";
int count = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
int count = fp[1]->data()->getIntVal(row, isNull);
if ( count < 1 )
return "";
if (isNull)
return "";
//calculate size of buffer to allocate
if ( count < 1 )
return "";
int size = str.length() * count;
//calculate size of buffer to allocate
//allocate memory
char *result = NULL;
result = (char*) alloca(size * sizeof(char) + 1);
if (result == NULL) {
return "";
}
int size = str.length() * count;
memset( (char*) result, 0, size);
//allocate memory
char* result = NULL;
result = (char*) alloca(size * sizeof(char) + 1);
for ( int i = 0 ; i < count ; i ++ )
{
if(strcat(result, str.c_str()) == NULL)
return "";
}
if (result == NULL)
{
return "";
}
return result;
memset( (char*) result, 0, size);
for ( int i = 0 ; i < count ; i ++ )
{
if (strcat(result, str.c_str()) == NULL)
return "";
}
return result;
}

View File

@ -39,42 +39,46 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_replace::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_replace::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& fromstr = fp[1]->data()->getStrVal(row, isNull);
const string& fromstr = fp[1]->data()->getStrVal(row, isNull);
const string& tostr = fp[2]->data()->getStrVal(row, isNull);
const string& tostr = fp[2]->data()->getStrVal(row, isNull);
string newstr;
unsigned int i = 0;
for(;;)
{
size_t pos = str.find(fromstr, i);
if ( pos != string::npos ) {
//match
if ( pos > i )
newstr = newstr + str.substr(i,pos-i);
string newstr;
unsigned int i = 0;
newstr = newstr + tostr;
i = pos + fromstr.size();
}
else {
newstr = newstr + str.substr(i,1000);
break;
}
}
for (;;)
{
size_t pos = str.find(fromstr, i);
return newstr;
if ( pos != string::npos )
{
//match
if ( pos > i )
newstr = newstr + str.substr(i, pos - i);
newstr = newstr + tostr;
i = pos + fromstr.size();
}
else
{
newstr = newstr + str.substr(i, 1000);
break;
}
}
return newstr;
}

View File

@ -39,9 +39,9 @@ using namespace joblist;
namespace
{
void reverse( char *start, char *end )
void reverse( char* start, char* end )
{
while( start < end )
while ( start < end )
{
char c = *start;
*start++ = *end;
@ -56,31 +56,31 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_reverse::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_reverse::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
string str = stringValue(fp[0], row, isNull);
string str = stringValue(fp[0], row, isNull);
// We used to reverse in the string buffer, but that doesn't
// work for all compilers as some re-use the buffer on simple
// string assignment and implement a ref-count. Reversing in the
// string buffer has the affect of reversing all strings from
// which this one derived.
int len = str.length();
char* pbuf = new char[len+1];
strncpy(pbuf, str.c_str(), len);
pbuf[len] = 0;
char *end = pbuf+len-1;
reverse(pbuf, end);
string rstr = pbuf;
delete [] pbuf;
return rstr;
// We used to reverse in the string buffer, but that doesn't
// work for all compilers as some re-use the buffer on simple
// string assignment and implement a ref-count. Reversing in the
// string buffer has the affect of reversing all strings from
// which this one derived.
int len = str.length();
char* pbuf = new char[len + 1];
strncpy(pbuf, str.c_str(), len);
pbuf[len] = 0;
char* end = pbuf + len - 1;
reverse(pbuf, end);
string rstr = pbuf;
delete [] pbuf;
return rstr;
}

View File

@ -40,43 +40,45 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_right::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_right::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
if (isNull)
return "";
if (isNull)
return "";
if (pos == -1) // pos == 0
return "";
int64_t pos = fp[1]->data()->getIntVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
//wchar_t wcbuf[strwclen];
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (isNull)
return "";
if ( (unsigned) pos >= strwclen )
pos = strwclen;
wstring out = str.substr(strwclen-pos,strwclen);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
//char outbuf[strmblen];
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
}
if (pos == -1) // pos == 0
return "";
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
//wchar_t wcbuf[strwclen];
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if ( (unsigned) pos >= strwclen )
pos = strwclen;
wstring out = str.substr(strwclen - pos, strwclen);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
//char outbuf[strmblen];
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
}
} // namespace funcexp

View File

@ -32,7 +32,7 @@ using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "errorcodes.h"
#include "idberrorinfo.h"
#include "errorids.h"
@ -47,20 +47,22 @@ using namespace funcexp;
inline void decimalPlaceDouble(FunctionParm& fp, int64_t& s, double& p, Row& row, bool& isNull)
{
s = fp[1]->data()->getIntVal(row, isNull);
int64_t d = s;
if (isNull)
return;
s = fp[1]->data()->getIntVal(row, isNull);
int64_t d = s;
int64_t i = (d >= 0) ? d : (-d);
int64_t r = 1;
while (i--)
r *= 10;
if (isNull)
return;
if (d >= 0)
p = (double) r;
else
p = 1.0 / ((double) r);
int64_t i = (d >= 0) ? d : (-d);
int64_t r = 1;
while (i--)
r *= 10;
if (d >= 0)
p = (double) r;
else
p = 1.0 / ((double) r);
}
}
@ -70,31 +72,34 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_round::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
if (resultType.colDataType == execplan::CalpontSystemCatalog::DECIMAL)
{
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (resultType.scale > ct.scale)
(resultType).scale = ct.scale;
break;
}
default:
{
break;
}
}
}
if (resultType.colDataType == execplan::CalpontSystemCatalog::DECIMAL)
{
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
return fp[0]->data()->resultType();
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (resultType.scale > ct.scale)
(resultType).scale = ct.scale;
break;
}
default:
{
break;
}
}
}
return fp[0]->data()->resultType();
}
@ -102,389 +107,426 @@ CalpontSystemCatalog::ColType Func_round::operationType(FunctionParm& fp, Calpon
//
int64_t Func_round::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
if (x.scale > 0)
{
while (x.scale-- > 0)
x.value /= 10;
}
else
{
while (x.scale++ < 0)
x.value *= 10;
}
if (x.scale > 0)
{
while (x.scale-- > 0)
x.value /= 10;
}
else
{
while (x.scale++ < 0)
x.value *= 10;
}
return x.value;
return x.value;
}
uint64_t Func_round::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return parm[0]->data()->getUintVal(row, isNull);
return parm[0]->data()->getUintVal(row, isNull);
}
double Func_round::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
if (execplan::CalpontSystemCatalog::DOUBLE == op_ct.colDataType ||
execplan::CalpontSystemCatalog::FLOAT == op_ct.colDataType)
{
int64_t d = 0;
double p = 1;
if (parm.size() > 1) // round(X, D)
decimalPlaceDouble(parm, d, p, row, isNull);
if (execplan::CalpontSystemCatalog::DOUBLE == op_ct.colDataType ||
execplan::CalpontSystemCatalog::FLOAT == op_ct.colDataType)
{
int64_t d = 0;
double p = 1;
if (isNull)
return 0.0;
if (parm.size() > 1) // round(X, D)
decimalPlaceDouble(parm, d, p, row, isNull);
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
x *= p;
if (x >= 0)
x = floor(x + 0.5);
else
x = ceil(x - 0.5);
if (isNull)
return 0.0;
if (p != 0.0)
x /= p;
else
x = 0.0;
}
double x = parm[0]->data()->getDoubleVal(row, isNull);
return x;
}
if (isUnsigned(op_ct.colDataType))
{
return getUintVal(row, parm, isNull, op_ct);
}
if (!isNull)
{
x *= p;
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
if (isNull)
return 0.0;
if (x >= 0)
x = floor(x + 0.5);
else
x = ceil(x - 0.5);
double d = x.value;
if (x.scale > 0)
{
while (x.scale-- > 0)
d /= 10.0;
}
else
{
while (x.scale++ < 0)
d *= 10.0;
}
if (p != 0.0)
x /= p;
else
x = 0.0;
}
return d;
return x;
}
if (isUnsigned(op_ct.colDataType))
{
return getUintVal(row, parm, isNull, op_ct);
}
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
if (isNull)
return 0.0;
double d = x.value;
if (x.scale > 0)
{
while (x.scale-- > 0)
d /= 10.0;
}
else
{
while (x.scale++ < 0)
d *= 10.0;
}
return d;
}
IDB_Decimal Func_round::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal decimal;
IDB_Decimal decimal;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
int64_t d = 0;
//@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile.
volatile int64_t p = 1;
decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (!isNull && parm.size() > 1) // round(X, D)
{
int64_t nvp = p;
d = parm[1]->data()->getIntVal(row, isNull);
if (!isNull)
helpers::decimalPlaceDec(d, nvp, decimal.scale);
p = nvp;
}
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
int64_t d = 0;
//@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile.
volatile int64_t p = 1;
decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
if (!isNull && parm.size() > 1) // round(X, D)
{
int64_t nvp = p;
d = parm[1]->data()->getIntVal(row, isNull);
int64_t x = decimal.value;
if (d > 0)
{
x = x * p;
}
else if (d < 0)
{
int64_t h = p / 2; // 0.5
if ((x >= h) || (x <= -h))
{
if (x >= 0)
x += h;
else
x -= h;
if (!isNull)
helpers::decimalPlaceDec(d, nvp, decimal.scale);
if (p != 0)
x = x / p;
else
x = 0;
}
else
{
x = 0;
}
}
p = nvp;
}
// negative scale is not supported by CNX yet, set d to 0.
if (decimal.scale < 0)
{
do
x *= 10;
while (++decimal.scale < 0);
}
decimal.value = x;
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t x = parm[0]->data()->getUintVal(row, isNull);
if (x > (uint64_t)helpers::maxNumber_c[18])
{
x = helpers::maxNumber_c[18];
}
if (isNull)
break;
decimal.value = x;
decimal.scale = 0;
}
break;
int64_t x = decimal.value;
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t s = 0;
double p = 1;
if (parm.size() > 1) // round(X, D)
decimalPlaceDouble(parm, s, p, row, isNull);
if (d > 0)
{
x = x * p;
}
else if (d < 0)
{
int64_t h = p / 2; // 0.5
if (isNull)
break;
if ((x >= h) || (x <= -h))
{
if (x >= 0)
x += h;
else
x -= h;
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
x *= p;
if (x >= 0)
x = floor(x + 0.5);
else
x = ceil(x - 0.5);
if (p != 0)
x = x / p;
else
x = 0;
}
else
{
x = 0;
}
}
decimal.value = (int64_t) x;
decimal.scale = s;
}
}
break;
// negative scale is not supported by CNX yet, set d to 0.
if (decimal.scale < 0)
{
do
x *= 10;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t s = 0;
while (++decimal.scale < 0);
}
string value = dataconvert::DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
decimal.value = x;
}
break;
if (parm.size() > 1) { // round(X, D)
s = parm[1]->data()->getIntVal(row, isNull);
if ( s > 11 )
s = 0;
if ( s > 0 ) {
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
else
{
if ( -s >= (int32_t) value.size() )
value = "0";
else
{
//check to see if last digit needs to be rounded up
int firstcutdigit = atoi(value.substr(value.size() + s,1).c_str());
value = value.substr(0,value.size() + s);
int lastdigit = atoi(value.substr(value.size()-1,1).c_str());
if ( firstcutdigit > 5 ) {
lastdigit++;
string lastStr = intToString(lastdigit);
value = value.substr(0, value.size()-1) + lastStr;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t x = parm[0]->data()->getUintVal(row, isNull);
s = -s;
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
if (x > (uint64_t)helpers::maxNumber_c[18])
{
x = helpers::maxNumber_c[18];
}
s = 0;
}
}
decimal.value = x;
decimal.scale = 0;
}
break;
int64_t x = atoll(value.c_str());
if (!isNull)
{
decimal.value = x;
decimal.scale = s;
}
}
break;
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t s = 0;
double p = 1;
case execplan::CalpontSystemCatalog::DATETIME:
{
int32_t s = 0;
if (parm.size() > 1) // round(X, D)
decimalPlaceDouble(parm, s, p, row, isNull);
string value = dataconvert::DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
if (isNull)
break;
//strip off micro seconds
value = value.substr(0,14);
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (parm.size() > 1) { // round(X, D)
s = parm[1]->data()->getIntVal(row, isNull);
if ( s > 5 )
s = 0;
if ( s > 0 ) {
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
else
{
if ( -s >= (int32_t) value.size() )
value = "0";
else
{
//check to see if last digit needs to be rounded up
int firstcutdigit = atoi(value.substr(value.size() + s,1).c_str());
value = value.substr(0,value.size() + s);
int lastdigit = atoi(value.substr(value.size()-1,1).c_str());
if ( firstcutdigit > 5 ) {
lastdigit++;
string lastStr = intToString(lastdigit);
value = value.substr(0, value.size()-1) + lastStr;
}
if (!isNull)
{
x *= p;
s = -s;
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
if (x >= 0)
x = floor(x + 0.5);
else
x = ceil(x - 0.5);
s = 0;
}
}
decimal.value = (int64_t) x;
decimal.scale = s;
}
}
break;
int64_t x = atoll(value.c_str());
if (!isNull)
{
decimal.value = x;
decimal.scale = s;
}
}
break;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t s = 0;
string value = dataconvert::DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (parm.size() > 1) // round(X, D)
{
s = parm[1]->data()->getIntVal(row, isNull);
if ( s > 11 )
s = 0;
if ( s > 0 )
{
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
else
{
if ( -s >= (int32_t) value.size() )
value = "0";
else
{
//check to see if last digit needs to be rounded up
int firstcutdigit = atoi(value.substr(value.size() + s, 1).c_str());
value = value.substr(0, value.size() + s);
int lastdigit = atoi(value.substr(value.size() - 1, 1).c_str());
if ( firstcutdigit > 5 )
{
lastdigit++;
string lastStr = intToString(lastdigit);
value = value.substr(0, value.size() - 1) + lastStr;
}
s = -s;
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
s = 0;
}
}
int64_t x = atoll(value.c_str());
if (!isNull)
{
decimal.value = x;
decimal.scale = s;
}
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int32_t s = 0;
string value = dataconvert::DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
//strip off micro seconds
value = value.substr(0, 14);
if (parm.size() > 1) // round(X, D)
{
s = parm[1]->data()->getIntVal(row, isNull);
if ( s > 5 )
s = 0;
if ( s > 0 )
{
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
else
{
if ( -s >= (int32_t) value.size() )
value = "0";
else
{
//check to see if last digit needs to be rounded up
int firstcutdigit = atoi(value.substr(value.size() + s, 1).c_str());
value = value.substr(0, value.size() + s);
int lastdigit = atoi(value.substr(value.size() - 1, 1).c_str());
if ( firstcutdigit > 5 )
{
lastdigit++;
string lastStr = intToString(lastdigit);
value = value.substr(0, value.size() - 1) + lastStr;
}
s = -s;
for ( int i = 0 ; i < s ; i++)
{
value = value + "0";
}
}
s = 0;
}
}
int64_t x = atoll(value.c_str());
if (!isNull)
{
decimal.value = x;
decimal.scale = s;
}
}
break;
default:
{
std::ostringstream oss;
oss << "round: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "round: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return decimal;
return decimal;
}
string Func_round::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
int64_t e = (x.scale < 0) ? (-x.scale) : x.scale;
int64_t p = 1;
while (e-- > 0)
p *= 10;
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
int64_t e = (x.scale < 0) ? (-x.scale) : x.scale;
int64_t p = 1;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
if (x.scale != 0)
{
if (x.scale > 0 && x.scale < 19)
{
x.value /= IDB_pow[x.scale];
}
else if (x.scale < 0 && x.scale > -19)
{
x.value *= IDB_pow[-x.scale]; // may overflow
}
else if (x.scale > 0)
{
x.value = 0;
}
else // overflow may need throw exception
{
int64_t e = -x.scale % 18;
x.value *= IDB_pow[e];
e = -x.scale - e;
while (e > 0)
{
x.value *= IDB_pow[18];
e -= 18;
}
}
while (e-- > 0)
p *= 10;
x.scale = 0;
}
break;
default:
break;
}
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
if (x.scale != 0)
{
if (x.scale > 0 && x.scale < 19)
{
x.value /= IDB_pow[x.scale];
}
else if (x.scale < 0 && x.scale > -19)
{
x.value *= IDB_pow[-x.scale]; // may overflow
}
else if (x.scale > 0)
{
x.value = 0;
}
else // overflow may need throw exception
{
int64_t e = -x.scale % 18;
x.value *= IDB_pow[e];
e = -x.scale - e;
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
while (e > 0)
{
x.value *= IDB_pow[18];
e -= 18;
}
}
x.scale = 0;
}
break;
default:
break;
}
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
}

153
utils/funcexp/func_rpad.cpp Executable file → Normal file
View File

@ -41,21 +41,21 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_rpad::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_rpad::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
unsigned i;
// The number of characters (not bytes) in our input str.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in our pad str.
size_t padwclen;
@ -64,59 +64,63 @@ std::string Func_rpad::getStrVal(rowgroup::Row& row,
// The result length in number of characters
size_t len = 0;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
switch (fp[1]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
len = fp[1]->data()->getUintVal(row, isNull);
}
break;
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min()+2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
double value = fp[1]->data()->getDoubleVal(row, isNull);
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (value > 0)
value += 0.5;
else if (value < 0)
value -= 0.5;
else if (value < 0)
value -= 0.5;
if (len < 1)
int64_t ret = (int64_t) value;
if (value > (double) numeric_limits<int64_t>::max())
ret = numeric_limits<int64_t>::max();
else if (value < (double) (numeric_limits<int64_t>::min() + 2))
ret = numeric_limits<int64_t>::min() + 2; // IDB min for bigint
len = ret;
}
break;
default:
{
len = fp[1]->data()->getIntVal(row, isNull);
}
}
if (len < 1)
return "";
// The pad characters.
@ -125,24 +129,28 @@ std::string Func_rpad::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than:
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
int alen = len;
if(strwclen > len)
alen = strwclen;
int bufsize = (alen+1) * sizeof(wchar_t);
int alen = len;
if (strwclen > len)
alen = strwclen;
int bufsize = (alen + 1) * sizeof(wchar_t);
// Convert to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
unsigned int strSize = strwclen; // The number of significant characters
const wchar_t* pWChar = wcbuf;
for (i = 0; *pWChar != '\0' && i < strwclen; ++pWChar, ++i)
{
}
strSize = i;
// If the incoming str is exactly the len of the result str,
@ -154,46 +162,49 @@ std::string Func_rpad::getStrVal(rowgroup::Row& row,
// If the incoming str is too big for the result str
// truncate the widechar buffer and return as a string
if (strSize > len)
if (strSize > len)
{
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
// Trim the excess length of the buffer
wstring trimmed = wstring(wcbuf, len);
return utf8::wstring_to_utf8(trimmed.c_str());
}
// This is the case where there's room to pad.
// Convert the pad string to wide
padwclen = pad.length(); // A guess to start.
int padbufsize = (padwclen+1) * sizeof(wchar_t);
int padbufsize = (padwclen + 1) * sizeof(wchar_t);
wchar_t* wcpad = (wchar_t*)alloca(padbufsize);
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen+1);
size_t padlen = utf8::idb_mbstowcs(wcpad, pad.c_str(), padwclen + 1);
// How many chars do we need?
unsigned int padspace = len - strSize;
// Fill in the back of the buffer
wchar_t* firstpadchar = wcbuf + strSize;
for (wchar_t* pch = wcbuf; pch < wcbuf + len && padlen > 0;)
for (wchar_t* pch = wcbuf; pch < wcbuf + len && padlen > 0;)
{
// Truncate the number of fill chars if running out of space
if (padlen > padspace)
{
padlen = padspace;
}
// Move the fill chars to buffer
for (wchar_t* padchar = wcpad; padchar < wcpad + padlen; ++padchar)
{
*firstpadchar++ = *padchar;
}
padspace -= padlen;
pch += padlen;
}
wstring padded = wstring(wcbuf, len);
wstring padded = wstring(wcbuf, len);
// Bug 5110 : strings were getting truncated since enough bytes not allocated.
return utf8::wstring_to_utf8(padded.c_str());
// Bug 5110 : strings were getting truncated since enough bytes not allocated.
return utf8::wstring_to_utf8(padded.c_str());
}

View File

@ -40,20 +40,20 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_rtrim::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_rtrim::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// The number of characters (not bytes) in our input tstr.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in ourtrim tstr.
size_t trimwclen;
@ -65,65 +65,71 @@ std::string Func_rtrim::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
if (tstr.empty() || tstr.length() == 0)
return tstr;
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than:
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
int bufsize = (strwclen+1) * sizeof(wchar_t);
int bufsize = (strwclen + 1) * sizeof(wchar_t);
// Convert the string to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
// utf8::idb_mbstowcs could return -1 if there is bad chars
if(strwclen == static_cast<size_t>(-1))
strwclen = 0;
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
// utf8::idb_mbstowcs could return -1 if there is bad chars
if (strwclen == static_cast<size_t>(-1))
strwclen = 0;
// Convert the trim string to wide
trimwclen = trim.length(); // A guess to start.
int trimbufsize = (trimwclen+1) * sizeof(wchar_t);
int trimbufsize = (trimwclen + 1) * sizeof(wchar_t);
wchar_t* wctrim = (wchar_t*)alloca(trimbufsize);
size_t trimlen = utf8::idb_mbstowcs(wctrim,trim.c_str(), trimwclen+1);
// idb_mbstowcs could return -1 if there is bad chars
if(trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimlen = utf8::idb_mbstowcs(wctrim, trim.c_str(), trimwclen + 1);
// idb_mbstowcs could return -1 if there is bad chars
if (trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimCmpLen = trimlen * sizeof(wchar_t);
const wchar_t* oPtr = wcbuf; // To remember the start of the string
const wchar_t* aPtr = oPtr;
const wchar_t* aEnd = wcbuf+strwclen-1;
const wchar_t* aEnd = wcbuf + strwclen - 1;
size_t trimCnt = 0;
if(trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr=wctrim[0];
while (aEnd >= aPtr && *aEnd == chr)
{
--aEnd;
++trimCnt;
}
}
else
{
aEnd-=(trimlen-1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aEnd, wctrim, trimCmpLen))
{
aEnd-=trimCmpLen;
trimCnt+=trimlen;
}
}
}
if (trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr = wctrim[0];
size_t aLen = strwclen-trimCnt;
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
while (aEnd >= aPtr && *aEnd == chr)
{
--aEnd;
++trimCnt;
}
}
else
{
aEnd -= (trimlen - 1); // So we don't compare past the end of the string.
while (aPtr <= aEnd && !memcmp(aEnd, wctrim, trimCmpLen))
{
aEnd -= trimCmpLen;
trimCnt += trimlen;
}
}
}
size_t aLen = strwclen - trimCnt;
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
} // namespace funcexp

View File

@ -44,228 +44,244 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_sec_to_time::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return resultType;
return resultType;
}
string Func_sec_to_time::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = 0;
CalpontSystemCatalog::ColType curCt = parm[0]->data()->resultType();
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
int64_t val = 0;
CalpontSystemCatalog::ColType curCt = parm[0]->data()->resultType();
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
val = parm[0]->data()->getIntVal(row, isNull);
}
break;
{
val = parm[0]->data()->getIntVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::DOUBLE:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
if (x < string::npos)
{
string tmp = valStr.substr(x+1,1);
char * ptr = &tmp[0];
int i = atoi(ptr);
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -=1;
}
}
}
break;
case execplan::CalpontSystemCatalog::DOUBLE:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
case execplan::CalpontSystemCatalog::FLOAT:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
if (x < string::npos)
{
string tmp = valStr.substr(x+1,1);
char * ptr = &tmp[0];
int i = atoi(ptr);
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -=1;
}
}
}
break;
if (x < string::npos)
{
string tmp = valStr.substr(x + 1, 1);
char* ptr = &tmp[0];
int i = atoi(ptr);
case execplan::CalpontSystemCatalog::DECIMAL:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
if (x < string::npos)
{
string tmp = valStr.substr(x+1,1);
char * ptr = &tmp[0];
int i = atoi(ptr);
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -=1;
}
}
}
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = parm[0]->data()->getIntVal(row, isNull);
break;
}
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -= 1;
}
}
}
break;
case execplan::CalpontSystemCatalog::FLOAT:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
if (x < string::npos)
{
string tmp = valStr.substr(x + 1, 1);
char* ptr = &tmp[0];
int i = atoi(ptr);
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -= 1;
}
}
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
{
const string& valStr = parm[0]->data()->getStrVal(row, isNull);
val = parm[0]->data()->getIntVal(row, isNull);
size_t x = valStr.find(".");
if (x < string::npos)
{
string tmp = valStr.substr(x + 1, 1);
char* ptr = &tmp[0];
int i = atoi(ptr);
if (i >= 5)
{
if (val > 0)
val += 1;
else
val -= 1;
}
}
}
break;
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = parm[0]->data()->getIntVal(row, isNull);
break;
}
default:
{
std::ostringstream oss;
oss << "sec_to_time: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
int64_t posVal = llabs(val);
if (val > 3020399)
return ("838:59:59");
if (val < -3020399)
return ("-838:59:59");
//Format the time
uint32_t hour = 0;
uint32_t minute = 0;
uint32_t second = 0;
hour = posVal / 3600;
minute = (posVal - (hour * 3600)) / 60;
second = posVal - (hour * 3600) - (minute * 60);
default:
{
std::ostringstream oss;
oss << "sec_to_time: datatype of " << execplan::colDataTypeToString(parm[0]->data()->resultType().colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
int64_t posVal = llabs(val);
if (val >3020399)
return ("838:59:59");
if (val < -3020399)
return ("-838:59:59");
//Format the time
uint32_t hour = 0;
uint32_t minute = 0;
uint32_t second = 0;
hour = posVal / 3600;
minute = (posVal - (hour * 3600)) / 60;
second = posVal - (hour * 3600) - (minute * 60);
const char* minus = "-";
const char* nominus = "";
const char* signstr = (val < 0) ? minus : nominus;
char buf[32]; // actual string either 9 or 10 characters
const char* signstr = (val < 0) ? minus : nominus;
char buf[32]; // actual string either 9 or 10 characters
snprintf(buf, 32, "%s%02d:%02d:%02d", signstr, hour, minute, second);
return buf;
return buf;
}
int64_t Func_sec_to_time::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
if (val > 3020399)
val = 8385959;
else if (val < -3020399)
val = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x,1);
x = time.find(":");
}
char *ep = NULL;
const char *str = time.c_str();
errno = 0;
val= strtoll(str, &ep, 10);
}
return val;
int64_t val = parm[0]->data()->getIntVal(row, isNull);
if (val > 3020399)
val = 8385959;
else if (val < -3020399)
val = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x, 1);
x = time.find(":");
}
char* ep = NULL;
const char* str = time.c_str();
errno = 0;
val = strtoll(str, &ep, 10);
}
return val;
}
double Func_sec_to_time::getDoubleVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
double val = parm[0]->data()->getDoubleVal(row, isNull);
if (val > 3020399)
val = 8385959;
else if (val < -3020399)
val = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x, 1);
x = time.find(":");
}
char *ep = NULL;
const char *str = time.c_str();
errno = 0;
val= (double)strtoll(str, &ep, 10);
}
return val;
}
double val = parm[0]->data()->getDoubleVal(row, isNull);
if (val > 3020399)
val = 8385959;
else if (val < -3020399)
val = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x, 1);
x = time.find(":");
}
char* ep = NULL;
const char* str = time.c_str();
errno = 0;
val = (double)strtoll(str, &ep, 10);
}
return val;
}
execplan::IDB_Decimal Func_sec_to_time::getDecimalVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal d;
int64_t val = parm[0]->data()->getIntVal(row, isNull);
if (val > 3020399)
d.value = 8385959;
else if (val < -3020399)
d.value = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x,1);
x = time.find(":");
}
char *ep = NULL;
const char *str = time.c_str();
errno = 0;
d.value= strtoll(str, &ep, 10);
}
d.scale = 0;
return d;
IDB_Decimal d;
int64_t val = parm[0]->data()->getIntVal(row, isNull);
if (val > 3020399)
d.value = 8385959;
else if (val < -3020399)
d.value = 4286581337LL;
else
{
string time = getStrVal(row, parm, isNull, op_ct);
size_t x = time.find(":");
while (x < string::npos)
{
time.erase(x, 1);
x = time.find(":");
}
char* ep = NULL;
const char* str = time.c_str();
errno = 0;
d.value = strtoll(str, &ep, 10);
}
d.scale = 0;
return d;
}

View File

@ -38,75 +38,90 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_second::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_second::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
break;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 20) & 0x3f);
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
break;
}
}
if (isNull)
return -1;
if ( val < 1000000000 )
return 0;
return (uint32_t)((val >> 20) & 0x3f);
}

View File

@ -69,7 +69,7 @@ namespace funcexp
*
*/
/*
/*
* SHA1
*
* Description:
@ -89,7 +89,7 @@ SHA1::SHA1()
Reset();
}
/*
/*
* ~SHA1
*
* Description:
@ -106,10 +106,10 @@ SHA1::SHA1()
*/
SHA1::~SHA1()
{
// The destructor does nothing
// The destructor does nothing
}
/*
/*
* Reset
*
* Description:
@ -127,21 +127,21 @@ SHA1::~SHA1()
*/
void SHA1::Reset()
{
Length_Low = 0;
Length_High = 0;
Message_Block_Index = 0;
H[0] = 0x67452301;
H[1] = 0xEFCDAB89;
H[2] = 0x98BADCFE;
H[3] = 0x10325476;
H[4] = 0xC3D2E1F0;
Computed = false;
Corrupted = false;
Length_Low = 0;
Length_High = 0;
Message_Block_Index = 0;
H[0] = 0x67452301;
H[1] = 0xEFCDAB89;
H[2] = 0x98BADCFE;
H[3] = 0x10325476;
H[4] = 0xC3D2E1F0;
Computed = false;
Corrupted = false;
}
/*
/*
* Result
*
* Description:
@ -159,30 +159,30 @@ void SHA1::Reset()
* Comments:
*
*/
bool SHA1::Result(unsigned *message_digest_array)
bool SHA1::Result(unsigned* message_digest_array)
{
int i; // Counter
if (Corrupted)
{
return false;
}
if (!Computed)
{
PadMessage();
Computed = true;
}
for(i = 0; i < 5; i++)
{
message_digest_array[i] = H[i];
}
return true;
int i; // Counter
if (Corrupted)
{
return false;
}
if (!Computed)
{
PadMessage();
Computed = true;
}
for (i = 0; i < 5; i++)
{
message_digest_array[i] = H[i];
}
return true;
}
/*
/*
* Input
*
* Description:
@ -200,46 +200,48 @@ bool SHA1::Result(unsigned *message_digest_array)
* Comments:
*
*/
void SHA1::Input( const unsigned char *message_array,
void SHA1::Input( const unsigned char* message_array,
unsigned length)
{
if (!length)
{
return;
}
if (Computed || Corrupted)
{
Corrupted = true;
return;
}
while(length-- && !Corrupted)
{
Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
Length_Low += 8;
Length_Low &= 0xFFFFFFFF; // Force it to 32 bits
if (Length_Low == 0)
{
Length_High++;
Length_High &= 0xFFFFFFFF; // Force it to 32 bits
if (Length_High == 0)
{
Corrupted = true; // Message is too long
}
}
if (Message_Block_Index == 64)
{
ProcessMessageBlock();
}
message_array++;
}
if (!length)
{
return;
}
if (Computed || Corrupted)
{
Corrupted = true;
return;
}
while (length-- && !Corrupted)
{
Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
Length_Low += 8;
Length_Low &= 0xFFFFFFFF; // Force it to 32 bits
if (Length_Low == 0)
{
Length_High++;
Length_High &= 0xFFFFFFFF; // Force it to 32 bits
if (Length_High == 0)
{
Corrupted = true; // Message is too long
}
}
if (Message_Block_Index == 64)
{
ProcessMessageBlock();
}
message_array++;
}
}
/*
/*
* Input
*
* Description:
@ -259,13 +261,13 @@ void SHA1::Input( const unsigned char *message_array,
* Comments:
*
*/
void SHA1::Input( const char *message_array,
void SHA1::Input( const char* message_array,
unsigned length)
{
Input((unsigned char *) message_array, length);
Input((unsigned char*) message_array, length);
}
/*
/*
* Input
*
* Description:
@ -283,10 +285,10 @@ void SHA1::Input( const char *message_array,
*/
void SHA1::Input(unsigned char message_element)
{
Input(&message_element, 1);
Input(&message_element, 1);
}
/*
/*
* Input
*
* Description:
@ -304,10 +306,10 @@ void SHA1::Input(unsigned char message_element)
*/
void SHA1::Input(char message_element)
{
Input((unsigned char *) &message_element, 1);
Input((unsigned char*) &message_element, 1);
}
/*
/*
* operator<<
*
* Description:
@ -325,51 +327,51 @@ void SHA1::Input(char message_element)
* Each character is assumed to hold 8 bits of information.
*
*/
SHA1& SHA1::operator<<(const char *message_array)
SHA1& SHA1::operator<<(const char* message_array)
{
const char *p = message_array;
const char* p = message_array;
while(*p)
{
Input(*p);
p++;
}
return *this;
}
/*
* operator<<
*
* Description:
* This operator makes it convenient to provide character strings to
* the SHA1 object for processing.
*
* Parameters:
* message_array: [in]
* The character array to take as input.
*
* Returns:
* A reference to the SHA1 object.
*
* Comments:
* Each character is assumed to hold 8 bits of information.
*
*/
SHA1& SHA1::operator<<(const unsigned char *message_array)
{
const unsigned char *p = message_array;
while(*p)
{
Input(*p);
p++;
}
while (*p)
{
Input(*p);
p++;
}
return *this;
}
/*
/*
* operator<<
*
* Description:
* This operator makes it convenient to provide character strings to
* the SHA1 object for processing.
*
* Parameters:
* message_array: [in]
* The character array to take as input.
*
* Returns:
* A reference to the SHA1 object.
*
* Comments:
* Each character is assumed to hold 8 bits of information.
*
*/
SHA1& SHA1::operator<<(const unsigned char* message_array)
{
const unsigned char* p = message_array;
while (*p)
{
Input(*p);
p++;
}
return *this;
}
/*
* operator<<
*
* Description:
@ -388,12 +390,12 @@ SHA1& SHA1::operator<<(const unsigned char *message_array)
*/
SHA1& SHA1::operator<<(const char message_element)
{
Input((unsigned char *) &message_element, 1);
Input((unsigned char*) &message_element, 1);
return *this;
return *this;
}
/*
/*
* operator<<
*
* Description:
@ -412,12 +414,12 @@ SHA1& SHA1::operator<<(const char message_element)
*/
SHA1& SHA1::operator<<(const unsigned char message_element)
{
Input(&message_element, 1);
Input(&message_element, 1);
return *this;
return *this;
}
/*
/*
* ProcessMessageBlock
*
* Description:
@ -438,94 +440,95 @@ SHA1& SHA1::operator<<(const unsigned char message_element)
*/
void SHA1::ProcessMessageBlock()
{
const unsigned K[] = { // Constants defined for SHA-1
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t; // Loop counter
unsigned temp; // Temporary word value
unsigned W[80]; // Word sequence
unsigned A, B, C, D, E; // Word buffers
const unsigned K[] = // Constants defined for SHA-1
{
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t; // Loop counter
unsigned temp; // Temporary word value
unsigned W[80]; // Word sequence
unsigned A, B, C, D, E; // Word buffers
/*
* Initialize the first 16 words in the array W
*/
for(t = 0; t < 16; t++)
{
W[t] = ((unsigned) Message_Block[t * 4]) << 24;
W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16;
W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8;
W[t] |= ((unsigned) Message_Block[t * 4 + 3]);
}
/*
* Initialize the first 16 words in the array W
*/
for (t = 0; t < 16; t++)
{
W[t] = ((unsigned) Message_Block[t * 4]) << 24;
W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16;
W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8;
W[t] |= ((unsigned) Message_Block[t * 4 + 3]);
}
for(t = 16; t < 80; t++)
{
W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}
for (t = 16; t < 80; t++)
{
W[t] = CircularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
}
A = H[0];
B = H[1];
C = H[2];
D = H[3];
E = H[4];
A = H[0];
B = H[1];
C = H[2];
D = H[3];
E = H[4];
for(t = 0; t < 20; t++)
{
temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (t = 0; t < 20; t++)
{
temp = CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30, B);
B = A;
A = temp;
}
for(t = 20; t < 40; t++)
{
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (t = 20; t < 40; t++)
{
temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30, B);
B = A;
A = temp;
}
for(t = 40; t < 60; t++)
{
temp = CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (t = 40; t < 60; t++)
{
temp = CircularShift(5, A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30, B);
B = A;
A = temp;
}
for(t = 60; t < 80; t++)
{
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (t = 60; t < 80; t++)
{
temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3];
temp &= 0xFFFFFFFF;
E = D;
D = C;
C = CircularShift(30, B);
B = A;
A = temp;
}
H[0] = (H[0] + A) & 0xFFFFFFFF;
H[1] = (H[1] + B) & 0xFFFFFFFF;
H[2] = (H[2] + C) & 0xFFFFFFFF;
H[3] = (H[3] + D) & 0xFFFFFFFF;
H[4] = (H[4] + E) & 0xFFFFFFFF;
H[0] = (H[0] + A) & 0xFFFFFFFF;
H[1] = (H[1] + B) & 0xFFFFFFFF;
H[2] = (H[2] + C) & 0xFFFFFFFF;
H[3] = (H[3] + D) & 0xFFFFFFFF;
H[4] = (H[4] + E) & 0xFFFFFFFF;
Message_Block_Index = 0;
Message_Block_Index = 0;
}
/*
/*
* PadMessage
*
* Description:
@ -548,53 +551,55 @@ void SHA1::ProcessMessageBlock()
*/
void SHA1::PadMessage()
{
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second block.
*/
if (Message_Block_Index > 55)
{
Message_Block[Message_Block_Index++] = 0x80;
while(Message_Block_Index < 64)
{
Message_Block[Message_Block_Index++] = 0;
}
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second block.
*/
if (Message_Block_Index > 55)
{
Message_Block[Message_Block_Index++] = 0x80;
ProcessMessageBlock();
while (Message_Block_Index < 64)
{
Message_Block[Message_Block_Index++] = 0;
}
while(Message_Block_Index < 56)
{
Message_Block[Message_Block_Index++] = 0;
}
}
else
{
Message_Block[Message_Block_Index++] = 0x80;
while(Message_Block_Index < 56)
{
Message_Block[Message_Block_Index++] = 0;
}
}
ProcessMessageBlock();
/*
* Store the message length as the last 8 octets
*/
Message_Block[56] = (Length_High >> 24) & 0xFF;
Message_Block[57] = (Length_High >> 16) & 0xFF;
Message_Block[58] = (Length_High >> 8) & 0xFF;
Message_Block[59] = (Length_High) & 0xFF;
Message_Block[60] = (Length_Low >> 24) & 0xFF;
Message_Block[61] = (Length_Low >> 16) & 0xFF;
Message_Block[62] = (Length_Low >> 8) & 0xFF;
Message_Block[63] = (Length_Low) & 0xFF;
while (Message_Block_Index < 56)
{
Message_Block[Message_Block_Index++] = 0;
}
}
else
{
Message_Block[Message_Block_Index++] = 0x80;
ProcessMessageBlock();
while (Message_Block_Index < 56)
{
Message_Block[Message_Block_Index++] = 0;
}
}
/*
* Store the message length as the last 8 octets
*/
Message_Block[56] = (Length_High >> 24) & 0xFF;
Message_Block[57] = (Length_High >> 16) & 0xFF;
Message_Block[58] = (Length_High >> 8) & 0xFF;
Message_Block[59] = (Length_High) & 0xFF;
Message_Block[60] = (Length_Low >> 24) & 0xFF;
Message_Block[61] = (Length_Low >> 16) & 0xFF;
Message_Block[62] = (Length_Low >> 8) & 0xFF;
Message_Block[63] = (Length_Low) & 0xFF;
ProcessMessageBlock();
}
/*
/*
* CircularShift
*
* Description:
@ -614,49 +619,50 @@ void SHA1::PadMessage()
*/
unsigned SHA1::CircularShift(int bits, unsigned word)
{
return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32 - bits));
}
/** Definition of class Func_sha */
CalpontSystemCatalog::ColType Func_sha::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_sha::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
SHA1 sha;
uint32_t message_digest[5];
SHA1 sha;
uint32_t message_digest[5];
// Input is always treated as sring
sha.Reset();
sha << parm[0]->data()->getStrVal(row, isNull).c_str();
// can not compute
// Input is always treated as sring
sha.Reset();
sha << parm[0]->data()->getStrVal(row, isNull).c_str();
// can not compute
#ifdef _MSC_VER
// This cast is probably portable, but we'll leave it for Windows only for now...
if (!sha.Result(reinterpret_cast<unsigned int *>(message_digest)))
#else
if (!sha.Result(message_digest))
#endif
{
isNull = true;
return "";
}
// result length is always 40+1
char result[41];
snprintf(result, 41, "%08x", message_digest[0]);
snprintf(result+8, 41-8, "%08x", message_digest[1]);
snprintf(result+16, 41-16, "%08x", message_digest[2]);
snprintf(result+24, 41-24, "%08x", message_digest[3]);
snprintf(result+32, 41-32, "%08x", message_digest[4]);
result[40] = 0;
return result;
// This cast is probably portable, but we'll leave it for Windows only for now...
if (!sha.Result(reinterpret_cast<unsigned int*>(message_digest)))
#else
if (!sha.Result(message_digest))
#endif
{
isNull = true;
return "";
}
// result length is always 40+1
char result[41];
snprintf(result, 41, "%08x", message_digest[0]);
snprintf(result + 8, 41 - 8, "%08x", message_digest[1]);
snprintf(result + 16, 41 - 16, "%08x", message_digest[2]);
snprintf(result + 24, 41 - 24, "%08x", message_digest[3]);
snprintf(result + 32, 41 - 32, "%08x", message_digest[4]);
result[40] = 0;
return result;
}

View File

@ -35,40 +35,42 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_sign::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::BIGINT;
ct.colWidth = 8;
return ct;
}
int64_t Func_sign::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
double val = parm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return 0;
else if (val > 0)
return 1;
else if (val < 0)
return -1;
else
return 0;
double val = parm[0]->data()->getDoubleVal(row, isNull);
if (isNull)
return 0;
else if (val > 0)
return 1;
else if (val < 0)
return -1;
else
return 0;
}
string Func_sign::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t sign = getIntVal(row, parm, isNull, op_ct);
if (sign > 0)
return string("1");
else if (sign < 0)
return string("-1");
else
return string("0");
int64_t sign = getIntVal(row, parm, isNull, op_ct);
if (sign > 0)
return string("1");
else if (sign < 0)
return string("-1");
else
return string("0");
}
} // namespace funcexp

View File

@ -42,100 +42,117 @@ namespace
using namespace funcexp;
dataconvert::DateTime getDateTime (rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
TimeExtractor extractor;
dataconvert::DateTime dateTime;
dateTime.year = 0;
dateTime.month = 0;
dateTime.day = 0;
dateTime.hour = 0;
dateTime.minute = 0;
dateTime.second = 0;
dateTime.msecond = 0;
int64_t val = 0;
string valStr;
const string& formatStr = parm[1]->data()->getStrVal(row, isNull);
int rc = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getIntVal(row, isNull);
valStr = dataconvert::DataConvert::dateToString (val);
rc = extractor.extractTime (valStr, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getIntVal(row, isNull);
valStr = dataconvert::DataConvert::datetimeToString (val);
rc = extractor.extractTime (valStr, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
const string& valref = parm[0]->data()->getStrVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (valref, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
{
val = parm[0]->data()->getIntVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (helpers::intToString(val), formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{
val = parm[0]->data()->getIntVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (helpers::intToString(val), formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
}
break;
}
default:
isNull = true;
return -1;
}
return dateTime;
TimeExtractor extractor;
dataconvert::DateTime dateTime;
dateTime.year = 0;
dateTime.month = 0;
dateTime.day = 0;
dateTime.hour = 0;
dateTime.minute = 0;
dateTime.second = 0;
dateTime.msecond = 0;
int64_t val = 0;
string valStr;
const string& formatStr = parm[1]->data()->getStrVal(row, isNull);
int rc = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getIntVal(row, isNull);
valStr = dataconvert::DataConvert::dateToString (val);
rc = extractor.extractTime (valStr, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getIntVal(row, isNull);
valStr = dataconvert::DataConvert::datetimeToString (val);
rc = extractor.extractTime (valStr, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
const string& valref = parm[0]->data()->getStrVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (valref, formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
{
val = parm[0]->data()->getIntVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (helpers::intToString(val), formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
break;
}
case CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale == 0)
{
val = parm[0]->data()->getIntVal(row, isNull);
//decode with provided format
rc = extractor.extractTime (helpers::intToString(val), formatStr, dateTime);
if ( rc < 0)
{
isNull = true;
return -1;
}
}
break;
}
default:
isNull = true;
return -1;
}
return dateTime;
}
}
@ -145,52 +162,52 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_str_to_date::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_str_to_date::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
string convertedDate = dataconvert::DataConvert::datetimeToString(*((long long*) &dateTime));
return convertedDate;
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
string convertedDate = dataconvert::DataConvert::datetimeToString(*((long long*) &dateTime));
return convertedDate;
}
int32_t Func_str_to_date::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return ((((int32_t)(time >> 32)) & 0xFFFFFFC0) | 0x3E);
}
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return ((((int32_t)(time >> 32)) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_str_to_date::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return time;
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return time;
}
int64_t Func_str_to_date::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return time;
}
dataconvert::DateTime dateTime;
dateTime = getDateTime(row, parm, isNull, ct);
int64_t time = *(reinterpret_cast<int64_t*>(&dateTime));
return time;
}
} // namespace funcexp

View File

@ -41,11 +41,11 @@ using namespace funcexp;
class to_lower
{
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
public:
char operator() (char c) const // notice the return type
{
return tolower(c);
}
};
@ -54,37 +54,38 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_strcmp::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
// operation type is not used by this functor
//return fp[0]->data()->resultType();
return resultType;
}
int64_t Func_strcmp::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str1 = fp[1]->data()->getStrVal(row, isNull);
int ret = utf8::idb_strcoll(str.c_str(), str1.c_str());
// mysql's strcmp returns only -1, 0, and 1
return (ret < 0 ? -1 : (ret > 0 ? 1 : 0));
const string& str1 = fp[1]->data()->getStrVal(row, isNull);
int ret = utf8::idb_strcoll(str.c_str(), str1.c_str());
// mysql's strcmp returns only -1, 0, and 1
return (ret < 0 ? -1 : (ret > 0 ? 1 : 0));
}
std::string Func_strcmp::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t val = getIntVal(row, fp, isNull, op_ct);
if (val > 0)
return string("1");
else if (val < 0)
return string("-1");
else
return string("0");
uint64_t val = getIntVal(row, fp, isNull, op_ct);
if (val > 0)
return string("1");
else if (val < 0)
return string("-1");
else
return string("0");
}
} // namespace funcexp

View File

@ -42,97 +42,107 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_substr::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_substr::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
#ifdef STRCOLL_ENH__
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (isNull)
return "";
int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1;
if (isNull)
return "";
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring str(wcbuf, strwclen);
if (start == -1) // pos == 0
return "";
int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1;
wstring::size_type n = wstring::npos;
if (fp.size() == 3)
{
int64_t len = fp[2]->data()->getIntVal(row,isNull);
if (isNull)
return "";
if (isNull)
return "";
if (len < 1)
return "";
if (start == -1) // pos == 0
return "";
n = len;
}
wstring::size_type n = wstring::npos;
int64_t strLen = static_cast<int64_t>(str.length());
if (start < -1) // negative pos, beginning from end
start += strLen + 1;
if (fp.size() == 3)
{
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (start < 0 || strLen <= start)
{
return "";
}
if (isNull)
return "";
wstring out = str.substr(start, n);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
if (len < 1)
return "";
n = len;
}
int64_t strLen = static_cast<int64_t>(str.length());
if (start < -1) // negative pos, beginning from end
start += strLen + 1;
if (start < 0 || strLen <= start)
{
return "";
}
wstring out = str.substr(start, n);
size_t strmblen = utf8::idb_wcstombs(0, out.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, out.c_str(), strmblen);
return string(outbuf, strmblen);
#else
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& str = fp[0]->data()->getStrVal(row, isNull);
int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1;
if (isNull)
return "";
if (isNull)
return "";
if (start == -1) // pos == 0
return "";
int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1;
size_t n = string::npos;
if (fp.size() == 3)
{
int64_t len = fp[2]->data()->getIntVal(row,isNull);
if (isNull)
return "";
if (isNull)
return "";
if (len < 1)
return "";
if (start == -1) // pos == 0
return "";
n = len;
}
size_t n = string::npos;
size_t strLen = strlen(str.c_str());
if (start < -1) // negative pos, beginning from end
start += strLen + 1;
if (fp.size() == 3)
{
int64_t len = fp[2]->data()->getIntVal(row, isNull);
if (start < 0 || (int64_t)strLen <= start)
{
return "";
}
if (isNull)
return "";
return str.substr(start, n);
if (len < 1)
return "";
n = len;
}
size_t strLen = strlen(str.c_str());
if (start < -1) // negative pos, beginning from end
start += strLen + 1;
if (start < 0 || (int64_t)strLen <= start)
{
return "";
}
return str.substr(start, n);
#endif
}
}
} // namespace funcexp

View File

@ -41,74 +41,85 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_substring_index::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_substring_index::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& delim = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
return "";
if (isNull)
return "";
int64_t count = fp[2]->data()->getIntVal(row,isNull);
if (isNull)
return "";
const string& delim = fp[1]->data()->getStrVal(row, isNull);
if ( count == 0 )
return "";
if (isNull)
return "";
size_t end = strlen(str.c_str());
int64_t count = fp[2]->data()->getIntVal(row, isNull);
if ( count > (int64_t) end )
return str;
if (isNull)
return "";
string value = str;
if ( count == 0 )
return "";
if ( count > 0 ) {
int pointer = 0;
size_t end = strlen(str.c_str());
for ( int i = 0 ; i < count ; i ++ )
{
string::size_type pos = str.find(delim,pointer);
if (pos != string::npos)
pointer = pos+1;
end = pos;
}
value = str.substr(0,end);
}
else
{
count = count *-1;
size_t end = strlen(str.c_str());
int pointer = end;
int start = 0;
if ( count > (int64_t) end )
return str;
for ( int i = 0 ; i < count ; i ++ )
{
string::size_type pos = str.rfind(delim,pointer);
if (pos != string::npos) {
if ( count > (int64_t) end )
return "";
pointer = pos-1;
start = pos+1;
}
else
start = 0;
}
value = str.substr(start,end);
}
string value = str;
return value;
}
if ( count > 0 )
{
int pointer = 0;
for ( int i = 0 ; i < count ; i ++ )
{
string::size_type pos = str.find(delim, pointer);
if (pos != string::npos)
pointer = pos + 1;
end = pos;
}
value = str.substr(0, end);
}
else
{
count = count * -1;
size_t end = strlen(str.c_str());
int pointer = end;
int start = 0;
for ( int i = 0 ; i < count ; i ++ )
{
string::size_type pos = str.rfind(delim, pointer);
if (pos != string::npos)
{
if ( count > (int64_t) end )
return "";
pointer = pos - 1;
start = pos + 1;
}
else
start = 0;
}
value = str.substr(start, end);
}
return value;
}
} // namespace funcexp

View File

@ -45,59 +45,59 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_sysdate::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_sysdate::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
struct tm tmp_tm;
time_t now;
now = time(NULL);
localtime_r(&now, &tmp_tm);
struct tm tmp_tm;
time_t now;
now = time(NULL);
localtime_r(&now, &tmp_tm);
dataconvert::DateTime aDatetime;
aDatetime.year = (tmp_tm.tm_year+1900) % 10000;
aDatetime.month = tmp_tm.tm_mon+1;
aDatetime.day = tmp_tm.tm_mday;
aDatetime.hour = tmp_tm.tm_hour;
aDatetime.minute = tmp_tm.tm_min;
aDatetime.second = tmp_tm.tm_sec;
aDatetime.msecond = 0;
return *(reinterpret_cast<uint64_t*>(&aDatetime));
dataconvert::DateTime aDatetime;
aDatetime.year = (tmp_tm.tm_year + 1900) % 10000;
aDatetime.month = tmp_tm.tm_mon + 1;
aDatetime.day = tmp_tm.tm_mday;
aDatetime.hour = tmp_tm.tm_hour;
aDatetime.minute = tmp_tm.tm_min;
aDatetime.second = tmp_tm.tm_sec;
aDatetime.msecond = 0;
return *(reinterpret_cast<uint64_t*>(&aDatetime));
}
string Func_sysdate::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
time_t now;
now = time(NULL);
struct tm tm;
localtime_r(&now, &tm);
time_t now;
now = time(NULL);
struct tm tm;
localtime_r(&now, &tm);
char timestamp[80];
strftime (timestamp, 80, "%Y-%m-%d %H:%M:%S", &tm);
return timestamp;
char timestamp[80];
strftime (timestamp, 80, "%Y-%m-%d %H:%M:%S", &tm);
return timestamp;
}
int32_t Func_sysdate::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
return (((getIntVal(row, parm, isNull, operationColType) >> 32) & 0xFFFFFFC0) | 0x3E);
return (((getIntVal(row, parm, isNull, operationColType) >> 32) & 0xFFFFFFC0) | 0x3E);
}
int64_t Func_sysdate::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
return getIntVal(row, parm, isNull, operationColType);
return getIntVal(row, parm, isNull, operationColType);
}

View File

@ -38,104 +38,119 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_time::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_time::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return "";
char buf[30] = {'\0'};
dataconvert::DataConvert::datetimeToString(val, buf, sizeof(buf));
string time(buf);
return time.substr(11,80);
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
{
if (parm[0]->data()->resultType().scale)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
{
isNull = true;
break;
}
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
isNull = true;
//else
// return *(reinterpret_cast<uint64_t*>(&val));
break;
}
case execplan::CalpontSystemCatalog::DATE:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
val = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
}
default:
{
isNull = true;
}
}
if (isNull)
return "";
char buf[30] = {'\0'};
dataconvert::DataConvert::datetimeToString(val, buf, sizeof(buf));
string time(buf);
return time.substr(11, 80);
}
int64_t Func_time::getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, fp, isNull, op_ct));
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, fp, isNull, op_ct));
}
double Func_time::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// convert time value to int followiing mysql. e.g. 23:34:34 => 233434
int64_t datetimevalue = dataconvert::DataConvert::stringToDatetime(fp[0]->data()->getStrVal(row, isNull));
return ((unsigned)((datetimevalue >> 32) & 0x3f)) * 10000 +
((unsigned)((datetimevalue >> 26) & 0x3f)) * 100 +
(unsigned)((datetimevalue >> 20) & 0x3f);
// convert time value to int followiing mysql. e.g. 23:34:34 => 233434
int64_t datetimevalue = dataconvert::DataConvert::stringToDatetime(fp[0]->data()->getStrVal(row, isNull));
return ((unsigned)((datetimevalue >> 32) & 0x3f)) * 10000 +
((unsigned)((datetimevalue >> 26) & 0x3f)) * 100 +
(unsigned)((datetimevalue >> 20) & 0x3f);
}

View File

@ -38,161 +38,184 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_time_format::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
CalpontSystemCatalog::ColType ct;
ct.colDataType = CalpontSystemCatalog::VARCHAR;
ct.colWidth = 255;
return ct;
}
string Func_time_format::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
int64_t val = 0;
uint32_t hour = 0,
min = 0,
sec = 0,
msec = 0;
// assume 256 is enough. assume not allowing incomplete date
char buf[256];
int64_t val = 0;
uint32_t hour = 0,
min = 0,
sec = 0,
msec = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
isNull = true;
return "";
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
isNull = true;
return "";
break;
char* ptr = buf;
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'f':
sprintf(ptr, "%06d", msec);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (hour%24 + 11)%12+1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", min);
ptr += 2;
break;
case 'k':
sprintf(ptr, "%d", hour);
ptr += (hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (hour%24 + 11)%12+1);
ptr += ((hour%24 + 11)%12+1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(hour + 11) % 12 + 1, min, sec);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", sec);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", hour, min, sec);
ptr += 8;
break;
default:
isNull = true;
return "";
}
}
}
*ptr = 0;
return string(buf);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return "";
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
msec = (uint32_t)((val & 0xfffff));
}
}
break;
default:
isNull = true;
return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
char* ptr = buf;
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
else
{
i++;
switch (format[i])
{
case 'f':
sprintf(ptr, "%06d", msec);
ptr += 6;
break;
case 'H':
sprintf(ptr, "%02d", hour);
ptr += 2;
break;
case 'h':
case 'I':
sprintf(ptr, "%02d", (hour % 24 + 11) % 12 + 1);
ptr += 2;
break;
case 'i': /* minutes */
sprintf(ptr, "%02d", min);
ptr += 2;
break;
case 'k':
sprintf(ptr, "%d", hour);
ptr += (hour >= 10 ? 2 : 1);
break;
case 'l':
sprintf(ptr, "%d", (hour % 24 + 11) % 12 + 1);
ptr += ((hour % 24 + 11) % 12 + 1 >= 10 ? 2 : 1);
break;
case 'p':
sprintf(ptr, "%s", (hour % 24 < 12 ? "AM" : "PM"));
ptr += 2;
break;
case 'r':
sprintf(ptr, (hour % 24 < 12 ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM"),
(hour + 11) % 12 + 1, min, sec);
ptr += 11;
break;
case 'S':
case 's':
sprintf(ptr, "%02d", sec);
ptr += 2;
break;
case 'T':
sprintf (ptr, "%02d:%02d:%02d", hour, min, sec);
ptr += 8;
break;
default:
isNull = true;
return "";
}
}
}
*ptr = 0;
return string(buf);
}

View File

@ -39,45 +39,91 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_time_to_sec::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
// assume 256 is enough. assume not allowing incomplete date
uint32_t hour = 0,
min = 0,
sec = 0;
// assume 256 is enough. assume not allowing incomplete date
uint32_t hour = 0,
min = 0,
sec = 0;
bool bIsNegative = false; // Only set to true if CHAR or VARCHAR with a '-'
int64_t val = 0;
dataconvert::Time tval;
int64_t val = 0;
dataconvert::Time tval;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
return 0;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
return 0;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
std::string strVal = parm[0]->data()->getStrVal(row, isNull);
if (strVal[0] == '-')
{
std::string strVal = parm[0]->data()->getStrVal(row, isNull);
if (strVal[0] == '-')
{
bIsNegative = true;
strVal.replace(0, 1, 1, ' ');
}
val = dataconvert::DataConvert::stringToTime(strVal);
bIsNegative = true;
strVal.replace(0, 1, 1, ' ');
}
val = dataconvert::DataConvert::stringToTime(strVal);
if (val == -1)
{
isNull = true;
return -1;
}
else
{
tval = *(reinterpret_cast<dataconvert::Time*>(&val));
hour = (uint32_t)(tval.hour);
min = (uint32_t)(tval.minute);
sec = (uint32_t)(tval.second);
}
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
@ -85,58 +131,27 @@ int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row,
}
else
{
tval = *(reinterpret_cast<dataconvert::Time*>(&val));
hour = (uint32_t)(tval.hour);
min = (uint32_t)(tval.minute);
sec = (uint32_t)(tval.second);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
}
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
int64_t rtn = (int64_t)(hour*60*60)+(min*60)+sec;
break;
default:
isNull = true;
return -1;
}
int64_t rtn = (int64_t)(hour * 60 * 60) + (min * 60) + sec;
if (bIsNegative)
{
rtn *= -1;
}
return rtn;
return rtn;
}

View File

@ -46,24 +46,25 @@ namespace helpers
const string timediff( int64_t time1, int64_t time2)
{
long long seconds;
long long microseconds;
int l_sign = 1;
long long seconds;
long long microseconds;
int l_sign = 1;
if ( (time1 < 0 && time2 >= 0) ||
(time2 < 0 && time1 >= 0) )
l_sign = -l_sign;
if ( (time1 < 0 && time2 >= 0) ||
(time2 < 0 && time1 >= 0) )
l_sign = -l_sign;
if ( time1 > time2 )
helpers::calc_time_diff(time1, time2, l_sign, &seconds, &microseconds);
else
helpers::calc_time_diff(time2, time1, l_sign, &seconds, &microseconds);
if ( time1 > time2 )
helpers::calc_time_diff(time1, time2, l_sign, &seconds, &microseconds);
else
helpers::calc_time_diff(time2, time1, l_sign, &seconds, &microseconds);
long t_seconds;
int hour = seconds / 3600L;
t_seconds = seconds % 3600L;
int minute = t_seconds / 60L;
int second = t_seconds % 60L;
long t_seconds;
int hour= seconds/3600L;
t_seconds= seconds%3600L;
int minute= t_seconds/60L;
int second= t_seconds%60L;
// Bug 5099: Standardize to mysql behavior. No timediff may be > 838:59:59
if (hour > 838)
{
@ -71,151 +72,165 @@ const string timediff( int64_t time1, int64_t time2)
minute = 59;
second = 59;
}
int sign = 0;
if ( time1 < time2 )
sign = 1;
char buf[256];
char* ptr = buf;
string time3;
if ( microseconds == 0 )
sprintf (ptr, "%s%02d:%02d:%02d", sign ? "-" : "", hour, minute, second);
else
sprintf (ptr, "%s%02d:%02d:%02d:%06lld", sign ? "-" : "",hour, minute, second, microseconds);
int sign = 0;
time3 = ptr;
if ( time1 < time2 )
sign = 1;
return time3;
char buf[256];
char* ptr = buf;
string time3;
if ( microseconds == 0 )
sprintf (ptr, "%s%02d:%02d:%02d", sign ? "-" : "", hour, minute, second);
else
sprintf (ptr, "%s%02d:%02d:%02d:%06lld", sign ? "-" : "", hour, minute, second, microseconds);
time3 = ptr;
return time3;
}
}
CalpontSystemCatalog::ColType Func_timediff::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_timediff::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int16_t type1 = parm[0]->data()->resultType().colDataType;
int16_t type2 = parm[1]->data()->resultType().colDataType;
int64_t val1 = -1, val2 = -1;
bool isDate1 = false, isDate2 = false;
int16_t type1 = parm[0]->data()->resultType().colDataType;
int16_t type2 = parm[1]->data()->resultType().colDataType;
switch (type1)
{
case execplan::CalpontSystemCatalog::DATE:
val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
isDate1 = true;
break;
case execplan::CalpontSystemCatalog::DATETIME:
val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
val1 = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull), &isDate1);
break;
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
break;
case execplan::CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale != 0)
{
isNull = true;
break;
}
else
{
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
break;
}
default:
isNull = true;
}
switch (type2)
{
case execplan::CalpontSystemCatalog::DATE:
val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
isDate2 = true;
break;
case execplan::CalpontSystemCatalog::DATETIME:
val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
val2 = dataconvert::DataConvert::stringToDatetime(parm[1]->data()->getStrVal(row, isNull), &isDate2);
break;
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
break;
case execplan::CalpontSystemCatalog::DECIMAL:
if (parm[1]->data()->resultType().scale != 0)
{
isNull = true;
break;
}
else
{
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
break;
}
default:
isNull = true;
}
if (isNull || val1 == -1 || val2 == -1)
{
isNull = true;
return "";
}
// both date format or both datetime format
if ((isDate1 && isDate2) || (!isDate1 && !isDate2))
return helpers::timediff( val1, val2);
isNull = true;
return "";
int64_t val1 = -1, val2 = -1;
bool isDate1 = false, isDate2 = false;
switch (type1)
{
case execplan::CalpontSystemCatalog::DATE:
val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
isDate1 = true;
break;
case execplan::CalpontSystemCatalog::DATETIME:
val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
val1 = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull), &isDate1);
break;
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
break;
case execplan::CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale != 0)
{
isNull = true;
break;
}
else
{
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
break;
}
default:
isNull = true;
}
switch (type2)
{
case execplan::CalpontSystemCatalog::DATE:
val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
isDate2 = true;
break;
case execplan::CalpontSystemCatalog::DATETIME:
val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
val2 = dataconvert::DataConvert::stringToDatetime(parm[1]->data()->getStrVal(row, isNull), &isDate2);
break;
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
break;
case execplan::CalpontSystemCatalog::DECIMAL:
if (parm[1]->data()->resultType().scale != 0)
{
isNull = true;
break;
}
else
{
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
break;
}
default:
isNull = true;
}
if (isNull || val1 == -1 || val2 == -1)
{
isNull = true;
return "";
}
// both date format or both datetime format
if ((isDate1 && isDate2) || (!isDate1 && !isDate2))
return helpers::timediff( val1, val2);
isNull = true;
return "";
}
int64_t Func_timediff::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
}
int64_t Func_timediff::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
// @bug 3585
//return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
return strtoll(getStrVal(row, parm, isNull, ct).c_str(), 0, 10);
// @bug 3585
//return dataconvert::DataConvert::datetimeToInt(getStrVal(row, parm, isNull, ct));
return strtoll(getStrVal(row, parm, isNull, ct).c_str(), 0, 10);
}
double Func_timediff::getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
// @bug 3585
//return (double)dataconvert::DataConvert::datetimeToInt(getStrVal(row, fp, isNull, op_ct));
return atof(getStrVal(row, fp, isNull, op_ct).c_str());
// @bug 3585
//return (double)dataconvert::DataConvert::datetimeToInt(getStrVal(row, fp, isNull, op_ct));
return atof(getStrVal(row, fp, isNull, op_ct).c_str());
}

View File

@ -42,109 +42,114 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_timestampdiff::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_timestampdiff::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
int64_t val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
int64_t val1 = parm[0]->data()->getDatetimeIntVal(row, isNull);
int64_t val2 = parm[1]->data()->getDatetimeIntVal(row, isNull);
IntervalColumn::interval_type unit = static_cast<IntervalColumn::interval_type>(parm[2]->data()->getIntVal(row, isNull));
DateTime dt1, dt2;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
dt2.year = (val2 >> 48) & 0xffff;
dt2.month = (val2 >> 44) & 0xf;
dt2.day = (val2 >> 38) & 0x3f;
dt2.hour = (val2 >> 32) & 0x3f;
dt2.minute = (val2 >> 26) & 0x3f;
dt2.second = (val2 >> 20) & 0x3f;
dt2.msecond = val2 & 0xfffff;
int64_t diff = 0;
// unit: MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR
int64_t monthdiff = ((int64_t)dt2.month - (int64_t)dt1.month) +
((int64_t)dt2.year - (int64_t)dt1.year) * 12;
if (unit == IntervalColumn::INTERVAL_YEAR)
{
diff = monthdiff / 12;
}
else if (unit == IntervalColumn::INTERVAL_MONTH)
{
diff = monthdiff;
if (dt2.day < dt1.day && monthdiff >0)
diff = monthdiff - 1;
else if (dt1.day < dt2.day && monthdiff < 0)
diff = monthdiff + 1;
}
else if (unit == IntervalColumn::INTERVAL_QUARTER)
{
diff = monthdiff / 3;
int daydiff = monthdiff %3;
if (daydiff == 0)
{
if (dt2.day < dt1.day && monthdiff > 0)
diff --;
else if (dt1.day < dt2.day && monthdiff < 0)
diff ++;
}
}
else
{
int64_t seconds = 0, mseconds = 0;
int l_sign = 1;
int l_sign3;
DateTime dt1, dt2;
dt1.year = (val1 >> 48) & 0xffff;
dt1.month = (val1 >> 44) & 0xf;
dt1.day = (val1 >> 38) & 0x3f;
dt1.hour = (val1 >> 32) & 0x3f;
dt1.minute = (val1 >> 26) & 0x3f;
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
l_sign3 = helpers::calc_time_diff(val2, val1, l_sign, (long long*)&seconds, (long long*)&mseconds);
l_sign3 = (l_sign3 == 0 ? 1 : -1);
if (unit == IntervalColumn::INTERVAL_SECOND)
diff = l_sign3 * seconds;
else if (unit == IntervalColumn::INTERVAL_MICROSECOND)
diff = l_sign3 * (seconds * 1000000L + mseconds);
else if (unit == IntervalColumn::INTERVAL_MINUTE)
diff = l_sign3 * (seconds/60L);
else if (unit == IntervalColumn::INTERVAL_HOUR)
diff = l_sign3 * (seconds/3600L);
else if (unit == IntervalColumn::INTERVAL_DAY)
diff = l_sign3 * (seconds/(24L*3600L));
else if (unit == IntervalColumn::INTERVAL_WEEK)
diff = l_sign3 * (seconds/(24L*3600L)/7L);
}
return diff;
dt2.year = (val2 >> 48) & 0xffff;
dt2.month = (val2 >> 44) & 0xf;
dt2.day = (val2 >> 38) & 0x3f;
dt2.hour = (val2 >> 32) & 0x3f;
dt2.minute = (val2 >> 26) & 0x3f;
dt2.second = (val2 >> 20) & 0x3f;
dt2.msecond = val2 & 0xfffff;
int64_t diff = 0;
// unit: MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR
int64_t monthdiff = ((int64_t)dt2.month - (int64_t)dt1.month) +
((int64_t)dt2.year - (int64_t)dt1.year) * 12;
if (unit == IntervalColumn::INTERVAL_YEAR)
{
diff = monthdiff / 12;
}
else if (unit == IntervalColumn::INTERVAL_MONTH)
{
diff = monthdiff;
if (dt2.day < dt1.day && monthdiff > 0)
diff = monthdiff - 1;
else if (dt1.day < dt2.day && monthdiff < 0)
diff = monthdiff + 1;
}
else if (unit == IntervalColumn::INTERVAL_QUARTER)
{
diff = monthdiff / 3;
int daydiff = monthdiff % 3;
if (daydiff == 0)
{
if (dt2.day < dt1.day && monthdiff > 0)
diff --;
else if (dt1.day < dt2.day && monthdiff < 0)
diff ++;
}
}
else
{
int64_t seconds = 0, mseconds = 0;
int l_sign = 1;
int l_sign3;
l_sign3 = helpers::calc_time_diff(val2, val1, l_sign, (long long*)&seconds, (long long*)&mseconds);
l_sign3 = (l_sign3 == 0 ? 1 : -1);
if (unit == IntervalColumn::INTERVAL_SECOND)
diff = l_sign3 * seconds;
else if (unit == IntervalColumn::INTERVAL_MICROSECOND)
diff = l_sign3 * (seconds * 1000000L + mseconds);
else if (unit == IntervalColumn::INTERVAL_MINUTE)
diff = l_sign3 * (seconds / 60L);
else if (unit == IntervalColumn::INTERVAL_HOUR)
diff = l_sign3 * (seconds / 3600L);
else if (unit == IntervalColumn::INTERVAL_DAY)
diff = l_sign3 * (seconds / (24L * 3600L));
else if (unit == IntervalColumn::INTERVAL_WEEK)
diff = l_sign3 * (seconds / (24L * 3600L) / 7L);
}
return diff;
}
string Func_timestampdiff::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return intToString(getIntVal(row, parm, isNull, ct));
return intToString(getIntVal(row, parm, isNull, ct));
}
int32_t Func_timestampdiff::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getIntVal(row, parm, isNull, ct);
return getIntVal(row, parm, isNull, ct);
}
int64_t Func_timestampdiff::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return getIntVal(row, parm, isNull, ct);
return getIntVal(row, parm, isNull, ct);
}

View File

@ -45,77 +45,80 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_to_days::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_to_days::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType;
uint32_t year = 0,
month = 0,
day = 0;
uint32_t year = 0,
month = 0,
day = 0;
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = parm[0]->data()->getDateIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
return helpers::calc_mysql_daynr(year, month, day);
break;
}
switch (type)
{
case execplan::CalpontSystemCatalog::DATE:
{
int32_t val = parm[0]->data()->getDateIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
return helpers::calc_mysql_daynr(year, month, day);
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = parm[0]->data()->getDatetimeIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t val = parm[0]->data()->getDatetimeIntVal(row, isNull);
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;
}
return helpers::calc_mysql_daynr(year, month, day);
break;
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
int64_t val = 0;
if ( value.size() == 10 ) {
// date type
val = dataconvert::DataConvert::dateToInt(value);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
}
else
{ // datetime type
val = dataconvert::DataConvert::datetimeToInt(value);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
int64_t val = 0;
return helpers::calc_mysql_daynr(year, month, day);
break;
}
if ( value.size() == 10 )
{
// date type
val = dataconvert::DataConvert::dateToInt(value);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
}
else
{
// datetime type
val = dataconvert::DataConvert::datetimeToInt(value);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
default:
{
std::ostringstream oss;
oss << "to_days: datatype of " << execplan::colDataTypeToString(type);;
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return helpers::calc_mysql_daynr(year, month, day);
break;
}
return 0;
default:
{
std::ostringstream oss;
oss << "to_days: datatype of " << execplan::colDataTypeToString(type);;
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return 0;
}

View File

@ -39,20 +39,20 @@ namespace funcexp
{
CalpontSystemCatalog::ColType Func_trim::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_trim::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// The number of characters (not bytes) in our input tstr.
// Not all of these are necessarily significant. We need to search for the
// Not all of these are necessarily significant. We need to search for the
// NULL terminator to be sure.
size_t strwclen;
size_t strwclen;
// this holds the number of characters (not bytes) in ourtrim tstr.
size_t trimwclen;
@ -64,79 +64,88 @@ std::string Func_trim::getStrVal(rowgroup::Row& row,
if (isNull)
return "";
if (tstr.empty() || tstr.length() == 0)
return tstr;
// Rather than calling the wideconvert functions with a null buffer to
// Rather than calling the wideconvert functions with a null buffer to
// determine the size of buffer to allocate, we can be sure the wide
// char string won't be longer than:
strwclen = tstr.length(); // a guess to start with. This will be >= to the real count.
int bufsize = (strwclen+1) * sizeof(wchar_t);
int bufsize = (strwclen + 1) * sizeof(wchar_t);
// Convert the string to wide characters. Do all further work in wide characters
wchar_t* wcbuf = (wchar_t*)alloca(bufsize);
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1);
// Bad char in mbc can return -1
if(strwclen == static_cast<size_t>(-1))
strwclen = 0;
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen + 1);
// Bad char in mbc can return -1
if (strwclen == static_cast<size_t>(-1))
strwclen = 0;
// Convert the trim string to wide
trimwclen = trim.length(); // A guess to start.
int trimbufsize = (trimwclen+1) * sizeof(wchar_t);
int trimbufsize = (trimwclen + 1) * sizeof(wchar_t);
wchar_t* wctrim = (wchar_t*)alloca(trimbufsize);
size_t trimlen = utf8::idb_mbstowcs(wctrim,trim.c_str(), trimwclen+1);
// Bad char in mbc can return -1
if(trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimlen = utf8::idb_mbstowcs(wctrim, trim.c_str(), trimwclen + 1);
// Bad char in mbc can return -1
if (trimlen == static_cast<size_t>(-1))
trimlen = 0;
size_t trimCmpLen = trimlen * sizeof(wchar_t);
const wchar_t* oPtr = wcbuf; // To remember the start of the string
const wchar_t* aPtr = oPtr;
const wchar_t* aEnd = wcbuf+strwclen-1;
const wchar_t* aEnd = wcbuf + strwclen - 1;
size_t trimCnt = 0;
if(trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr = wctrim[0];
// remove leading
while (aPtr != aEnd && *aPtr == chr)
{
aPtr++;
++trimCnt;
}
// remove trailing
while (aEnd != aPtr && *aEnd == chr)
{
aEnd--;
++trimCnt;
}
}
else
{
aEnd-=(trimlen-1); // So we don't compare past the end of the string.
// remove leading
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
{
aPtr+=trimlen;
trimCnt+=trimlen;
}
// remove trailing
while (aPtr <= aEnd && !memcmp(aEnd, wctrim, trimCmpLen))
{
aEnd-=trimlen; //BUG 5241
trimCnt+=trimlen;
}
}
}
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen-trimCnt;
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
if (trimlen > 0)
{
if (trimlen == 1)
{
// If trim is a single char, then don't spend the overhead for memcmp.
wchar_t chr = wctrim[0];
// remove leading
while (aPtr != aEnd && *aPtr == chr)
{
aPtr++;
++trimCnt;
}
// remove trailing
while (aEnd != aPtr && *aEnd == chr)
{
aEnd--;
++trimCnt;
}
}
else
{
aEnd -= (trimlen - 1); // So we don't compare past the end of the string.
// remove leading
while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen))
{
aPtr += trimlen;
trimCnt += trimlen;
}
// remove trailing
while (aPtr <= aEnd && !memcmp(aEnd, wctrim, trimCmpLen))
{
aEnd -= trimlen; //BUG 5241
trimCnt += trimlen;
}
}
}
// Bug 5110 - error in allocating enough memory for utf8 chars
size_t aLen = strwclen - trimCnt;
wstring trimmed = wstring(aPtr, aLen);
// Turn back to a string
return utf8::wstring_to_utf8(trimmed.c_str());
}
} // namespace funcexp

View File

@ -28,7 +28,7 @@ using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "errorcodes.h"
#include "idberrorinfo.h"
#include "errorids.h"
@ -44,20 +44,22 @@ using namespace funcexp;
inline void decimalPlaceDouble(FunctionParm& fp, int64_t& s, double& p, Row& row, bool& isNull)
{
s = fp[1]->data()->getIntVal(row, isNull);
int64_t d = s;
if (isNull)
return;
s = fp[1]->data()->getIntVal(row, isNull);
int64_t d = s;
int64_t i = (d >= 0) ? d : (-d);
int64_t r = 1;
while (i--)
r *= 10;
if (isNull)
return;
if (d >= 0)
p = (double) r;
else
p = 1.0 / ((double) r);
int64_t i = (d >= 0) ? d : (-d);
int64_t r = 1;
while (i--)
r *= 10;
if (d >= 0)
p = (double) r;
else
p = 1.0 / ((double) r);
}
}
@ -67,37 +69,40 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_truncate::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
if (resultType.colDataType == execplan::CalpontSystemCatalog::DECIMAL ||
resultType.colDataType == execplan::CalpontSystemCatalog::UDECIMAL)
{
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (resultType.scale > ct.scale)
(resultType).scale = ct.scale;
break;
}
default:
{
break;
}
}
}
if (resultType.colDataType == execplan::CalpontSystemCatalog::DECIMAL ||
resultType.colDataType == execplan::CalpontSystemCatalog::UDECIMAL)
{
CalpontSystemCatalog::ColType ct = fp[0]->data()->resultType();
return fp[0]->data()->resultType();
switch (ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
if (resultType.scale > ct.scale)
(resultType).scale = ct.scale;
break;
}
default:
{
break;
}
}
}
return fp[0]->data()->resultType();
}
@ -105,335 +110,352 @@ CalpontSystemCatalog::ColType Func_truncate::operationType(FunctionParm& fp, Cal
//
int64_t Func_truncate::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
if (x.scale > 0)
{
while (x.scale-- > 0)
x.value /= 10;
}
else
{
while (x.scale++ < 0)
x.value *= 10;
}
if (x.scale > 0)
{
while (x.scale-- > 0)
x.value /= 10;
}
else
{
while (x.scale++ < 0)
x.value *= 10;
}
return x.value;
return x.value;
}
uint64_t Func_truncate::getUintVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
return parm[0]->data()->getUintVal(row, isNull);
return parm[0]->data()->getUintVal(row, isNull);
}
double Func_truncate::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
if (execplan::CalpontSystemCatalog::DOUBLE == op_ct.colDataType ||
execplan::CalpontSystemCatalog::FLOAT == op_ct.colDataType)
{
int64_t d = 0;
double p = 1;
decimalPlaceDouble(parm, d, p, row, isNull);
if (execplan::CalpontSystemCatalog::DOUBLE == op_ct.colDataType ||
execplan::CalpontSystemCatalog::FLOAT == op_ct.colDataType)
{
int64_t d = 0;
double p = 1;
decimalPlaceDouble(parm, d, p, row, isNull);
if (isNull)
return 0.0;
if (isNull)
return 0.0;
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
x *= p;
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (x > 0)
x = floor(x);
else
x = ceil(x);
if (!isNull)
{
x *= p;
if (p != 0.0)
x /= p;
else
x = 0.0;
}
if (x > 0)
x = floor(x);
else
x = ceil(x);
return x;
}
if (p != 0.0)
x /= p;
else
x = 0.0;
}
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
if (isNull)
return 0.0;
return x;
}
double d = x.value;
if (x.scale > 0)
{
while (x.scale-- > 0)
d /= 10.0;
}
else
{
while (x.scale++ < 0)
d *= 10.0;
}
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
return d;
if (isNull)
return 0.0;
double d = x.value;
if (x.scale > 0)
{
while (x.scale-- > 0)
d /= 10.0;
}
else
{
while (x.scale++ < 0)
d *= 10.0;
}
return d;
}
IDB_Decimal Func_truncate::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal decimal;
IDB_Decimal decimal;
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
int64_t d = 0;
//@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile.
volatile int64_t p = 1;
decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (!isNull)
{
int64_t nvp = p;
d = parm[1]->data()->getIntVal(row, isNull);
if (!isNull)
helpers::decimalPlaceDec(d, nvp, decimal.scale);
p = nvp;
}
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
int64_t d = 0;
//@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile.
volatile int64_t p = 1;
decimal = parm[0]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
if (!isNull)
{
int64_t nvp = p;
d = parm[1]->data()->getIntVal(row, isNull);
int64_t x = decimal.value;
if (d > 0)
{
x = x * p;
}
else if (d < 0)
{
if ((x >= p) || (x <= -p))
{
if (p != 0)
x = x / p;
else
x = 0;
}
else
{
x = 0;
}
}
if (!isNull)
helpers::decimalPlaceDec(d, nvp, decimal.scale);
// negative scale is not supported by CNX yet, set d to 0.
if (decimal.scale < 0)
{
do
x *= 10;
while (++decimal.scale < 0);
}
decimal.value = x;
}
break;
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t s = 0;
double p = 1;
decimalPlaceDouble(parm, s, p, row, isNull);
p = nvp;
}
if (isNull)
break;
if (isNull)
break;
double x = parm[0]->data()->getDoubleVal(row, isNull);
if (!isNull)
{
x *= p;
decimal.value = (int64_t) x;
decimal.scale = s;
}
}
break;
int64_t x = decimal.value;
case execplan::CalpontSystemCatalog::DATE:
{
int32_t s = 0;
int64_t x = 0;
if (d > 0)
{
x = x * p;
}
else if (d < 0)
{
if ((x >= p) || (x <= -p))
{
if (p != 0)
x = x / p;
else
x = 0;
}
else
{
x = 0;
}
}
string value = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
// negative scale is not supported by CNX yet, set d to 0.
if (decimal.scale < 0)
{
do
x *= 10;
s = parm[1]->data()->getIntVal(row, isNull);
while (++decimal.scale < 0);
}
if (!isNull)
{
x = atoll(value.c_str());
decimal.value = x;
}
break;
if ( s > 11 )
s = 0;
if ( s > 0 )
{
x *= helpers::powerOf10_c[s];
}
else if (s < 0)
{
s = -s;
if ( s >= (int32_t) value.size() )
{
x = 0;
}
else
{
x /= helpers::powerOf10_c[s];
x *= helpers::powerOf10_c[s];
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
int64_t s = 0;
double p = 1;
decimalPlaceDouble(parm, s, p, row, isNull);
s = 0;
}
}
if (isNull)
break;
decimal.value = x;
decimal.scale = s;
}
break;
double x = parm[0]->data()->getDoubleVal(row, isNull);
case execplan::CalpontSystemCatalog::DATETIME:
{
int32_t s = 0;
int64_t x = 0;
if (!isNull)
{
x *= p;
decimal.value = (int64_t) x;
decimal.scale = s;
}
}
break;
string value =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
case execplan::CalpontSystemCatalog::DATE:
{
int32_t s = 0;
int64_t x = 0;
s = parm[1]->data()->getIntVal(row, isNull);
string value = DataConvert::dateToString1(parm[0]->data()->getDateIntVal(row, isNull));
if (!isNull)
{
//strip off micro seconds
value = value.substr(0,14);
int64_t x = atoll(value.c_str());
s = parm[1]->data()->getIntVal(row, isNull);
if ( s > 5 )
s = 0;
if ( s > 0 )
{
x *= helpers::powerOf10_c[s];
}
else if (s < 0)
{
s = -s;
if ( s >= (int32_t) value.size() )
{
x = 0;
}
else
{
x /= helpers::powerOf10_c[s];
x *= helpers::powerOf10_c[s];
}
if (!isNull)
{
x = atoll(value.c_str());
s = 0;
}
}
if ( s > 11 )
s = 0;
decimal.value = x;
decimal.scale = s;
}
break;
if ( s > 0 )
{
x *= helpers::powerOf10_c[s];
}
else if (s < 0)
{
s = -s;
if ( s >= (int32_t) value.size() )
{
x = 0;
}
else
{
x /= helpers::powerOf10_c[s];
x *= helpers::powerOf10_c[s];
}
s = 0;
}
}
decimal.value = x;
decimal.scale = s;
}
break;
case execplan::CalpontSystemCatalog::DATETIME:
{
int32_t s = 0;
int64_t x = 0;
string value =
DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull));
s = parm[1]->data()->getIntVal(row, isNull);
if (!isNull)
{
//strip off micro seconds
value = value.substr(0, 14);
int64_t x = atoll(value.c_str());
if ( s > 5 )
s = 0;
if ( s > 0 )
{
x *= helpers::powerOf10_c[s];
}
else if (s < 0)
{
s = -s;
if ( s >= (int32_t) value.size() )
{
x = 0;
}
else
{
x /= helpers::powerOf10_c[s];
x *= helpers::powerOf10_c[s];
}
s = 0;
}
}
decimal.value = x;
decimal.scale = s;
}
break;
default:
{
std::ostringstream oss;
oss << "truncate: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
default:
{
std::ostringstream oss;
oss << "truncate: datatype of " << execplan::colDataTypeToString(op_ct.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return decimal;
return decimal;
}
string Func_truncate::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct);
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
if (x.scale != 0)
{
if (x.scale > 0 && x.scale < 19)
{
x.value /= IDB_pow[x.scale];
}
else if (x.scale < 0 && x.scale > -19)
{
x.value *= IDB_pow[-x.scale]; // may overflow
}
else if (x.scale > 0)
{
x.value = 0;
}
else // overflow may need throw exception
{
int64_t e = -x.scale % 18;
x.value *= IDB_pow[e];
e = -x.scale - e;
while (e > 0)
{
x.value *= IDB_pow[18];
e -= 18;
}
}
switch (op_ct.colDataType)
{
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
if (x.scale != 0)
{
if (x.scale > 0 && x.scale < 19)
{
x.value /= IDB_pow[x.scale];
}
else if (x.scale < 0 && x.scale > -19)
{
x.value *= IDB_pow[-x.scale]; // may overflow
}
else if (x.scale > 0)
{
x.value = 0;
}
else // overflow may need throw exception
{
int64_t e = -x.scale % 18;
x.value *= IDB_pow[e];
e = -x.scale - e;
x.scale = 0;
}
break;
default:
break;
}
while (e > 0)
{
x.value *= IDB_pow[18];
e -= 18;
}
}
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
x.scale = 0;
}
break;
default:
break;
}
return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType);
}

View File

@ -37,47 +37,48 @@ using namespace joblist;
class to_upper
{
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
public:
char operator() (char c) const // notice the return type
{
return toupper(c);
}
};
namespace funcexp
{
CalpontSystemCatalog::ColType Func_ucase::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_ucase::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType&)
{
// string str = fp[0]->data()->getStrVal(row, isNull);
// transform (str.begin(), str.end(), str.begin(), to_lower());
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
if (isNull)
return "";
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towupper(wstr[i]);
size_t strwclen = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1;
wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t));
strwclen = utf8::idb_mbstowcs(wcbuf, tstr.c_str(), strwclen);
wstring wstr(wcbuf, strwclen);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
for (uint32_t i = 0; i < strwclen; i++)
wstr[i] = std::towupper(wstr[i]);
size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1;
char* outbuf = (char*)alloca(strmblen * sizeof(char));
strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen);
return string(outbuf, strmblen);
}
} // namespace funcexp

View File

@ -36,15 +36,18 @@ using namespace execplan;
namespace
{
int64_t hex_to_int(char c)
{
if (c <= '9' && c >= '0')
return c-'0';
c = toupper(c);
if (c <= 'F' && c >= 'A')
return c-'A'+10;
return -1;
}
int64_t hex_to_int(char c)
{
if (c <= '9' && c >= '0')
return c - '0';
c = toupper(c);
if (c <= 'F' && c >= 'A')
return c - 'A' + 10;
return -1;
}
}
namespace funcexp
@ -52,50 +55,58 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_unhex::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
string Func_unhex::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& from = parm[0]->data()->getStrVal(row, isNull);
char* to = new char[2 + from.length()/2];
if (!to)
{
isNull = true;
return "";
}
uint64_t from_pos = 0, to_pos = 0;
int64_t hex_char = 0;
if (strlen(from.c_str()) % 2)
{
hex_char = hex_to_int(from[from_pos++]);
to[to_pos++] = hex_char;
if (hex_char == -1)
goto nullHandling;
}
const string& from = parm[0]->data()->getStrVal(row, isNull);
char* to = new char[2 + from.length() / 2];
for (; from_pos < strlen(from.c_str()); from_pos+=2)
{
hex_char = hex_to_int(from[from_pos]) << 4;
if (hex_char == -1)
goto nullHandling;
to[to_pos] = hex_char;
hex_char = hex_to_int(from[from_pos+1]);
if (hex_char == -1)
goto nullHandling;
to[to_pos++] |= hex_char;
}
to[to_pos] = 0;
return string(to);
if (!to)
{
isNull = true;
return "";
}
uint64_t from_pos = 0, to_pos = 0;
int64_t hex_char = 0;
if (strlen(from.c_str()) % 2)
{
hex_char = hex_to_int(from[from_pos++]);
to[to_pos++] = hex_char;
if (hex_char == -1)
goto nullHandling;
}
for (; from_pos < strlen(from.c_str()); from_pos += 2)
{
hex_char = hex_to_int(from[from_pos]) << 4;
if (hex_char == -1)
goto nullHandling;
to[to_pos] = hex_char;
hex_char = hex_to_int(from[from_pos + 1]);
if (hex_char == -1)
goto nullHandling;
to[to_pos++] |= hex_char;
}
to[to_pos] = 0;
return string(to);
nullHandling:
isNull = true;
return "";
isNull = true;
return "";
}

View File

@ -38,173 +38,192 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_unix_timestamp::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_unix_timestamp::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
int64_t val = parm[0]->data()->getIntVal(row, isNull);
if (isNull) { //no paramter, return current unix_timestamp
// get current time in seconds
time_t cal;
time (&cal);
return (int64_t) cal;
}
int64_t val = parm[0]->data()->getIntVal(row, isNull);
uint32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
if (isNull) //no paramter, return current unix_timestamp
{
// get current time in seconds
time_t cal;
time (&cal);
return (int64_t) cal;
}
uint32_t year = 0,
month = 0,
day = 0,
hour = 0,
min = 0,
sec = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
break;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
// same algorithm as my_time.c:my_system_gmt_sec
uint32_t loop;
time_t tmp_t= 0;
int shift= 0;
struct tm *l_time,tm_tmp;
int64_t diff, my_time_zone = parm[1]->data()->getIntVal(row, isNull);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
hour = (uint32_t)((val >> 32) & 0x3f);
min = (uint32_t)((val >> 26) & 0x3f);
sec = (uint32_t)((val >> 20) & 0x3f);
break;
if ((year == helpers::TIMESTAMP_MAX_YEAR) && (month == 1) && (day > 4))
{
day-= 2;
shift= 2;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
tmp_t= (time_t)(((helpers::calc_mysql_daynr(year,month,day) -
719528)* 86400L + (int64_t)hour*3600L +
(int64_t)(min*60 + sec)) - (time_t)my_time_zone);
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
localtime_r(&tmp_t,&tm_tmp);
l_time=&tm_tmp;
for (loop=0; loop < 2 && (hour != (uint32_t) l_time->tm_hour || min != (uint32_t) l_time->tm_min ||
sec != (uint32_t)l_time->tm_sec); loop++)
{
int days= day - l_time->tm_mday;
if (days < -1)
days= 1; /* Month has wrapped */
else if (days > 1)
days= -1;
diff=(3600L*(int64_t) (days*24+((int) hour - (int) l_time->tm_hour)) +
(int64_t) (60*((int) min - (int) l_time->tm_min)) +
(int64_t) ((int) sec - (int) l_time->tm_sec));
tmp_t+= (time_t) diff;
localtime_r(&tmp_t,&tm_tmp);
l_time=&tm_tmp;
}
break;
if (loop == 2 && hour != (uint32_t)l_time->tm_hour)
{
int days= day - l_time->tm_mday;
if (days < -1)
days=1; /* Month has wrapped */
else if (days > 1)
days= -1;
diff=(3600L*(int64_t) (days*24+((int) hour - (int) l_time->tm_hour))+
(int64_t) (60*((int) min - (int) l_time->tm_min)) +
(int64_t) ((int) sec - (int) l_time->tm_sec));
if (diff == 3600)
tmp_t+=3600 - min*60 - sec; /* Move to next hour */
else if (diff == -3600)
tmp_t-=min*60 + sec; /* Move to previous hour */
}
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
// same algorithm as my_time.c:my_system_gmt_sec
uint32_t loop;
time_t tmp_t = 0;
int shift = 0;
struct tm* l_time, tm_tmp;
int64_t diff, my_time_zone = parm[1]->data()->getIntVal(row, isNull);
if ((year == helpers::TIMESTAMP_MAX_YEAR) && (month == 1) && (day > 4))
{
day -= 2;
shift = 2;
}
tmp_t = (time_t)(((helpers::calc_mysql_daynr(year, month, day) -
719528) * 86400L + (int64_t)hour * 3600L +
(int64_t)(min * 60 + sec)) - (time_t)my_time_zone);
localtime_r(&tmp_t, &tm_tmp);
l_time = &tm_tmp;
for (loop = 0; loop < 2 && (hour != (uint32_t) l_time->tm_hour || min != (uint32_t) l_time->tm_min ||
sec != (uint32_t)l_time->tm_sec); loop++)
{
int days = day - l_time->tm_mday;
if (days < -1)
days = 1; /* Month has wrapped */
else if (days > 1)
days = -1;
diff = (3600L * (int64_t) (days * 24 + ((int) hour - (int) l_time->tm_hour)) +
(int64_t) (60 * ((int) min - (int) l_time->tm_min)) +
(int64_t) ((int) sec - (int) l_time->tm_sec));
tmp_t += (time_t) diff;
localtime_r(&tmp_t, &tm_tmp);
l_time = &tm_tmp;
}
if (loop == 2 && hour != (uint32_t)l_time->tm_hour)
{
int days = day - l_time->tm_mday;
if (days < -1)
days = 1; /* Month has wrapped */
else if (days > 1)
days = -1;
diff = (3600L * (int64_t) (days * 24 + ((int) hour - (int) l_time->tm_hour)) +
(int64_t) (60 * ((int) min - (int) l_time->tm_min)) +
(int64_t) ((int) sec - (int) l_time->tm_sec));
if (diff == 3600)
tmp_t += 3600 - min * 60 - sec; /* Move to next hour */
else if (diff == -3600)
tmp_t -= min * 60 + sec; /* Move to previous hour */
}
/* shift back, if we were dealing with boundary dates */
tmp_t += shift*86400L;
/* shift back, if we were dealing with boundary dates */
tmp_t += shift * 86400L;
/* make sure we have legit timestamps (i.e. we didn't over/underflow anywhere above) */
if ((tmp_t < helpers::TIMESTAMP_MIN_VALUE) || (tmp_t > helpers::TIMESTAMP_MAX_VALUE))
tmp_t = 0;
/* make sure we have legit timestamps (i.e. we didn't over/underflow anywhere above) */
if ((tmp_t < helpers::TIMESTAMP_MIN_VALUE) || (tmp_t > helpers::TIMESTAMP_MAX_VALUE))
tmp_t = 0;
return (int64_t)tmp_t;
return (int64_t)tmp_t;
}
string Func_unix_timestamp::getStrVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& ct)
{
return dataconvert::DataConvert::datetimeToString(getIntVal(row, parm, isNull, ct));
return dataconvert::DataConvert::datetimeToString(getIntVal(row, parm, isNull, ct));
}

View File

@ -39,98 +39,109 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_week::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_week::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0,
month = 0,
day = 0;
uint32_t year = 0,
month = 0,
day = 0;
int64_t val = 0;
int16_t mode = 0;
int64_t val = 0;
int16_t mode = 0;
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
int week = helpers::calc_mysql_week(year, month, day,
helpers::convert_mysql_mode_to_modeflags(mode));
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
return week;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
int week = helpers::calc_mysql_week(year, month, day,
helpers::convert_mysql_mode_to_modeflags(mode));
return week;
}

View File

@ -39,89 +39,102 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_weekday::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_weekday::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, false);
uint32_t year = 0;
uint32_t month = 0;
uint32_t day = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
return helpers::calc_mysql_weekday(year, month, day, false);
}

View File

@ -38,78 +38,89 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_year::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_year::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
int64_t val = 0;
int64_t val = 0;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 16) & 0xffff);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 48) & 0xffff);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 16) & 0xffff);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
return (unsigned)((val >> 48) & 0xffff);
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::DOUBLE:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
}
break;
default:
isNull = true;
return -1;
}
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
return -1;
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
return (unsigned)((val >> 48) & 0xffff);
}
}
break;
default:
isNull = true;
return -1;
}
return -1;
}

View File

@ -39,103 +39,114 @@ namespace funcexp
CalpontSystemCatalog::ColType Func_yearweek::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
return resultType;
}
int64_t Func_yearweek::getIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
uint32_t year = 0,
month = 0,
day = 0;
uint32_t year = 0,
month = 0,
day = 0;
int64_t val = 0;
int16_t mode = 0; // default to 2
int64_t val = 0;
int16_t mode = 0; // default to 2
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
if (parm.size() > 1) // mode value
mode = parm[1]->data()->getIntVal(row, isNull);
//cout << parm.size() << " " << mode << endl;
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
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:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
switch (parm[0]->data()->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 16) & 0xffff);
month = (uint32_t)((val >> 12) & 0xf);
day = (uint32_t)((val >> 6) & 0x3f);
break;
uint32_t lyear=0;
int week = helpers::calc_mysql_week(year, month, day,
(helpers::convert_mysql_mode_to_modeflags(mode) | helpers::WEEK_NO_ZERO),
&lyear);
case CalpontSystemCatalog::DATETIME:
val = parm[0]->data()->getIntVal(row, isNull);
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
break;
return (lyear*100)+week;
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::BIGINT:
case CalpontSystemCatalog::MEDINT:
case CalpontSystemCatalog::SMALLINT:
case CalpontSystemCatalog::TINYINT:
case CalpontSystemCatalog::INT:
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
break;
case CalpontSystemCatalog::DECIMAL:
if (parm[0]->data()->resultType().scale == 0)
{
val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
default:
isNull = true;
return -1;
}
uint32_t lyear = 0;
int week = helpers::calc_mysql_week(year, month, day,
(helpers::convert_mysql_mode_to_modeflags(mode) | helpers::WEEK_NO_ZERO),
&lyear);
return (lyear * 100) + week;
}

View File

@ -56,340 +56,392 @@ boost::mutex FuncExp::fInstanceMutex;
FuncExp* FuncExp::instance()
{
boost::mutex::scoped_lock lk(fInstanceMutex);
if (!fInstance)
fInstance = new FuncExp();
return fInstance;
boost::mutex::scoped_lock lk(fInstanceMutex);
if (!fInstance)
fInstance = new FuncExp();
return fInstance;
}
FuncExp::FuncExp()
{
fFuncMap["<<"] = new Func_leftshift();
fFuncMap[">>"] = new Func_rightshift();
fFuncMap["|"] = new Func_bitor();
fFuncMap["^"] = new Func_bitxor();
fFuncMap["&"] = new Func_bitand();
fFuncMap["abs"] = new Func_abs();
fFuncMap["acos"] = new Func_acos();
fFuncMap["add_time"] = new Func_add_time();
fFuncMap["asin"] = new Func_asin();
fFuncMap["ascii"] = new Func_ascii();
fFuncMap["atan"] = new Func_atan();
fFuncMap["atan2"] = new Func_atan();
fFuncMap["between"] = new Func_between();
fFuncMap["case_searched"] = new Func_searched_case();
fFuncMap["case_simple"] = new Func_simple_case();
fFuncMap["cast_as_signed"] = new Func_cast_signed(); //dlh
fFuncMap["<<"] = new Func_leftshift();
fFuncMap[">>"] = new Func_rightshift();
fFuncMap["|"] = new Func_bitor();
fFuncMap["^"] = new Func_bitxor();
fFuncMap["&"] = new Func_bitand();
fFuncMap["abs"] = new Func_abs();
fFuncMap["acos"] = new Func_acos();
fFuncMap["add_time"] = new Func_add_time();
fFuncMap["asin"] = new Func_asin();
fFuncMap["ascii"] = new Func_ascii();
fFuncMap["atan"] = new Func_atan();
fFuncMap["atan2"] = new Func_atan();
fFuncMap["between"] = new Func_between();
fFuncMap["case_searched"] = new Func_searched_case();
fFuncMap["case_simple"] = new Func_simple_case();
fFuncMap["cast_as_signed"] = new Func_cast_signed(); //dlh
fFuncMap["cast_as_unsigned"] = new Func_cast_unsigned(); //dch
fFuncMap["cast_as_char"] = new Func_cast_char(); //dlh
fFuncMap["cast_as_date"] = new Func_cast_date(); //dlh
fFuncMap["cast_as_datetime"] = new Func_cast_datetime(); //dlh
fFuncMap["decimal_typecast"] = new Func_cast_decimal(); //dlh
fFuncMap["cast_as_char"] = new Func_cast_char(); //dlh
fFuncMap["cast_as_date"] = new Func_cast_date(); //dlh
fFuncMap["cast_as_datetime"] = new Func_cast_datetime(); //dlh
fFuncMap["decimal_typecast"] = new Func_cast_decimal(); //dlh
fFuncMap["double_typecast"] = new Func_cast_double();
fFuncMap["ceil"] = new Func_ceil(); //dlh
fFuncMap["ceiling"] = new Func_ceil(); //dlh
fFuncMap["char"] = new Func_char(); //dlh
fFuncMap["char_length"] = new Func_char_length(); //dlh
fFuncMap["character_length"] = new Func_char_length(); //dlh
fFuncMap["coalesce"] = new Func_coalesce();
fFuncMap["concat"] = new Func_concat();
fFuncMap["concat_ws"] = new Func_concat_ws();
fFuncMap["conv"] = new Func_conv();
fFuncMap["cos"] = new Func_cos();
fFuncMap["cot"] = new Func_cot();
fFuncMap["convert"] = new Func_cast_char(); //dlh
fFuncMap["crc32"] = new Func_crc32();
fFuncMap["date_add_interval"] = new Func_date_add(); //dlh
fFuncMap["date_format"] = new Func_date_format();
fFuncMap["day"] = new Func_day(); //dlh
fFuncMap["dayname"] = new Func_dayname();
fFuncMap["dayofmonth"] = new Func_day(); //dlh
fFuncMap["dayofweek"] = new Func_dayofweek(); //dlh
fFuncMap["dayofyear"] = new Func_dayofyear(); //dlh
fFuncMap["degrees"] = new Func_degrees();
fFuncMap["DIV"] = new Func_div(); // MySQL use upper case for this function name
fFuncMap["elt"] = new Func_elt();
fFuncMap["exp"] = new Func_exp();
fFuncMap["extract"] = new Func_extract(); //dlh
fFuncMap["find_in_set"] = new Func_find_in_set();
fFuncMap["floor"] = new Func_floor(); //dlh
fFuncMap["format"] = new Func_format(); //dlh
fFuncMap["from_days"] = new Func_from_days();
fFuncMap["from_unixtime"] = new Func_from_unixtime();
fFuncMap["get_format"] = new Func_get_format(); //dlh
fFuncMap["greatest"] = new Func_greatest(); //dlh
fFuncMap["hex"] = new Func_hex();
fFuncMap["hour"] = new Func_hour(); //dlh
fFuncMap["idbpartition"] = new Func_idbpartition(); // pseudo column
fFuncMap["if"] = new Func_if();
fFuncMap["ifnull"] = new Func_ifnull();
fFuncMap["in"] = new Func_in();
fFuncMap[" IN "] = new Func_in();
fFuncMap["inet_aton"] = new Func_inet_aton();
fFuncMap["inet_ntoa"] = new Func_inet_ntoa();
fFuncMap["insert"] = new Func_insert();
fFuncMap["instr"] = new Func_instr();
fFuncMap["isnull"] = new Func_isnull(false);
fFuncMap["isnotnull"] = new Func_isnull(true);
fFuncMap["last_day"] = new Func_last_day();
fFuncMap["lcase"] = new Func_lcase(); //dlh
fFuncMap["least"] = new Func_least(); //dlh
fFuncMap["left"] = new Func_left(); //dlh
fFuncMap["length"] = new Func_length();
fFuncMap["ln"] = new Func_log();
fFuncMap["locate"] = new Func_instr();
fFuncMap["log"] = new Func_log();
fFuncMap["log2"] = new Func_log2();
fFuncMap["log10"] = new Func_log10();
fFuncMap["lower"] = new Func_lcase(); //dlh
fFuncMap["lpad"] = new Func_lpad(); //dlh
fFuncMap["ltrim"] = new Func_ltrim(); //dlh
fFuncMap["makedate"] = new Func_makedate();
fFuncMap["maketime"] = new Func_maketime();
fFuncMap["microsecond"] = new Func_microsecond();
fFuncMap["minute"] = new Func_minute(); //dlh
fFuncMap["mod"] = new Func_mod(); //dlh
fFuncMap["%"] = new Func_mod(); //dlh
fFuncMap["md5"] = new Func_md5();
fFuncMap["mid"] = new Func_substr();
fFuncMap["month"] = new Func_month(); //dlh
fFuncMap["monthname"] = new Func_monthname();
fFuncMap["notin"] = new Func_notin();
fFuncMap["not IN "] = new Func_notin();
fFuncMap["notbetween"] = new Func_notbetween();
fFuncMap["nullif"] = new Func_nullif();
fFuncMap["period_add"] = new Func_period_add(); //dlh
fFuncMap["period_diff"] = new Func_period_diff(); //dlh
fFuncMap["position"] = new Func_instr(); //dlh
fFuncMap["pow"] = new Func_pow();
fFuncMap["power"] = new Func_pow();
fFuncMap["quarter"] = new Func_quarter();
fFuncMap["radians"] = new Func_radians(); //dlh
fFuncMap["rand"] = new Func_rand();
fFuncMap["regexp"] = new Func_regexp(); //dlh
fFuncMap["repeat"] = new Func_repeat(); //dlh
fFuncMap["replace"] = new Func_replace(); //dlh
fFuncMap["reverse"] = new Func_reverse(); //dlh
fFuncMap["right"] = new Func_right(); //dlh
fFuncMap["round"] = new Func_round();
fFuncMap["rpad"] = new Func_rpad(); //dlh
fFuncMap["rtrim"] = new Func_rtrim(); //dlh
fFuncMap["second"] = new Func_second(); //dlh
fFuncMap["sec_to_time"] = new Func_sec_to_time();
fFuncMap["sha"] = new Func_sha();
fFuncMap["sha1"] = new Func_sha();
fFuncMap["sign"] = new Func_sign();
fFuncMap["sin"] = new Func_sin();
fFuncMap["sqrt"] = new Func_sqrt();
fFuncMap["str_to_date"] = new Func_str_to_date();
fFuncMap["strcmp"] = new Func_strcmp();
fFuncMap["substr"] = new Func_substr();
fFuncMap["substring"] = new Func_substr(); //dlh
fFuncMap["substring_index"] = new Func_substring_index(); //dlh
fFuncMap["sysdate"] = new Func_sysdate(); //dlhFuncExp
fFuncMap["cast_as_time"] = new Func_time(); //dlh
fFuncMap["tan"] = new Func_tan();
fFuncMap["timediff"] = new Func_timediff(); //dlh
fFuncMap["timestampdiff"] = new Func_timestampdiff();
fFuncMap["time_format"] = new Func_time_format(); //dlh
fFuncMap["time_to_sec"] = new Func_time_to_sec(); //dlh
fFuncMap["to_days"] = new Func_to_days(); //dlh
fFuncMap["trim"] = new Func_trim(); //dlh
fFuncMap["truncate"] = new Func_truncate(); //dlh
fFuncMap["ucase"] = new Func_ucase(); //dlh
//fFuncMap["unhex"] = new Func_unhex();
fFuncMap["unix_timestamp"] = new Func_unix_timestamp();
fFuncMap["upper"] = new Func_ucase(); //dlh
fFuncMap["week"] = new Func_week(); //dlh
fFuncMap["weekday"] = new Func_weekday();
fFuncMap["weekofyear"] = new Func_week(); //dlh
fFuncMap["year"] = new Func_year(); //dlh
fFuncMap["yearweek"] = new Func_yearweek(); //dlh
fFuncMap["ceil"] = new Func_ceil(); //dlh
fFuncMap["ceiling"] = new Func_ceil(); //dlh
fFuncMap["char"] = new Func_char(); //dlh
fFuncMap["char_length"] = new Func_char_length(); //dlh
fFuncMap["character_length"] = new Func_char_length(); //dlh
fFuncMap["coalesce"] = new Func_coalesce();
fFuncMap["concat"] = new Func_concat();
fFuncMap["concat_ws"] = new Func_concat_ws();
fFuncMap["conv"] = new Func_conv();
fFuncMap["cos"] = new Func_cos();
fFuncMap["cot"] = new Func_cot();
fFuncMap["convert"] = new Func_cast_char(); //dlh
fFuncMap["crc32"] = new Func_crc32();
fFuncMap["date_add_interval"] = new Func_date_add(); //dlh
fFuncMap["date_format"] = new Func_date_format();
fFuncMap["day"] = new Func_day(); //dlh
fFuncMap["dayname"] = new Func_dayname();
fFuncMap["dayofmonth"] = new Func_day(); //dlh
fFuncMap["dayofweek"] = new Func_dayofweek(); //dlh
fFuncMap["dayofyear"] = new Func_dayofyear(); //dlh
fFuncMap["degrees"] = new Func_degrees();
fFuncMap["DIV"] = new Func_div(); // MySQL use upper case for this function name
fFuncMap["elt"] = new Func_elt();
fFuncMap["exp"] = new Func_exp();
fFuncMap["extract"] = new Func_extract(); //dlh
fFuncMap["find_in_set"] = new Func_find_in_set();
fFuncMap["floor"] = new Func_floor(); //dlh
fFuncMap["format"] = new Func_format(); //dlh
fFuncMap["from_days"] = new Func_from_days();
fFuncMap["from_unixtime"] = new Func_from_unixtime();
fFuncMap["get_format"] = new Func_get_format(); //dlh
fFuncMap["greatest"] = new Func_greatest(); //dlh
fFuncMap["hex"] = new Func_hex();
fFuncMap["hour"] = new Func_hour(); //dlh
fFuncMap["idbpartition"] = new Func_idbpartition(); // pseudo column
fFuncMap["if"] = new Func_if();
fFuncMap["ifnull"] = new Func_ifnull();
fFuncMap["in"] = new Func_in();
fFuncMap[" IN "] = new Func_in();
fFuncMap["inet_aton"] = new Func_inet_aton();
fFuncMap["inet_ntoa"] = new Func_inet_ntoa();
fFuncMap["insert"] = new Func_insert();
fFuncMap["instr"] = new Func_instr();
fFuncMap["isnull"] = new Func_isnull(false);
fFuncMap["isnotnull"] = new Func_isnull(true);
fFuncMap["last_day"] = new Func_last_day();
fFuncMap["lcase"] = new Func_lcase(); //dlh
fFuncMap["least"] = new Func_least(); //dlh
fFuncMap["left"] = new Func_left(); //dlh
fFuncMap["length"] = new Func_length();
fFuncMap["ln"] = new Func_log();
fFuncMap["locate"] = new Func_instr();
fFuncMap["log"] = new Func_log();
fFuncMap["log2"] = new Func_log2();
fFuncMap["log10"] = new Func_log10();
fFuncMap["lower"] = new Func_lcase(); //dlh
fFuncMap["lpad"] = new Func_lpad(); //dlh
fFuncMap["ltrim"] = new Func_ltrim(); //dlh
fFuncMap["makedate"] = new Func_makedate();
fFuncMap["maketime"] = new Func_maketime();
fFuncMap["microsecond"] = new Func_microsecond();
fFuncMap["minute"] = new Func_minute(); //dlh
fFuncMap["mod"] = new Func_mod(); //dlh
fFuncMap["%"] = new Func_mod(); //dlh
fFuncMap["md5"] = new Func_md5();
fFuncMap["mid"] = new Func_substr();
fFuncMap["month"] = new Func_month(); //dlh
fFuncMap["monthname"] = new Func_monthname();
fFuncMap["notin"] = new Func_notin();
fFuncMap["not IN "] = new Func_notin();
fFuncMap["notbetween"] = new Func_notbetween();
fFuncMap["nullif"] = new Func_nullif();
fFuncMap["period_add"] = new Func_period_add(); //dlh
fFuncMap["period_diff"] = new Func_period_diff(); //dlh
fFuncMap["position"] = new Func_instr(); //dlh
fFuncMap["pow"] = new Func_pow();
fFuncMap["power"] = new Func_pow();
fFuncMap["quarter"] = new Func_quarter();
fFuncMap["radians"] = new Func_radians(); //dlh
fFuncMap["rand"] = new Func_rand();
fFuncMap["regexp"] = new Func_regexp(); //dlh
fFuncMap["repeat"] = new Func_repeat(); //dlh
fFuncMap["replace"] = new Func_replace(); //dlh
fFuncMap["reverse"] = new Func_reverse(); //dlh
fFuncMap["right"] = new Func_right(); //dlh
fFuncMap["round"] = new Func_round();
fFuncMap["rpad"] = new Func_rpad(); //dlh
fFuncMap["rtrim"] = new Func_rtrim(); //dlh
fFuncMap["second"] = new Func_second(); //dlh
fFuncMap["sec_to_time"] = new Func_sec_to_time();
fFuncMap["sha"] = new Func_sha();
fFuncMap["sha1"] = new Func_sha();
fFuncMap["sign"] = new Func_sign();
fFuncMap["sin"] = new Func_sin();
fFuncMap["sqrt"] = new Func_sqrt();
fFuncMap["str_to_date"] = new Func_str_to_date();
fFuncMap["strcmp"] = new Func_strcmp();
fFuncMap["substr"] = new Func_substr();
fFuncMap["substring"] = new Func_substr(); //dlh
fFuncMap["substring_index"] = new Func_substring_index(); //dlh
fFuncMap["sysdate"] = new Func_sysdate(); //dlhFuncExp
fFuncMap["cast_as_time"] = new Func_time(); //dlh
fFuncMap["tan"] = new Func_tan();
fFuncMap["timediff"] = new Func_timediff(); //dlh
fFuncMap["timestampdiff"] = new Func_timestampdiff();
fFuncMap["time_format"] = new Func_time_format(); //dlh
fFuncMap["time_to_sec"] = new Func_time_to_sec(); //dlh
fFuncMap["to_days"] = new Func_to_days(); //dlh
fFuncMap["trim"] = new Func_trim(); //dlh
fFuncMap["truncate"] = new Func_truncate(); //dlh
fFuncMap["ucase"] = new Func_ucase(); //dlh
//fFuncMap["unhex"] = new Func_unhex();
fFuncMap["unix_timestamp"] = new Func_unix_timestamp();
fFuncMap["upper"] = new Func_ucase(); //dlh
fFuncMap["week"] = new Func_week(); //dlh
fFuncMap["weekday"] = new Func_weekday();
fFuncMap["weekofyear"] = new Func_week(); //dlh
fFuncMap["year"] = new Func_year(); //dlh
fFuncMap["yearweek"] = new Func_yearweek(); //dlh
#ifndef SKIP_UDF
udfsdk::UDFSDK sdk;
FuncMap sdkfm = sdk.UDFMap();
FuncMap::const_iterator iter = sdkfm.begin();
FuncMap::iterator funcMapIter;
for (; iter != sdkfm.end(); ++iter)
{
//add sdkfm to fFuncMap
funcMapIter = fFuncMap.find(iter->first);
if (funcMapIter != fFuncMap.end())
{
// silently ignore the udf function? log it?
}
else
{
fFuncMap[iter->first] = iter->second;
}
}
udfsdk::UDFSDK sdk;
FuncMap sdkfm = sdk.UDFMap();
FuncMap::const_iterator iter = sdkfm.begin();
FuncMap::iterator funcMapIter;
for (; iter != sdkfm.end(); ++iter)
{
//add sdkfm to fFuncMap
funcMapIter = fFuncMap.find(iter->first);
if (funcMapIter != fFuncMap.end())
{
// silently ignore the udf function? log it?
}
else
{
fFuncMap[iter->first] = iter->second;
}
}
#endif
}
Func* FuncExp::getFunctor(std::string& funcName)
{
FuncMap::iterator iter = fFuncMap.find(funcName);
if (iter == fFuncMap.end())
return NULL;
else
return (*iter).second;
FuncMap::iterator iter = fFuncMap.find(funcName);
if (iter == fFuncMap.end())
return NULL;
else
return (*iter).second;
}
void FuncExp::evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expression)
{
bool isNull;
for (uint32_t i = 0; i < expression.size(); i++)
{
isNull = false;
switch (expression[i]->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
{
int64_t val = expression[i]->getIntVal(row, isNull);
// @bug6061, workaround date_add always return datetime for both date and datetime
if (val & 0xFFFFFFFF00000000)
val = (((val >> 32) & 0xFFFFFFC0) | 0x3E);
if (isNull)
row.setUintField<4>(DATENULL, expression[i]->outputIndex());
else
row.setUintField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::DATETIME:
{
int64_t val = expression[i]->getDatetimeIntVal(row, isNull);
if (isNull)
row.setUintField<8>(DATETIMENULL, expression[i]->outputIndex());
else
row.setUintField<8>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
bool isNull;
for (uint32_t i = 0; i < expression.size(); i++)
{
isNull = false;
switch (expression[i]->resultType().colDataType)
{
case CalpontSystemCatalog::DATE:
{
int64_t val = expression[i]->getIntVal(row, isNull);
// @bug6061, workaround date_add always return datetime for both date and datetime
if (val & 0xFFFFFFFF00000000)
val = (((val >> 32) & 0xFFFFFFC0) | 0x3E);
if (isNull)
row.setUintField<4>(DATENULL, expression[i]->outputIndex());
else
row.setUintField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::DATETIME:
{
int64_t val = expression[i]->getDatetimeIntVal(row, isNull);
if (isNull)
row.setUintField<8>(DATETIMENULL, expression[i]->outputIndex());
else
row.setUintField<8>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
// TODO: might not be right thing for BLOB
case CalpontSystemCatalog::BLOB:
case CalpontSystemCatalog::TEXT:
{
const std::string& val = expression[i]->getStrVal(row, isNull);
if (isNull)
row.setStringField(CPNULLSTRMARK, expression[i]->outputIndex());
else
row.setStringField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::BIGINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<8>(BIGINTNULL, expression[i]->outputIndex());
else
row.setIntField<8>(val, expression[i]->outputIndex());
break;
}
{
const std::string& val = expression[i]->getStrVal(row, isNull);
if (isNull)
row.setStringField(CPNULLSTRMARK, expression[i]->outputIndex());
else
row.setStringField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::BIGINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<8>(BIGINTNULL, expression[i]->outputIndex());
else
row.setIntField<8>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::UBIGINT:
{
uint64_t val = expression[i]->getUintVal(row, isNull);
if (isNull)
row.setUintField<8>(UBIGINTNULL, expression[i]->outputIndex());
else
row.setUintField<8>(val, expression[i]->outputIndex());
break;
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<4>(INTNULL, expression[i]->outputIndex());
else
row.setIntField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
{
uint64_t val = expression[i]->getUintVal(row, isNull);
if (isNull)
row.setUintField<4>(UINTNULL, expression[i]->outputIndex());
else
row.setUintField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<2>(SMALLINTNULL, expression[i]->outputIndex());
else
row.setIntField<2>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::INT:
case CalpontSystemCatalog::MEDINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<4>(INTNULL, expression[i]->outputIndex());
else
row.setIntField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::UINT:
case CalpontSystemCatalog::UMEDINT:
{
uint64_t val = expression[i]->getUintVal(row, isNull);
if (isNull)
row.setUintField<4>(UINTNULL, expression[i]->outputIndex());
else
row.setUintField<4>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::SMALLINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<2>(SMALLINTNULL, expression[i]->outputIndex());
else
row.setIntField<2>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::USMALLINT:
{
uint64_t val = expression[i]->getUintVal(row, isNull);
if (isNull)
row.setUintField<2>(USMALLINTNULL, expression[i]->outputIndex());
else
row.setUintField<2>(val, expression[i]->outputIndex());
break;
break;
}
case CalpontSystemCatalog::TINYINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<1>(TINYINTNULL, expression[i]->outputIndex());
else
row.setIntField<1>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::TINYINT:
{
int64_t val = expression[i]->getIntVal(row, isNull);
if (isNull)
row.setIntField<1>(TINYINTNULL, expression[i]->outputIndex());
else
row.setIntField<1>(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::UTINYINT:
{
uint64_t val = expression[i]->getUintVal(row, isNull);
if (isNull)
row.setUintField<1>(UTINYINTNULL, expression[i]->outputIndex());
else
row.setUintField<1>(val, expression[i]->outputIndex());
break;
break;
}
//In this case, we're trying to load a double output column with float data. This is the
// case when you do sum(floatcol), e.g.
case CalpontSystemCatalog::DOUBLE:
//In this case, we're trying to load a double output column with float data. This is the
// case when you do sum(floatcol), e.g.
case CalpontSystemCatalog::DOUBLE:
case CalpontSystemCatalog::UDOUBLE:
{
double val = expression[i]->getDoubleVal(row, isNull);
if (isNull)
row.setIntField<8>(DOUBLENULL, expression[i]->outputIndex());
else
row.setDoubleField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::FLOAT:
{
double val = expression[i]->getDoubleVal(row, isNull);
if (isNull)
row.setIntField<8>(DOUBLENULL, expression[i]->outputIndex());
else
row.setDoubleField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT:
{
float val = expression[i]->getFloatVal(row, isNull);
if (isNull)
row.setIntField<4>(FLOATNULL, expression[i]->outputIndex());
else
row.setFloatField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::DECIMAL:
{
float val = expression[i]->getFloatVal(row, isNull);
if (isNull)
row.setIntField<4>(FLOATNULL, expression[i]->outputIndex());
else
row.setFloatField(val, expression[i]->outputIndex());
break;
}
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal val = expression[i]->getDecimalVal(row, isNull);
if (isNull)
row.setIntField<8>(BIGINTNULL, expression[i]->outputIndex());
else
row.setIntField<8>(val.value, expression[i]->outputIndex());
break;
}
default: // treat as int64
{
throw std::runtime_error("funcexp::evaluate(): non support datatype to set field.");
}
}
}
{
IDB_Decimal val = expression[i]->getDecimalVal(row, isNull);
if (isNull)
row.setIntField<8>(BIGINTNULL, expression[i]->outputIndex());
else
row.setIntField<8>(val.value, expression[i]->outputIndex());
break;
}
default: // treat as int64
{
throw std::runtime_error("funcexp::evaluate(): non support datatype to set field.");
}
}
}
}
}

View File

@ -40,79 +40,80 @@
namespace execplan
{
class FunctionColumn;
class ArithmeticColumn;
class FunctionColumn;
class ArithmeticColumn;
}
namespace funcexp
{
class Func;
typedef std::tr1::unordered_map<std::string, Func*> FuncMap;
class Func;
typedef std::tr1::unordered_map<std::string, Func*> FuncMap;
/** @brief FuncExp is a component for evaluate function and expression filters
*/
class FuncExp {
public:
/** Singleton pattern */
static FuncExp* instance();
/********************************************************************
* Row based evaluation APIs
********************************************************************/
/** @brief evaluate a filter stack on row. used for F&E on the where clause
*
* @param row input row that contains all the columns in the filter stack
* @param filters parsetree of filters to evaluate
* @return boolean of whether or not the row passed evaluation
*/
inline bool evaluate(rowgroup::Row& row, execplan::ParseTree* filters);
/** @brief evaluate a filter stack on rowgroup
*
* @param row input rowgroup that contains all the columns in the filter stack
* @param filters parse tree of filters to evaluate. The failed rows are removed from the rowgroup
*/
inline void evaluate(rowgroup::RowGroup& rowgroup, execplan::ParseTree* filters);
/** @brief evaluate a F&E column on row. used for F&E on the select and group by clause
*
* @param row input row that contains all the columns in all the expressions
* @param expressions vector of F&Es that needs evaluation. The results are filled on the row.
*/
void evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressions);
/** @brief evaluate a F&E column on rowgroup. used for F&E on the select and group by clause
*
* @param row input rowgroup that contains all the columns in all the expressions
* @param expressions vector of F&Es that needs evaluation. The results are filled on each row.
*/
inline void evaluate(rowgroup::RowGroup& rowgroup, std::vector<execplan::SRCP>& expressions);
/** @brief get functor from functor map
*
* @param funcName function name
* @return functor pointer. If non-support function, return NULL
*/
Func* getFunctor(std::string& funcName);
class FuncExp
{
public:
/** Singleton pattern */
static FuncExp* instance();
/********************************************************************
* Row based evaluation APIs
********************************************************************/
/** @brief evaluate a filter stack on row. used for F&E on the where clause
*
* @param row input row that contains all the columns in the filter stack
* @param filters parsetree of filters to evaluate
* @return boolean of whether or not the row passed evaluation
*/
inline bool evaluate(rowgroup::Row& row, execplan::ParseTree* filters);
/** @brief evaluate a filter stack on rowgroup
*
* @param row input rowgroup that contains all the columns in the filter stack
* @param filters parse tree of filters to evaluate. The failed rows are removed from the rowgroup
*/
inline void evaluate(rowgroup::RowGroup& rowgroup, execplan::ParseTree* filters);
/** @brief evaluate a F&E column on row. used for F&E on the select and group by clause
*
* @param row input row that contains all the columns in all the expressions
* @param expressions vector of F&Es that needs evaluation. The results are filled on the row.
*/
void evaluate(rowgroup::Row& row, std::vector<execplan::SRCP>& expressions);
/** @brief evaluate a F&E column on rowgroup. used for F&E on the select and group by clause
*
* @param row input rowgroup that contains all the columns in all the expressions
* @param expressions vector of F&Es that needs evaluation. The results are filled on each row.
*/
inline void evaluate(rowgroup::RowGroup& rowgroup, std::vector<execplan::SRCP>& expressions);
/** @brief get functor from functor map
*
* @param funcName function name
* @return functor pointer. If non-support function, return NULL
*/
Func* getFunctor(std::string& funcName);
private:
static FuncExp* fInstance;
static boost::mutex fInstanceMutex;
FuncMap fFuncMap;
FuncExp();
static FuncExp* fInstance;
static boost::mutex fInstanceMutex;
FuncMap fFuncMap;
FuncExp();
};
inline bool FuncExp::evaluate( rowgroup::Row& row, execplan::ParseTree* filters )
{
bool isNull = false;
return (filters->getBoolVal(row, isNull));
{
bool isNull = false;
return (filters->getBoolVal(row, isNull));
}
inline void FuncExp::evaluate( rowgroup::RowGroup& rowgroup, execplan::ParseTree* filters )
{
{
}
}

Some files were not shown because too many files have changed in this diff Show More