1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-08 14:22:09 +03:00

MCOL-641 This commit introduces templates for DataConvert and RowGroup methods.

This commit is contained in:
drrtuy
2020-01-21 12:57:31 +03:00
committed by Roman Nozdrin
parent 0c67b6ab50
commit 54c152d6c8
9 changed files with 111 additions and 37 deletions

View File

@@ -625,6 +625,12 @@ void SimpleColumn::evaluate(Row& row, bool& isNull)
{
switch (fResultType.colWidth)
{
case 16:
{
fResult.decimalVal.value = row.getIntField<16>(fInputIndex);
fResult.decimalVal.scale = (unsigned)fResultType.scale;
break;
}
case 1:
{
fResult.decimalVal.value = row.getIntField<1>(fInputIndex);

View File

@@ -36,6 +36,8 @@
#include "exceptclasses.h"
#include "dataconvert.h"
using uint128_t = unsigned __int128;
namespace messageqcpp
{
class ByteStream;
@@ -61,7 +63,7 @@ typedef execplan::CalpontSystemCatalog::ColType Type;
*/
struct IDB_Decimal
{
IDB_Decimal(): value(0), scale(0), precision(0) {}
IDB_Decimal(): val(0), value(0), scale(0), precision(0) {}
IDB_Decimal(int64_t val, int8_t s, uint8_t p) :
value (val),
scale(s),
@@ -149,9 +151,10 @@ struct IDB_Decimal
return (decimalComp(rhs) != 0);
}
uint128_t val;
int64_t value;
int8_t scale; // 0~18
uint8_t precision; // 1~18
int8_t scale; // 0~38
uint8_t precision; // 1~38
};
typedef IDB_Decimal CNX_Decimal;

View File

@@ -3106,13 +3106,14 @@ CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item)
{
Item_decimal* idp = (Item_decimal*)item;
ct.colDataType = CalpontSystemCatalog::DECIMAL;
ct.colWidth = 8;
// MCOL-641 WIP Make this dynamic
ct.colWidth = (idp->max_length >= 18) ? 16 : 8;
ct.scale = idp->decimals;
if (ct.scale == 0)
ct.precision = idp->max_length - 1;
ct.precision = (idp->max_length > 38) ? 38 : idp->max_length - 1;
else
ct.precision = idp->max_length - idp->decimals;
ct.precision = (idp->max_length > 38) ? 38 : idp->max_length - idp->decimals;
break;
}
@@ -3599,10 +3600,8 @@ ArithmeticColumn* buildArithmeticColumn(
pt->right(rhs);
}
//aop->resultType(colType_MysqlToIDB(item));
// @bug5715. Use InfiniDB adjusted coltype for result type.
// decimal arithmetic operation gives double result when the session variable is set.
//idbassert(pt->left() && pt->right() && pt->left()->data() && pt->right()->data());
CalpontSystemCatalog::ColType mysql_type = colType_MysqlToIDB(item);
if (get_double_for_decimal_math(current_thd) == true)

View File

@@ -145,6 +145,8 @@ extern bool nonConstFunc(Item_func* ifp);
namespace
{
using int128_t = __int128;
using uint128_t = unsigned __int128;
// Calpont vtable non-support error message
const string infinidb_autoswitch_warning = "The query includes syntax that is not supported by MariaDB Columnstore distributed mode. The execution was switched to standard mode with downgraded performance.";
@@ -247,9 +249,6 @@ void force_close_fep_conn(THD *thd, cal_connection_info* ci, bool check_prev_rc
ci->cal_conn_hndl = 0;
}
// WIP MCOL-641
using uint128_t = unsigned __int128;
void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType& ct)
{
// unset null bit first
@@ -268,6 +267,8 @@ void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType&
//if (f2->dec < ct.scale)
// f2->dec = ct.scale;
// WIP MCOL-641
// This is too much
char buf[256];
dataconvert::DataConvert::decimalToString(value, (unsigned)ct.scale, buf, 256, ct.colDataType);
(*f)->store(buf, strlen(buf), (*f)->charset());
@@ -808,12 +809,33 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h
if (row.getPrecision(s) > 18)
{
// unset null bit first
// Might be redundant
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);
uint128_t* udec;
int128_t* dec;
// We won't have more than 38 digits + sign + dp
// Make this precision based
char buf[41];
// This C-style cast doesn't look appropriate.
// Is there a way to use decltype instead of if?
if (colType.colDataType == CalpontSystemCatalog::DECIMAL)
{
dec = row.getBinaryField<int128_t>(s);
dataconvert::DataConvert::decimalToString<int128_t>(dec,
(unsigned)colType.scale, buf,
sizeof(buf), colType.colDataType);
}
else
{
udec = row.getBinaryField<uint128_t>(s);
dataconvert::DataConvert::decimalToString<uint128_t>(udec,
(unsigned)colType.scale, buf,
sizeof(buf), colType.colDataType);
}
Field_new_decimal* f2 = (Field_new_decimal*)*f;
f2->store(buf, strlen(buf), f2->charset());
}