sumMap: return types less prone to oveflows

It used to be that sumMap would return the same type as the values
columns. If columns of Array(UInt8) were to be given, that would really
easily cause oveflow. It now uses `getWidenDataType` (and ultimately
`NearestFieldType`) in order to define the result type.
This commit is contained in:
Léo Ercolanelli 2019-01-25 14:08:16 +01:00
parent d9195cda99
commit 0d6094a3ea
3 changed files with 21 additions and 1 deletions

View File

@ -72,7 +72,7 @@ public:
types.emplace_back(std::make_shared<DataTypeArray>(keys_type));
for (const auto & value_type : values_types)
types.emplace_back(std::make_shared<DataTypeArray>(value_type));
types.emplace_back(std::make_shared<DataTypeArray>(widenDataType(value_type)));
return std::make_shared<DataTypeTuple>(types);
}
@ -260,6 +260,16 @@ public:
const char * getHeaderFilePath() const override { return __FILE__; }
bool keepKey(const T & key) const { return static_cast<const Derived &>(*this).keepKey(key); }
private:
static DataTypePtr widenDataType(const DataTypePtr & data_type)
{
if (!data_type->canBeWiden())
throw new Exception{"Values to be summed are expected to be Numeric, Float or Decimal.",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
return data_type->getWidenDataType();
}
};
template <typename T>

View File

@ -10,6 +10,7 @@
2000-01-01 00:01:00 [4,5,6,7,8] [10,10,20,10,10]
([1],[10])
([1,4,8],[10,20,10])
([1],[257])
([1],[1])
([1],[1])
(['a'],[1])

View File

@ -17,6 +17,15 @@ SELECT sumMapFiltered([1, 4, 8])(statusMap.status, statusMap.requests) FROM test
DROP TABLE test.sum_map;
DROP TABLE IF EXISTS test.sum_map_overflow;
CREATE TABLE test.sum_map_overflow(events Array(UInt8), counts Array(UInt8)) ENGINE = Log;
INSERT INTO test.sum_map_overflow VALUES ([1], [255]), ([1], [2]);
SELECT sumMap(events, counts) FROM test.sum_map_overflow;
DROP TABLE test.sum_map_overflow;
select sumMap(val, cnt) from ( SELECT [ CAST(1, 'UInt64') ] as val, [1] as cnt );
select sumMap(val, cnt) from ( SELECT [ CAST(1, 'Float64') ] as val, [1] as cnt );
select sumMap(val, cnt) from ( SELECT [ CAST('a', 'Enum16(\'a\'=1)') ] as val, [1] as cnt );