You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
Fix regression in a query involving an aggregate function on a
non-wide decimal column in the HAVING clause. In buildAggregateColumn(), if an aggregate function (such as avg) is applied on a non-wide decimal column, we were setting the precision of the resulting column as -1. This later down in the execution got converted to 255 as in some cases, precision is stored as uint8_t. The predicate operations on a DECIMAL column has logic that uses the wide Decimal::s128value field if precision > 18. This logic incorrectly used the Decimal::s128value instead of the correct value stored in the narrow Decimal::value field, since precision of the Decimal column was 255. The fix is to set the aggregate column precision to datatypes::INT64MAXPRECISION (18) in buildAggregateColumn() when the aggregate is applied on a non-wide decimal column. This commit also partially fixes -Wstrict-aliasing GCC warnings.
This commit is contained in:
@ -85,8 +85,6 @@ constexpr uint8_t INT64MAXPRECISION = 18U;
|
|||||||
constexpr uint8_t INT128MAXPRECISION = 38U;
|
constexpr uint8_t INT128MAXPRECISION = 38U;
|
||||||
constexpr uint8_t MAXLEGACYWIDTH = 8U;
|
constexpr uint8_t MAXLEGACYWIDTH = 8U;
|
||||||
constexpr uint8_t MAXSCALEINC4AVG = 4U;
|
constexpr uint8_t MAXSCALEINC4AVG = 4U;
|
||||||
constexpr int8_t IGNOREPRECISION = -1;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint64_t mcs_pow_10[20] =
|
const uint64_t mcs_pow_10[20] =
|
||||||
|
@ -5068,7 +5068,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
|||||||
{
|
{
|
||||||
ct.scale += datatypes::MAXSCALEINC4AVG;
|
ct.scale += datatypes::MAXSCALEINC4AVG;
|
||||||
}
|
}
|
||||||
ct.precision = datatypes::IGNOREPRECISION;
|
ct.precision = datatypes::INT64MAXPRECISION;
|
||||||
}
|
}
|
||||||
ac->resultType(ct);
|
ac->resultType(ct);
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ class Hash128
|
|||||||
public:
|
public:
|
||||||
inline size_t operator()(const int128_t i) const
|
inline size_t operator()(const int128_t i) const
|
||||||
{
|
{
|
||||||
return *reinterpret_cast<const uint64_t*>(&i);
|
return (uint64_t)((int64_t) i);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,6 +105,27 @@ bool number_value ( const string& data )
|
|||||||
namespace dataconvert
|
namespace dataconvert
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// LE stands for Little Endian
|
||||||
|
uint32_t getUInt32LE(const char* ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const uint32_t*>(ptr)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getSInt32LE(const char* ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const int32_t*>(ptr)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getUInt64LE(const char* ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const uint64_t*>(ptr)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t getSInt64LE(const char* ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const int64_t*>(ptr)[0];
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void number_int_value(const string& data,
|
void number_int_value(const string& data,
|
||||||
cscDataType typeCode,
|
cscDataType typeCode,
|
||||||
@ -1627,7 +1648,7 @@ DataConvert::StringToDate(const std::string& data, bool& pushWarning)
|
|||||||
|
|
||||||
if (stringToDateStruct(data, aDay))
|
if (stringToDateStruct(data, aDay))
|
||||||
{
|
{
|
||||||
boost::any value = (*(reinterpret_cast<uint32_t*> (&aDay)));
|
boost::any value = getUInt32LE((const char*) &aDay);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
boost::any value = (uint32_t) 0;
|
boost::any value = (uint32_t) 0;
|
||||||
@ -1643,7 +1664,7 @@ DataConvert::StringToDatetime(const std::string& data, bool& pushWarning)
|
|||||||
|
|
||||||
if (stringToDatetimeStruct(data, aDatetime, 0)) // QQ: why 0?
|
if (stringToDatetimeStruct(data, aDatetime, 0)) // QQ: why 0?
|
||||||
{
|
{
|
||||||
boost::any value = *(reinterpret_cast<uint64_t*>(&aDatetime));
|
boost::any value = getUInt64LE((const char*) &aDatetime);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
boost::any value = (uint64_t) 0;
|
boost::any value = (uint64_t) 0;
|
||||||
@ -1664,7 +1685,7 @@ DataConvert::StringToTime(const datatypes::SystemCatalog::TypeAttributesStd& col
|
|||||||
pushWarning = true;
|
pushWarning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::any value = (int64_t) * (reinterpret_cast<int64_t*>(&aTime));
|
boost::any value = getSInt64LE((const char*) &aTime);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1681,7 +1702,7 @@ DataConvert::StringToTimestamp(const datatypes::ConvertFromStringParam &prm,
|
|||||||
pushWarning = true;
|
pushWarning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::any value = (uint64_t) *(reinterpret_cast<uint64_t*>(&aTimestamp));
|
boost::any value = getUInt64LE((const char*) &aTimestamp);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2448,7 +2469,10 @@ int64_t DataConvert::stringToDate(const string& data)
|
|||||||
Date aDay;
|
Date aDay;
|
||||||
|
|
||||||
if ( stringToDateStruct( data, aDay ) )
|
if ( stringToDateStruct( data, aDay ) )
|
||||||
return (((*(reinterpret_cast<uint32_t*> (&aDay))) & 0xFFFFFFC0) | 0x3E);
|
{
|
||||||
|
uint32_t temp = getUInt32LE((const char*) &aDay);
|
||||||
|
return ((temp & 0xFFFFFFC0) | 0x3E);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2458,7 +2482,7 @@ int64_t DataConvert::stringToDatetime(const string& data, bool* date)
|
|||||||
DateTime dtime;
|
DateTime dtime;
|
||||||
|
|
||||||
if ( stringToDatetimeStruct( data, dtime, date ) )
|
if ( stringToDatetimeStruct( data, dtime, date ) )
|
||||||
return *(reinterpret_cast<uint64_t*>(&dtime));
|
return getUInt64LE((const char*) &dtime);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2468,7 +2492,7 @@ int64_t DataConvert::stringToTimestamp(const string& data, const string& timeZon
|
|||||||
TimeStamp aTimestamp;
|
TimeStamp aTimestamp;
|
||||||
|
|
||||||
if ( stringToTimestampStruct( data, aTimestamp, timeZone ) )
|
if ( stringToTimestampStruct( data, aTimestamp, timeZone ) )
|
||||||
return *(reinterpret_cast<uint64_t*>(&aTimestamp));
|
return getUInt64LE((const char*) &aTimestamp);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2485,7 +2509,7 @@ int64_t DataConvert::intToDate(int64_t data)
|
|||||||
aday.year = 0;
|
aday.year = 0;
|
||||||
aday.month = 0;
|
aday.month = 0;
|
||||||
aday.day = 0;
|
aday.day = 0;
|
||||||
return *(reinterpret_cast<uint32_t*>(&aday));
|
return getUInt32LE((const char*) &aday);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
||||||
@ -2597,7 +2621,7 @@ int64_t DataConvert::intToDate(int64_t data)
|
|||||||
aday.year = y;
|
aday.year = y;
|
||||||
aday.month = m;
|
aday.month = m;
|
||||||
aday.day = d;
|
aday.day = d;
|
||||||
return *(reinterpret_cast<uint32_t*>(&aday));
|
return getUInt32LE((const char*) &aday);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is really painful and expensive b/c it seems the input is not normalized or
|
/* This is really painful and expensive b/c it seems the input is not normalized or
|
||||||
@ -2621,7 +2645,7 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
|||||||
if (date)
|
if (date)
|
||||||
*date = true;
|
*date = true;
|
||||||
|
|
||||||
return *(reinterpret_cast<uint64_t*>(&adaytime));
|
return getUInt64LE((const char*) &adaytime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
||||||
@ -2747,7 +2771,7 @@ int64_t DataConvert::intToDatetime(int64_t data, bool* date)
|
|||||||
if (date)
|
if (date)
|
||||||
*date = isDate;
|
*date = isDate;
|
||||||
|
|
||||||
return *(reinterpret_cast<uint64_t*>(&adaytime));
|
return getUInt64LE((const char*) &adaytime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is really painful and expensive b/c it seems the input is not normalized or
|
/* This is really painful and expensive b/c it seems the input is not normalized or
|
||||||
@ -2767,7 +2791,7 @@ int64_t DataConvert::intToTime(int64_t data, bool fromString)
|
|||||||
atime.msecond = 0;
|
atime.msecond = 0;
|
||||||
atime.is_neg = 0;
|
atime.is_neg = 0;
|
||||||
|
|
||||||
return *(reinterpret_cast<int64_t*>(&atime));
|
return getSInt64LE((const char*) &atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
// this snprintf call causes a compiler warning b/c we're potentially copying a 20-digit #
|
||||||
@ -2871,7 +2895,7 @@ int64_t DataConvert::intToTime(int64_t data, bool fromString)
|
|||||||
atime.msecond = ms;
|
atime.msecond = ms;
|
||||||
atime.is_neg = isNeg;
|
atime.is_neg = isNeg;
|
||||||
|
|
||||||
return *(reinterpret_cast<int64_t*>(&atime));
|
return getSInt64LE((const char*) &atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t DataConvert::stringToTime(const string& data)
|
int64_t DataConvert::stringToTime(const string& data)
|
||||||
@ -2991,7 +3015,7 @@ int64_t DataConvert::stringToTime(const string& data)
|
|||||||
atime.second = sec;
|
atime.second = sec;
|
||||||
atime.msecond = msec;
|
atime.msecond = msec;
|
||||||
atime.is_neg = isNeg;
|
atime.is_neg = isNeg;
|
||||||
return *(reinterpret_cast<int64_t*>(&atime));
|
return getSInt64LE((const char*) &atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user