You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
Basic SELECT support for Decimal38
This commit is contained in:
committed by
Roman Nozdrin
parent
63dcaa387f
commit
77e1d6abe3
@ -223,11 +223,10 @@ void ColumnDef::convertDecimal()
|
|||||||
fType->fType = DDL_BIGINT;
|
fType->fType = DDL_BIGINT;
|
||||||
fType->fLength = 8;
|
fType->fLength = 8;
|
||||||
}
|
}
|
||||||
else if (fType->fPrecision > 19 && fType->fPrecision <39)
|
else if (fType->fPrecision > 18 && fType->fPrecision < 39)
|
||||||
{
|
{
|
||||||
fType->fType = DDL_BINARY;
|
fType->fType = DDL_BINARY;
|
||||||
fType->fLength = 16;
|
fType->fLength = 16;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
@ -247,6 +247,9 @@ void force_close_fep_conn(THD *thd, cal_connection_info* ci, bool check_prev_rc
|
|||||||
ci->cal_conn_hndl = 0;
|
ci->cal_conn_hndl = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WIP MCOL-641
|
||||||
|
using uint128_t = unsigned __int128;
|
||||||
|
|
||||||
void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType& ct)
|
void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType& ct)
|
||||||
{
|
{
|
||||||
// unset null bit first
|
// unset null bit first
|
||||||
@ -801,15 +804,24 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h
|
|||||||
case CalpontSystemCatalog::DECIMAL:
|
case CalpontSystemCatalog::DECIMAL:
|
||||||
case CalpontSystemCatalog::UDECIMAL:
|
case CalpontSystemCatalog::UDECIMAL:
|
||||||
{
|
{
|
||||||
|
// WIP MCOL-641
|
||||||
if (row.getPrecision(s) > 18)
|
if (row.getPrecision(s) > 18)
|
||||||
{
|
{
|
||||||
sscanf(row.getBinaryField(s).c_str(), "%ld",&intColVal);
|
// unset null bit first
|
||||||
|
if ((*f)->null_ptr)
|
||||||
|
*(*f)->null_ptr &= ~(*f)->null_bit;
|
||||||
|
|
||||||
|
const uint128_t val = *reinterpret_cast<const uint128_t*>(row.getBinaryField2(s));
|
||||||
|
char buf[256];
|
||||||
|
dataconvert::DataConvert::decimalToString(val, (unsigned)colType.scale, buf, 256, colType.colDataType);
|
||||||
|
Field_new_decimal* f2 = (Field_new_decimal*)*f;
|
||||||
|
f2->store(buf, strlen(buf), f2->charset());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
intColVal = row.getIntField(s);
|
intColVal = row.getIntField(s);
|
||||||
|
storeNumericField(f, intColVal, colType);
|
||||||
}
|
}
|
||||||
storeNumericField(f, intColVal, colType);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1629,7 +1629,6 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in,
|
|||||||
memcpy(argVals[argIndex],args->val, W);
|
memcpy(argVals[argIndex],args->val, W);
|
||||||
regex[argIndex].used = false;
|
regex[argIndex].used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1639,7 +1638,6 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in,
|
|||||||
|
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
|
|
||||||
// if((*((uint64_t *) (bval))) != 0)
|
// if((*((uint64_t *) (bval))) != 0)
|
||||||
// {
|
// {
|
||||||
// cout << "rid "<< rid << " value ";
|
// cout << "rid "<< rid << " value ";
|
||||||
|
@ -1172,7 +1172,8 @@ struct uint128_pod
|
|||||||
uint64_t hi;
|
uint64_t hi;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void toString(uint128_t i, char *p)
|
// WIP MCOL-641
|
||||||
|
void DataConvert::toString(unsigned __int128 i, char *p)
|
||||||
{
|
{
|
||||||
uint64_t div = 10000000000000000000ULL;
|
uint64_t div = 10000000000000000000ULL;
|
||||||
size_t div_log = 19;
|
size_t div_log = 19;
|
||||||
@ -1191,7 +1192,7 @@ inline void toString(uint128_t i, char *p)
|
|||||||
|
|
||||||
// WIP replace snprintf with streams
|
// WIP replace snprintf with streams
|
||||||
if (high_pod->lo != 0) {
|
if (high_pod->lo != 0) {
|
||||||
printed_chars = snprintf(p, div_log+1, "%ld", high_pod->lo);
|
printed_chars = snprintf(p, div_log+1, "%lu", high_pod->lo);
|
||||||
p += printed_chars;
|
p += printed_chars;
|
||||||
printed_chars = snprintf(p, div_log+1, "%019lu", mid_pod->lo);
|
printed_chars = snprintf(p, div_log+1, "%019lu", mid_pod->lo);
|
||||||
p += printed_chars;
|
p += printed_chars;
|
||||||
@ -1199,10 +1200,11 @@ inline void toString(uint128_t i, char *p)
|
|||||||
printed_chars = snprintf(p, div_log+1, "%lu", mid_pod->lo);
|
printed_chars = snprintf(p, div_log+1, "%lu", mid_pod->lo);
|
||||||
p += printed_chars;
|
p += printed_chars;
|
||||||
}
|
}
|
||||||
snprintf(p, div_log+1, "%019ld", low_pod->lo);
|
snprintf(p, div_log+1, "%019lu", low_pod->lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// WIP MCOL-641
|
||||||
// Template this
|
// Template this
|
||||||
// result must be calloc-ed
|
// result must be calloc-ed
|
||||||
void atoi_(const string &arg, int128_t &res, size_t &size)
|
void atoi_(const string &arg, int128_t &res, size_t &size)
|
||||||
@ -1211,7 +1213,7 @@ void atoi_(const string &arg, int128_t &res, size_t &size)
|
|||||||
//char buf[40];
|
//char buf[40];
|
||||||
//int128_t *res_ptr = reinterpret_cast<int128_t*>(result);
|
//int128_t *res_ptr = reinterpret_cast<int128_t*>(result);
|
||||||
res = 0;
|
res = 0;
|
||||||
for (int j = 0; j < arg.size(); j++)
|
for (size_t j = 0; j < arg.size(); j++)
|
||||||
{
|
{
|
||||||
// WIP
|
// WIP
|
||||||
res = res*10 + arg[j] - '0';
|
res = res*10 + arg[j] - '0';
|
||||||
@ -1222,6 +1224,69 @@ void atoi_(const string &arg, int128_t &res, size_t &size)
|
|||||||
size = 16;
|
size = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WIP MCOL-641
|
||||||
|
void DataConvert::decimalToString(unsigned __int128 int_val, uint8_t scale, char* buf, unsigned int buflen,
|
||||||
|
execplan::CalpontSystemCatalog::ColDataType colDataType)
|
||||||
|
{
|
||||||
|
toString(int_val, buf);
|
||||||
|
|
||||||
|
// Biggest ColumnStore supports is DECIMAL(38,x), or 38 total digits+dp+sign for column
|
||||||
|
|
||||||
|
if (scale == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//we want to move the last scale chars right by one spot to insert the dp
|
||||||
|
//we want to move the trailing null as well, so it's really scale+1 chars
|
||||||
|
size_t l1 = strlen(buf);
|
||||||
|
char* ptr = &buf[0];
|
||||||
|
|
||||||
|
if (int_val < 0)
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
idbassert(l1 >= 2);
|
||||||
|
l1--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//need to make sure we have enough leading zeros for this to work...
|
||||||
|
//at this point scale is always > 0
|
||||||
|
size_t l2 = 1;
|
||||||
|
|
||||||
|
if ((unsigned)scale > l1)
|
||||||
|
{
|
||||||
|
const char* zeros = "00000000000000000000000000000000000000"; //38 0's
|
||||||
|
size_t diff = 0;
|
||||||
|
|
||||||
|
if (int_val != 0)
|
||||||
|
diff = scale - l1; //this will always be > 0
|
||||||
|
else
|
||||||
|
diff = scale;
|
||||||
|
|
||||||
|
memmove((ptr + diff), ptr, l1 + 1); //also move null
|
||||||
|
memcpy(ptr, zeros, diff);
|
||||||
|
|
||||||
|
if (int_val != 0)
|
||||||
|
l1 = 0;
|
||||||
|
else
|
||||||
|
l1 = 1;
|
||||||
|
}
|
||||||
|
else if ((unsigned)scale == l1)
|
||||||
|
{
|
||||||
|
l1 = 0;
|
||||||
|
l2 = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l1 -= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove((ptr + l1 + l2), (ptr + l1), scale + 1); //also move null
|
||||||
|
|
||||||
|
if (l2 == 2)
|
||||||
|
*(ptr + l1++) = '0';
|
||||||
|
|
||||||
|
*(ptr + l1) = '.';
|
||||||
|
}
|
||||||
|
|
||||||
boost::any
|
boost::any
|
||||||
DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType,
|
DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType,
|
||||||
const std::string& dataOrig, bool& pushWarning, const std::string& timeZone, bool nulFlag, bool noRoundup, bool isUpdate)
|
const std::string& dataOrig, bool& pushWarning, const std::string& timeZone, bool nulFlag, bool noRoundup, bool isUpdate)
|
||||||
|
@ -1011,6 +1011,8 @@ public:
|
|||||||
EXPORT static bool isNullData(execplan::ColumnResult* cr, int rownum, execplan::CalpontSystemCatalog::ColType colType);
|
EXPORT static bool isNullData(execplan::ColumnResult* cr, int rownum, execplan::CalpontSystemCatalog::ColType colType);
|
||||||
static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
||||||
static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
||||||
|
EXPORT static void decimalToString(unsigned __int128 value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
||||||
|
EXPORT static void toString(unsigned __int128 i, char *p);
|
||||||
static inline std::string constructRegexp(const std::string& str);
|
static inline std::string constructRegexp(const std::string& str);
|
||||||
static inline void trimWhitespace(int64_t& charData);
|
static inline void trimWhitespace(int64_t& charData);
|
||||||
static inline bool isEscapedChar(char c)
|
static inline bool isEscapedChar(char c)
|
||||||
|
@ -435,6 +435,7 @@ public:
|
|||||||
inline void setVarBinaryField(const uint8_t* val, uint32_t len, uint32_t colIndex);
|
inline void setVarBinaryField(const uint8_t* val, uint32_t len, uint32_t colIndex);
|
||||||
|
|
||||||
inline std::string getBinaryField(uint32_t colIndex) const;
|
inline std::string getBinaryField(uint32_t colIndex) const;
|
||||||
|
inline const uint8_t* getBinaryField2(uint32_t colIndex) const;
|
||||||
|
|
||||||
inline boost::shared_ptr<mcsv1sdk::UserData> getUserData(uint32_t colIndex) const;
|
inline boost::shared_ptr<mcsv1sdk::UserData> getUserData(uint32_t colIndex) const;
|
||||||
inline void setUserData(mcsv1sdk::mcsv1Context& context,
|
inline void setUserData(mcsv1sdk::mcsv1Context& context,
|
||||||
@ -835,6 +836,12 @@ inline std::string Row::getBinaryField(uint32_t colIndex) const
|
|||||||
return std::string((char*) &data[offsets[colIndex]], getColumnWidth(colIndex));
|
return std::string((char*) &data[offsets[colIndex]], getColumnWidth(colIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WIP MCOL-641
|
||||||
|
inline const uint8_t* Row::getBinaryField2(uint32_t colIndex) const
|
||||||
|
{
|
||||||
|
return &data[offsets[colIndex]];
|
||||||
|
}
|
||||||
|
|
||||||
inline std::string Row::getVarBinaryStringField(uint32_t colIndex) const
|
inline std::string Row::getVarBinaryStringField(uint32_t colIndex) const
|
||||||
{
|
{
|
||||||
if (inStringTable(colIndex))
|
if (inStringTable(colIndex))
|
||||||
|
@ -456,13 +456,12 @@ uint8_t WE_DDLCommandProc::writeCreateSyscolumn(ByteStream& bs, std::string& err
|
|||||||
if (dataType == CalpontSystemCatalog::DECIMAL ||
|
if (dataType == CalpontSystemCatalog::DECIMAL ||
|
||||||
dataType == CalpontSystemCatalog::UDECIMAL)
|
dataType == CalpontSystemCatalog::UDECIMAL)
|
||||||
{
|
{
|
||||||
if (colDefPtr->fType->fPrecision > 18) //@Bug 5717 precision cannot be over 18.
|
// WIP MCOL-641
|
||||||
|
if (colDefPtr->fType->fPrecision > 38) // precision cannot be over 38.
|
||||||
{
|
{
|
||||||
// WIP MCOL-641
|
ostringstream os;
|
||||||
//ostringstream os;
|
os << "Syntax error: The maximum precision (total number of digits) that can be specified is 38";
|
||||||
//os << "Syntax error: The maximum precision (total number of digits) that can be specified is 18";
|
throw std::runtime_error(os.str());
|
||||||
//throw std::runtime_error(os.str());
|
|
||||||
colDefPtr->convertDecimal();
|
|
||||||
}
|
}
|
||||||
else if (colDefPtr->fType->fPrecision < colDefPtr->fType->fScale)
|
else if (colDefPtr->fType->fPrecision < colDefPtr->fType->fScale)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user