You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
MCOL-641 Add support for functions (Part 2).
This commit is contained in:
committed by
Roman Nozdrin
parent
bd0d5af123
commit
6aea838360
@ -56,8 +56,12 @@ bool getUIntValFromParm(
|
||||
const execplan::SPTP& parm,
|
||||
uint64_t& value,
|
||||
bool& isNull,
|
||||
const string& timeZone)
|
||||
const string& timeZone,
|
||||
bool& isBigVal,
|
||||
int128_t& bigval)
|
||||
{
|
||||
isBigVal = false;
|
||||
|
||||
switch (parm->data()->resultType().colDataType)
|
||||
{
|
||||
case execplan::CalpontSystemCatalog::BIGINT:
|
||||
@ -104,10 +108,12 @@ bool getUIntValFromParm(
|
||||
|
||||
if (parm->data()->resultType().colWidth == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
isBigVal = true;
|
||||
|
||||
if (parm->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL &&
|
||||
d.value < 0)
|
||||
{
|
||||
value = 0;
|
||||
bigval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -126,12 +132,7 @@ bool getUIntValFromParm(
|
||||
if (tmpval < 0 && lefto < -4)
|
||||
tmpval--;
|
||||
|
||||
if (tmpval > static_cast<int128_t>(INT64_MAX))
|
||||
tmpval = INT64_MAX;
|
||||
else if (tmpval < static_cast<int128_t>(INT64_MIN))
|
||||
tmpval = INT64_MIN;
|
||||
|
||||
value = tmpval;
|
||||
bigval = tmpval;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -229,15 +230,39 @@ int64_t Func_bitand::getIntVal(Row& row,
|
||||
uint64_t val1 = 0;
|
||||
uint64_t val2 = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
|
||||
int128_t bigval1 = 0;
|
||||
int128_t bigval2 = 0;
|
||||
bool isBigVal1;
|
||||
bool isBigVal2;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
return val1 & val2;
|
||||
if (LIKELY(!isBigVal1 && !isBigVal2))
|
||||
{
|
||||
return val1 & val2;
|
||||
}
|
||||
|
||||
// Type promotion to int128_t
|
||||
if (!isBigVal1)
|
||||
bigval1 = val1;
|
||||
|
||||
if (!isBigVal2)
|
||||
bigval2 = val2;
|
||||
|
||||
int128_t res = bigval1 & bigval2;
|
||||
|
||||
if (res > static_cast<int128_t>(UINT64_MAX))
|
||||
res = UINT64_MAX;
|
||||
else if (res < static_cast<int128_t>(INT64_MIN))
|
||||
res = INT64_MIN;
|
||||
|
||||
return (int64_t) res;
|
||||
}
|
||||
|
||||
|
||||
@ -265,15 +290,39 @@ int64_t Func_leftshift::getIntVal(Row& row,
|
||||
uint64_t val1 = 0;
|
||||
uint64_t val2 = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
|
||||
int128_t bigval1 = 0;
|
||||
int128_t bigval2 = 0;
|
||||
bool isBigVal1;
|
||||
bool isBigVal2;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "leftshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
return val1 << val2;
|
||||
if (LIKELY(!isBigVal1 && !isBigVal2))
|
||||
{
|
||||
return val1 << val2;
|
||||
}
|
||||
|
||||
// Type promotion to int128_t
|
||||
if (!isBigVal1)
|
||||
bigval1 = val1;
|
||||
|
||||
if (!isBigVal2)
|
||||
bigval2 = val2;
|
||||
|
||||
int128_t res = bigval1 << bigval2;
|
||||
|
||||
if (res > static_cast<int128_t>(UINT64_MAX))
|
||||
res = UINT64_MAX;
|
||||
else if (res < static_cast<int128_t>(INT64_MIN))
|
||||
res = INT64_MIN;
|
||||
|
||||
return (int64_t) res;
|
||||
}
|
||||
|
||||
|
||||
@ -301,15 +350,39 @@ int64_t Func_rightshift::getIntVal(Row& row,
|
||||
uint64_t val1 = 0;
|
||||
uint64_t val2 = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
|
||||
int128_t bigval1 = 0;
|
||||
int128_t bigval2 = 0;
|
||||
bool isBigVal1;
|
||||
bool isBigVal2;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "rightshift: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
return val1 >> val2;
|
||||
if (LIKELY(!isBigVal1 && !isBigVal2))
|
||||
{
|
||||
return val1 >> val2;
|
||||
}
|
||||
|
||||
// Type promotion to int128_t
|
||||
if (!isBigVal1)
|
||||
bigval1 = val1;
|
||||
|
||||
if (!isBigVal2)
|
||||
bigval2 = val2;
|
||||
|
||||
int128_t res = bigval1 >> bigval2;
|
||||
|
||||
if (res > static_cast<int128_t>(UINT64_MAX))
|
||||
res = UINT64_MAX;
|
||||
else if (res < static_cast<int128_t>(INT64_MIN))
|
||||
res = INT64_MIN;
|
||||
|
||||
return (int64_t) res;
|
||||
}
|
||||
|
||||
|
||||
@ -337,15 +410,39 @@ int64_t Func_bitor::getIntVal(Row& row,
|
||||
uint64_t val1 = 0;
|
||||
uint64_t val2 = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
|
||||
int128_t bigval1 = 0;
|
||||
int128_t bigval2 = 0;
|
||||
bool isBigVal1;
|
||||
bool isBigVal2;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "bitor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
return val1 | val2;
|
||||
if (LIKELY(!isBigVal1 && !isBigVal2))
|
||||
{
|
||||
return val1 | val2;
|
||||
}
|
||||
|
||||
// Type promotion to int128_t
|
||||
if (!isBigVal1)
|
||||
bigval1 = val1;
|
||||
|
||||
if (!isBigVal2)
|
||||
bigval2 = val2;
|
||||
|
||||
int128_t res = bigval1 | bigval2;
|
||||
|
||||
if (res > static_cast<int128_t>(UINT64_MAX))
|
||||
res = UINT64_MAX;
|
||||
else if (res < static_cast<int128_t>(INT64_MIN))
|
||||
res = INT64_MIN;
|
||||
|
||||
return (int64_t) res;
|
||||
}
|
||||
|
||||
uint64_t Func_bitor::getUintVal(rowgroup::Row& row,
|
||||
@ -381,15 +478,39 @@ int64_t Func_bitxor::getIntVal(Row& row,
|
||||
uint64_t val1 = 0;
|
||||
uint64_t val2 = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone()) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone()))
|
||||
int128_t bigval1 = 0;
|
||||
int128_t bigval2 = 0;
|
||||
bool isBigVal1;
|
||||
bool isBigVal2;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val1, isNull, timeZone(), isBigVal1, bigval1) ||
|
||||
!getUIntValFromParm(row, parm[1], val2, isNull, timeZone(), isBigVal2, bigval2))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
return val1 ^ val2;
|
||||
if (LIKELY(!isBigVal1 && !isBigVal2))
|
||||
{
|
||||
return val1 ^ val2;
|
||||
}
|
||||
|
||||
// Type promotion to int128_t
|
||||
if (!isBigVal1)
|
||||
bigval1 = val1;
|
||||
|
||||
if (!isBigVal2)
|
||||
bigval2 = val2;
|
||||
|
||||
int128_t res = bigval1 ^ bigval2;
|
||||
|
||||
if (res > static_cast<int128_t>(UINT64_MAX))
|
||||
res = UINT64_MAX;
|
||||
else if (res < static_cast<int128_t>(INT64_MIN))
|
||||
res = INT64_MIN;
|
||||
|
||||
return (int64_t) res;
|
||||
}
|
||||
|
||||
|
||||
@ -403,6 +524,20 @@ CalpontSystemCatalog::ColType Func_bit_count::operationType( FunctionParm& fp, C
|
||||
return resultType;
|
||||
}
|
||||
|
||||
inline int64_t bitCount(uint64_t val)
|
||||
{
|
||||
// Refer to Hacker's Delight Chapter 5
|
||||
// for the bit counting algo used here
|
||||
val = val - ((val >> 1) & 0x5555555555555555);
|
||||
val = (val & 0x3333333333333333) + ((val >> 2) & 0x3333333333333333);
|
||||
val = (val + (val >> 4)) & 0x0F0F0F0F0F0F0F0F;
|
||||
val = val + (val >> 8);
|
||||
val = val + (val >> 16);
|
||||
val = val + (val >> 32);
|
||||
|
||||
return (int64_t)(val & 0x000000000000007F);
|
||||
}
|
||||
|
||||
int64_t Func_bit_count::getIntVal(Row& row,
|
||||
FunctionParm& parm,
|
||||
bool& isNull,
|
||||
@ -416,24 +551,25 @@ int64_t Func_bit_count::getIntVal(Row& row,
|
||||
|
||||
uint64_t val = 0;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val, isNull, timeZone()))
|
||||
int128_t bigval = 0;
|
||||
bool isBigVal;
|
||||
|
||||
if (!getUIntValFromParm(row, parm[0], val, isNull, timeZone(), isBigVal, bigval))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "bit_count: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
|
||||
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
// Refer to Hacker's Delight Chapter 5
|
||||
// for the bit counting algo used here
|
||||
val = val - ((val >> 1) & 0x5555555555555555);
|
||||
val = (val & 0x3333333333333333) + ((val >> 2) & 0x3333333333333333);
|
||||
val = (val + (val >> 4)) & 0x0F0F0F0F0F0F0F0F;
|
||||
val = val + (val >> 8);
|
||||
val = val + (val >> 16);
|
||||
val = val + (val >> 32);
|
||||
|
||||
return (int64_t)(val & 0x000000000000007F);
|
||||
|
||||
if (LIKELY(!isBigVal))
|
||||
{
|
||||
return bitCount(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bitCount(*reinterpret_cast<uint64_t*>(&bigval)) +
|
||||
bitCount(*(reinterpret_cast<uint64_t*>(&bigval) + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user