You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-27 21:01:50 +03:00
MCOL-641 Implement int128_t versions of arithmetic operations and add unit test cases.
This commit is contained in:
committed by
Roman Nozdrin
parent
b5534eb847
commit
554c6da8e8
@ -3105,17 +3105,13 @@ CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item)
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
Item_decimal* idp = (Item_decimal*)item;
|
||||
|
||||
ct.colDataType = CalpontSystemCatalog::DECIMAL;
|
||||
ct.colWidth = (idp->max_length >= datatypes::INT64MAXPRECISION)
|
||||
? datatypes::MAXDECIMALWIDTH : utils::MAXLEGACYWIDTH;
|
||||
ct.scale = idp->decimals;
|
||||
// WIP MCOL-641
|
||||
if (ct.scale == 0)
|
||||
ct.precision = (idp->max_length > datatypes::INT128MAXPRECISION)
|
||||
? datatypes::INT128MAXPRECISION : idp->max_length - 1;
|
||||
else
|
||||
ct.precision = (idp->max_length > datatypes::INT128MAXPRECISION )
|
||||
? datatypes::INT128MAXPRECISION : idp->max_length - idp->decimals;
|
||||
|
||||
unsigned int precision = idp->decimal_precision();
|
||||
unsigned int scale = idp->decimal_scale();
|
||||
|
||||
datatypes::Decimal::setDecimalScalePrecision(ct, precision, scale);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -3141,7 +3137,7 @@ ReturnedColumn* buildReturnedColumn(
|
||||
{
|
||||
ReturnedColumn* rc = NULL;
|
||||
|
||||
if ( gwi.thd)
|
||||
if (gwi.thd)
|
||||
{
|
||||
//if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ))
|
||||
{
|
||||
@ -3444,6 +3440,7 @@ ArithmeticColumn* buildArithmeticColumn(
|
||||
Item** sfitempp = item->arguments();
|
||||
ArithmeticOperator* aop = new ArithmeticOperator(item->func_name());
|
||||
aop->timeZone(gwi.thd->variables.time_zone->get_name()->ptr());
|
||||
aop->setOverflowCheck(get_decimal_overflow_check(gwi.thd));
|
||||
ParseTree* pt = new ParseTree(aop);
|
||||
//ReturnedColumn *lhs = 0, *rhs = 0;
|
||||
ParseTree* lhs = 0, *rhs = 0;
|
||||
@ -3606,6 +3603,60 @@ ArithmeticColumn* buildArithmeticColumn(
|
||||
// decimal arithmetic operation gives double result when the session variable is set.
|
||||
CalpontSystemCatalog::ColType mysql_type = colType_MysqlToIDB(item);
|
||||
|
||||
if (mysql_type.colDataType == CalpontSystemCatalog::DECIMAL ||
|
||||
mysql_type.colDataType == CalpontSystemCatalog::UDECIMAL)
|
||||
{
|
||||
int32_t leftColWidth = pt->left()->data()->resultType().colWidth;
|
||||
int32_t rightColWidth = pt->right()->data()->resultType().colWidth;
|
||||
|
||||
// Revert back to legacy values of scale and precision
|
||||
// if the 2 columns involved in the expression are not wide
|
||||
if (leftColWidth <= utils::MAXLEGACYWIDTH &&
|
||||
rightColWidth <= utils::MAXLEGACYWIDTH)
|
||||
{
|
||||
Item_decimal* idp = (Item_decimal*)item;
|
||||
|
||||
mysql_type.colWidth = 8;
|
||||
|
||||
unsigned int precision = idp->max_length;
|
||||
unsigned int scale = idp->decimals;
|
||||
|
||||
datatypes::Decimal::setDecimalScalePrecisionLegacy(mysql_type, precision, scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (leftColWidth == datatypes::MAXDECIMALWIDTH ||
|
||||
rightColWidth == datatypes::MAXDECIMALWIDTH)
|
||||
mysql_type.colWidth = datatypes::MAXDECIMALWIDTH;
|
||||
|
||||
if (mysql_type.colWidth == datatypes::MAXDECIMALWIDTH)
|
||||
{
|
||||
string funcName = item->func_name();
|
||||
|
||||
int32_t scale1 = pt->left()->data()->resultType().scale;
|
||||
int32_t scale2 = pt->right()->data()->resultType().scale;
|
||||
|
||||
if (funcName == "/" &&
|
||||
(mysql_type.scale - (scale1 - scale2)) > datatypes::INT128MAXPRECISION)
|
||||
{
|
||||
Item_decimal* idp = (Item_decimal*)item;
|
||||
|
||||
unsigned int precision = idp->decimal_precision();
|
||||
unsigned int scale = idp->decimal_scale();
|
||||
|
||||
datatypes::Decimal::setDecimalScalePrecisionHeuristic(mysql_type, precision, scale);
|
||||
|
||||
if (mysql_type.scale < scale1)
|
||||
mysql_type.scale = scale1;
|
||||
|
||||
if (mysql_type.precision < mysql_type.scale)
|
||||
mysql_type.precision = mysql_type.scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_double_for_decimal_math(current_thd) == true)
|
||||
aop->adjustResultType(mysql_type);
|
||||
else
|
||||
|
@ -159,6 +159,15 @@ static MYSQL_THDVAR_BOOL(
|
||||
0
|
||||
);
|
||||
|
||||
static MYSQL_THDVAR_BOOL(
|
||||
decimal_overflow_check,
|
||||
PLUGIN_VAR_NOCMDARG,
|
||||
"Enable/disable for ColumnStore to check for overflow in arithmetic operation.",
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
static MYSQL_THDVAR_BOOL(
|
||||
ordered_only,
|
||||
PLUGIN_VAR_NOCMDARG,
|
||||
@ -353,6 +362,7 @@ st_mysql_sys_var* mcs_system_variables[] =
|
||||
MYSQL_SYSVAR(diskjoin_bucketsize),
|
||||
MYSQL_SYSVAR(um_mem_limit),
|
||||
MYSQL_SYSVAR(double_for_decimal_math),
|
||||
MYSQL_SYSVAR(decimal_overflow_check),
|
||||
MYSQL_SYSVAR(local_query),
|
||||
MYSQL_SYSVAR(use_import_for_batchinsert),
|
||||
MYSQL_SYSVAR(import_for_batchinsert_delimiter),
|
||||
@ -557,6 +567,15 @@ void set_double_for_decimal_math(THD* thd, bool value)
|
||||
THDVAR(thd, double_for_decimal_math) = value;
|
||||
}
|
||||
|
||||
bool get_decimal_overflow_check(THD* thd)
|
||||
{
|
||||
return ( thd == NULL ) ? false : THDVAR(thd, decimal_overflow_check);
|
||||
}
|
||||
void set_decimal_overflow_check(THD* thd, bool value)
|
||||
{
|
||||
THDVAR(thd, decimal_overflow_check) = value;
|
||||
}
|
||||
|
||||
ulong get_local_query(THD* thd)
|
||||
{
|
||||
return ( thd == NULL ) ? 0 : THDVAR(thd, local_query);
|
||||
|
@ -101,6 +101,9 @@ void set_varbin_always_hex(THD* thd, bool value);
|
||||
bool get_double_for_decimal_math(THD* thd);
|
||||
void set_double_for_decimal_math(THD* thd, bool value);
|
||||
|
||||
bool get_decimal_overflow_check(THD* thd);
|
||||
void set_decimal_overflow_check(THD* thd, bool value);
|
||||
|
||||
ulong get_local_query(THD* thd);
|
||||
void set_local_query(THD* thd, ulong value);
|
||||
|
||||
|
Reference in New Issue
Block a user