From eaa8a75a6359ebf28cb0a81d7efa7f8543ad3ef8 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Fri, 21 Nov 2014 17:07:25 +0300 Subject: [PATCH] dbms: prohibit narrow-width integral types for determinator of quantile(s)Deterministic. [#METR-13199] --- .../ReservoirSamplerDeterministic.h | 6 +++-- .../AggregateFunctionFactory.cpp | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/dbms/include/DB/AggregateFunctions/ReservoirSamplerDeterministic.h b/dbms/include/DB/AggregateFunctions/ReservoirSamplerDeterministic.h index 0eb33672605..3ebaa3fca0c 100644 --- a/dbms/include/DB/AggregateFunctions/ReservoirSamplerDeterministic.h +++ b/dbms/include/DB/AggregateFunctions/ReservoirSamplerDeterministic.h @@ -22,6 +22,7 @@ namespace detail { const size_t DEFAULT_SAMPLE_COUNT = 8192; +const auto MAX_SKIP_DEGREE = sizeof(UInt32) * 8; } /// Что делать, если нет ни одного значения - кинуть исключение, или вернуть 0 или NaN в случае double? @@ -66,9 +67,10 @@ public: void insertImpl(const T & v, const UInt32 hash) { - if (samples.size() == sample_count) + while (samples.size() + 1 >= sample_count) { - ++skip_degree; + if (++skip_degree > detail::MAX_SKIP_DEGREE) + throw DB::Exception{"skip_degree exceeds maximum value", DB::ErrorCodes::MEMORY_LIMIT_EXCEEDED}; thinOut(); } diff --git a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp index 14f72537281..d278d88c4d4 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp +++ b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp @@ -331,6 +331,19 @@ AggregateFunctionPtr AggregateFunctionFactory::get(const String & name, const Da if (argument_types.size() != 2) throw Exception("Incorrect number of arguments for aggregate function " + name, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + const auto determinator_type = argument_types[1].get(); + if (!typeid_cast(determinator_type) && + !typeid_cast(determinator_type) && + !typeid_cast(determinator_type) && + !typeid_cast(determinator_type)) + { + throw Exception{ + "Illegal type " + determinator_type->getName() + " of second argument for aggregate function " + name + + ", Int32, UInt32, Int64 or UInt64 required", + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT + }; + } + const IDataType & argument_type = *argument_types[0]; if (typeid_cast(&argument_type)) return new AggregateFunctionQuantileDeterministic; @@ -353,6 +366,19 @@ AggregateFunctionPtr AggregateFunctionFactory::get(const String & name, const Da if (argument_types.size() != 2) throw Exception("Incorrect number of arguments for aggregate function " + name, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + const auto determinator_type = argument_types[1].get(); + if (!typeid_cast(determinator_type) && + !typeid_cast(determinator_type) && + !typeid_cast(determinator_type) && + !typeid_cast(determinator_type)) + { + throw Exception{ + "Illegal type " + determinator_type->getName() + " of second argument for aggregate function " + name + + ", Int32, UInt32, Int64 or UInt64 required", + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT + }; + } + const IDataType & argument_type = *argument_types[0]; if (typeid_cast(&argument_type)) return new AggregateFunctionQuantilesDeterministic;