1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

A joint patch fixing MCOL-4618 and MCOL-4653:

- MCOL-4618 FLOOR(-9999.0) returns a bad result
- MCOL-4653 CEIL(negativeNarrowDecimal) returns a wrong result

Main changes:
a. Moving ROUND, CEIL, FLOOR related code into a new simple
   class template DecomposedDecimal, which is reused for
   64 and 128 bit decimal.
b. Using DecomposedDecimal in TDecimal64 and TDecimal128
   to implement ROUND, CEIL, FLOOR related methods.
c. Adding corresponding wrapper methods to the class Decimal.
d. Using new Decimal methods in Func_ceil and Func_floor.

Additional minor changed:
- Adding "explicit" to TSInt128 constructors to avoid
  hidden data type conversion and erroneous choice between
  64 vs 128 bit APIs when using Decimal.
  Now one can call constructors in this self explanatory way:
  - Decimal(TSInt128(some_int_value), scale, precision)
    to create a wide decimal
  - Decimal(TSInt64(some_int_value, scale, precision)
    to create a narrow decimal

  TODO:
  Consider changing
    Decimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128 = 0)
  to
    Decimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128)
  (or even removing this constructor) to disallow compilation of:
    Decimal(some_trivial_type_value, scale, precision)
This commit is contained in:
Alexander Barkov
2021-03-31 13:11:08 +04:00
parent dd48eeb1ff
commit e19096a91a
7 changed files with 238 additions and 115 deletions

View File

@ -97,22 +97,7 @@ int64_t Func_ceil::getIntVal(Row& row,
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
{
ret = static_cast<int64_t>(d.getRoundedIntegralPart());
}
else
{
int64_t tmp = d.value;
d.value /= helpers::powerOf10_c[d.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (d.value * helpers::powerOf10_c[d.scale])) > 0)
d.value += 1;
ret = d.value;
}
ret = d.toSInt64Ceil();
}
}
break;
@ -240,22 +225,7 @@ uint64_t Func_ceil::getUintVal(Row& row,
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
{
ret = static_cast<uint64_t>(d.getRoundedIntegralPart());
}
else
{
int64_t tmp = d.value;
d.value /= helpers::powerOf10_c[d.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (d.value * helpers::powerOf10_c[d.scale])) > 0)
d.value += 1;
ret = (uint64_t) d.value;
}
ret = d.toUInt64Ceil();
}
}
break;
@ -562,23 +532,7 @@ IDB_Decimal Func_ceil::getDecimalVal(Row& row,
<< " with scale " << (int) ret.scale << " is beyond supported scale";
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
if (op_ct.colWidth == datatypes::MAXDECIMALWIDTH)
{
ret = IDB_Decimal(ret.getRoundedIntegralPart(),
ret.scale,
ret.precision);
}
else
{
int64_t tmp = ret.value;
ret.value /= helpers::powerOf10_c[ret.scale];
// Add 1 if this is a positive number and there were values to the right of the
// decimal point so that we return the largest integer value not less than X.
if ((tmp - (ret.value * helpers::powerOf10_c[ret.scale])) > 0)
ret.value += 1;
}
return ret.ceil();
}
}
break;