You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-01 06:46:55 +03:00
MCOL-641 1. Implement int128 version of strtoll.
2. Templatize number_int_value. 3. Add test cases for strtoll128 and number_int_value for Decimal38.
This commit is contained in:
committed by
Roman Nozdrin
parent
b29d0c9daa
commit
8f80c1dee6
@ -50,6 +50,9 @@
|
||||
#include "calpontsystemcatalog.h"
|
||||
#include "columnresult.h"
|
||||
#include "exceptclasses.h"
|
||||
#include "common/branchpred.h"
|
||||
|
||||
#include "widedecimalutils.h"
|
||||
|
||||
// remove this block if the htonll is defined in library
|
||||
#ifdef __linux__
|
||||
@ -822,8 +825,8 @@ void TimeStamp::reset()
|
||||
second = 0xFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
inline
|
||||
int64_t string_to_ll( const std::string& data, bool& bSaturate )
|
||||
template<typename T=int64_t>
|
||||
inline T string_to_ll( const std::string& data, bool& bSaturate )
|
||||
{
|
||||
// This function doesn't take into consideration our special values
|
||||
// for NULL and EMPTY when setting the saturation point. Should it?
|
||||
@ -870,6 +873,13 @@ uint64_t string_to_ull( const std::string& data, bool& bSaturate )
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void number_int_value(const std::string& data,
|
||||
const execplan::CalpontSystemCatalog::ColType& ct,
|
||||
bool& pushwarning,
|
||||
bool noRoundup,
|
||||
T& intVal);
|
||||
|
||||
/** @brief DataConvert is a component for converting string data to Calpont format
|
||||
*/
|
||||
class DataConvert
|
||||
@ -1044,9 +1054,7 @@ public:
|
||||
const uint8_t scale);
|
||||
template <typename T>
|
||||
static size_t writeFractionalPart(T* dec, char* p,
|
||||
const uint16_t buflen, const uint8_t scale);
|
||||
|
||||
|
||||
const uint16_t buflen, const uint8_t scale);
|
||||
|
||||
static inline void int128Max(int128_t& i)
|
||||
{
|
||||
@ -1465,6 +1473,107 @@ inline std::string DataConvert::constructRegexp(const std::string& str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int128_t add128(int128_t a, int128_t b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
inline int128_t subtract128(int128_t a, int128_t b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
inline bool lessThan128(int128_t a, int128_t b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
inline bool greaterThan128(int128_t a, int128_t b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
// Naive __int128 version of strtoll
|
||||
inline int128_t strtoll128(const char* data, bool& saturate, char** ep)
|
||||
{
|
||||
int128_t res = 0;
|
||||
|
||||
if (*data == '\0')
|
||||
{
|
||||
if (ep)
|
||||
*ep = (char*)data;
|
||||
return res;
|
||||
}
|
||||
|
||||
// skip leading whitespace characters
|
||||
while (*data != '\0' &&
|
||||
(*data == ' ' || *data == '\t' || *data == '\n'))
|
||||
data++;
|
||||
|
||||
int128_t (*op)(int128_t, int128_t);
|
||||
op = add128;
|
||||
bool (*compare)(int128_t, int128_t);
|
||||
compare = lessThan128;
|
||||
|
||||
// check the -ve sign
|
||||
bool is_neg = false;
|
||||
if (*data == '-')
|
||||
{
|
||||
is_neg = true;
|
||||
op = subtract128;
|
||||
compare = greaterThan128;
|
||||
data++;
|
||||
}
|
||||
|
||||
int128_t tmp;
|
||||
|
||||
for (; *data != '\0' && isdigit(*data); data++)
|
||||
{
|
||||
tmp = op(res*10, *data - '0');
|
||||
|
||||
if (UNLIKELY(compare(tmp, res)))
|
||||
{
|
||||
saturate = true;
|
||||
|
||||
if (is_neg)
|
||||
utils::int128Min(res);
|
||||
else
|
||||
utils::int128Max(res);
|
||||
|
||||
while (*data != '\0' && isdigit(*data))
|
||||
data++;
|
||||
|
||||
if (ep)
|
||||
*ep = (char*)data;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
if (ep)
|
||||
*ep = (char*)data;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int128_t string_to_ll<int128_t> ( const std::string& data, bool& bSaturate )
|
||||
{
|
||||
// This function doesn't take into consideration our special values
|
||||
// for NULL and EMPTY when setting the saturation point. Should it?
|
||||
char* ep = NULL;
|
||||
const char* str = data.c_str();
|
||||
int128_t value = strtoll128(str, bSaturate, &ep);
|
||||
|
||||
// (no digits) || (more chars)
|
||||
if ((ep == str) || (*ep != '\0'))
|
||||
throw logging::QueryDataExcept("value is not numerical.", logging::formatErr);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace dataconvert
|
||||
|
||||
#undef EXPORT
|
||||
|
Reference in New Issue
Block a user