2012-08-22 20:29:01 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <set>
|
|
|
|
|
|
2012-09-05 19:51:09 +00:00
|
|
|
|
#include <Yandex/logger_useful.h>
|
|
|
|
|
|
2012-08-23 23:49:28 +00:00
|
|
|
|
#include <DB/Core/ColumnNumbers.h>
|
2013-02-08 19:34:44 +00:00
|
|
|
|
#include <DB/Common/Arena.h>
|
2012-08-23 23:49:28 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/DataStreams/IBlockInputStream.h>
|
|
|
|
|
|
2012-08-22 20:29:01 +00:00
|
|
|
|
#include <DB/Parsers/IAST.h>
|
|
|
|
|
|
2014-04-28 01:48:24 +00:00
|
|
|
|
#include <DB/Common/HashTable/HashSet.h>
|
2012-08-23 23:49:28 +00:00
|
|
|
|
#include <DB/Interpreters/AggregationCommon.h>
|
2013-06-20 12:12:27 +00:00
|
|
|
|
#include <DB/Interpreters/Limits.h>
|
2013-03-25 13:02:12 +00:00
|
|
|
|
#include <DB/Columns/ColumnConst.h>
|
|
|
|
|
#include <DB/Columns/ColumnArray.h>
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
2014-03-26 18:19:25 +00:00
|
|
|
|
#include <DB/Storages/MergeTree/BoolMask.h>
|
2014-03-31 14:49:43 +00:00
|
|
|
|
#include <DB/Storages/MergeTree/PKCondition.h>
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Структура данных для реализации выражения IN.
|
|
|
|
|
*/
|
2012-08-23 22:40:51 +00:00
|
|
|
|
class Set
|
2012-08-22 20:29:01 +00:00
|
|
|
|
{
|
2012-08-23 22:40:51 +00:00
|
|
|
|
public:
|
2014-07-06 19:48:39 +00:00
|
|
|
|
Set(const Limits & limits) :
|
2014-05-15 10:24:03 +00:00
|
|
|
|
log(&Logger::get("Set")),
|
2013-06-20 12:12:27 +00:00
|
|
|
|
max_rows(limits.max_rows_in_set),
|
|
|
|
|
max_bytes(limits.max_bytes_in_set),
|
|
|
|
|
overflow_mode(limits.set_overflow_mode)
|
|
|
|
|
{
|
|
|
|
|
}
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2012-08-23 20:22:44 +00:00
|
|
|
|
bool empty() { return type == EMPTY; }
|
|
|
|
|
|
2012-08-24 19:42:03 +00:00
|
|
|
|
/** Создать множество по выражению (для перечисления в самом запросе).
|
|
|
|
|
* types - типы того, что стоит слева от IN.
|
|
|
|
|
* node - это список значений: 1, 2, 3 или список tuple-ов: (1, 2), (3, 4), (5, 6).
|
2014-04-08 12:54:32 +00:00
|
|
|
|
* create_ordered_set - создавать ли вектор упорядоченных элементов. Нужен для работы индекса
|
2012-08-24 19:42:03 +00:00
|
|
|
|
*/
|
2014-04-01 10:09:22 +00:00
|
|
|
|
void createFromAST(DataTypes & types, ASTPtr node, bool create_ordered_set);
|
2014-03-04 11:26:55 +00:00
|
|
|
|
|
|
|
|
|
// Возвращает false, если превышено какое-нибудь ограничение, и больше не нужно вставлять.
|
2015-01-27 00:52:03 +00:00
|
|
|
|
bool insertFromBlock(const Block & block, bool create_ordered_set = false);
|
2014-03-04 11:26:55 +00:00
|
|
|
|
|
2015-01-27 00:52:03 +00:00
|
|
|
|
/// Считает суммарное число ключей во всех Set'ах
|
|
|
|
|
size_t getTotalRowCount() const;
|
|
|
|
|
/// Считает суммарный размер в байтах буфферов всех Set'ов + размер string_pool'а
|
|
|
|
|
size_t getTotalByteCount() const;
|
2012-08-23 20:22:44 +00:00
|
|
|
|
|
|
|
|
|
/** Для указанных столбцов блока проверить принадлежность их значений множеству.
|
|
|
|
|
* Записать результат в столбец в позиции result.
|
|
|
|
|
*/
|
|
|
|
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result, bool negative) const;
|
2014-03-26 10:56:21 +00:00
|
|
|
|
|
2014-04-01 10:25:56 +00:00
|
|
|
|
std::string describe()
|
2014-03-26 10:56:21 +00:00
|
|
|
|
{
|
2014-04-08 12:54:32 +00:00
|
|
|
|
if (!ordered_set_elements)
|
2014-03-26 10:56:21 +00:00
|
|
|
|
return "{}";
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2014-04-01 10:09:22 +00:00
|
|
|
|
bool first = true;
|
|
|
|
|
std::stringstream ss;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2014-04-07 17:43:50 +00:00
|
|
|
|
ss << "{";
|
2014-04-08 12:54:32 +00:00
|
|
|
|
for (const Field & f : *ordered_set_elements)
|
2014-04-01 10:09:22 +00:00
|
|
|
|
{
|
2014-05-12 00:45:50 +00:00
|
|
|
|
ss << (first ? "" : ", ") << apply_visitor(FieldVisitorToString(), f);
|
2014-04-01 10:09:22 +00:00
|
|
|
|
first = false;
|
2014-03-26 18:19:25 +00:00
|
|
|
|
}
|
2014-04-07 17:43:50 +00:00
|
|
|
|
ss << "}";
|
2014-04-01 10:09:22 +00:00
|
|
|
|
return ss.str();
|
2014-03-26 10:56:21 +00:00
|
|
|
|
}
|
2014-04-01 10:09:22 +00:00
|
|
|
|
|
2014-04-08 12:54:32 +00:00
|
|
|
|
/// проверяет есть ли в Set элементы для заданного диапазона индекса
|
2014-04-01 10:09:22 +00:00
|
|
|
|
BoolMask mayBeTrueInRange(const Range & range);
|
2014-06-18 20:08:31 +00:00
|
|
|
|
|
|
|
|
|
enum Type
|
|
|
|
|
{
|
|
|
|
|
EMPTY = 0,
|
|
|
|
|
KEY_64 = 1,
|
|
|
|
|
KEY_STRING = 2,
|
|
|
|
|
HASHED = 3,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static Type chooseMethod(const ConstColumnPlainPtrs & key_columns, bool & keys_fit_128_bits, Sizes & key_sizes);
|
|
|
|
|
|
2012-08-23 20:22:44 +00:00
|
|
|
|
private:
|
2012-08-22 20:29:01 +00:00
|
|
|
|
/** Разные структуры данных, которые могут использоваться для проверки принадлежности
|
|
|
|
|
* одного или нескольких столбцов значений множеству.
|
|
|
|
|
*/
|
|
|
|
|
typedef HashSet<UInt64> SetUInt64;
|
2014-05-10 02:42:45 +00:00
|
|
|
|
typedef HashSetWithSavedHash<StringRef> SetString;
|
2014-04-28 01:48:24 +00:00
|
|
|
|
typedef HashSet<UInt128, UInt128Hash> SetHashed;
|
2012-08-23 20:22:44 +00:00
|
|
|
|
|
2013-06-21 19:25:53 +00:00
|
|
|
|
/// Специализация для случая, когда есть один числовой ключ.
|
2014-04-28 01:48:24 +00:00
|
|
|
|
std::unique_ptr<SetUInt64> key64;
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда есть один строковый ключ.
|
2014-04-28 01:48:24 +00:00
|
|
|
|
std::unique_ptr<SetString> key_string;
|
2013-02-08 19:34:44 +00:00
|
|
|
|
Arena string_pool;
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
|
|
|
|
/** Сравнивает 128 битные хэши.
|
|
|
|
|
* Если все ключи фиксированной длины, влезающие целиком в 128 бит, то укладывает их без изменений в 128 бит.
|
2012-10-07 06:30:10 +00:00
|
|
|
|
* Иначе - вычисляет SipHash от набора из всех ключей.
|
2012-08-22 20:29:01 +00:00
|
|
|
|
* (При этом, строки, содержащие нули посередине, могут склеиться.)
|
2012-08-23 20:22:44 +00:00
|
|
|
|
*/
|
2014-04-28 01:48:24 +00:00
|
|
|
|
std::unique_ptr<SetHashed> hashed;
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
2014-04-28 01:48:24 +00:00
|
|
|
|
Type type = EMPTY;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2013-03-25 13:02:12 +00:00
|
|
|
|
bool keys_fit_128_bits;
|
|
|
|
|
Sizes key_sizes;
|
2012-08-23 22:40:51 +00:00
|
|
|
|
|
|
|
|
|
/** Типы данных, из которых было создано множество.
|
|
|
|
|
* При проверке на принадлежность множеству, типы проверяемых столбцов должны с ними совпадать.
|
|
|
|
|
*/
|
|
|
|
|
DataTypes data_types;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2012-08-23 20:22:44 +00:00
|
|
|
|
Logger * log;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2013-06-20 12:12:27 +00:00
|
|
|
|
/// Ограничения на максимальный размер множества
|
|
|
|
|
size_t max_rows;
|
|
|
|
|
size_t max_bytes;
|
2014-02-17 23:56:45 +00:00
|
|
|
|
OverflowMode overflow_mode;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2014-04-28 01:48:24 +00:00
|
|
|
|
void init(Type type_)
|
|
|
|
|
{
|
|
|
|
|
type = type_;
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case EMPTY: break;
|
|
|
|
|
case KEY_64: key64 .reset(new SetUInt64); break;
|
|
|
|
|
case KEY_STRING: key_string .reset(new SetString); break;
|
|
|
|
|
case HASHED: hashed .reset(new SetHashed); break;
|
|
|
|
|
|
|
|
|
|
default:
|
2014-06-12 01:22:49 +00:00
|
|
|
|
throw Exception("Unknown Set variant.", ErrorCodes::UNKNOWN_AGGREGATED_DATA_VARIANT);
|
2014-04-28 01:48:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-19 12:25:59 +00:00
|
|
|
|
/// Если в левой части IN стоит массив. Проверяем, что хоть один элемент массива лежит в множестве.
|
2013-03-25 13:02:12 +00:00
|
|
|
|
void executeConstArray(const ColumnConstArray * key_column, ColumnUInt8::Container_t & vec_res, bool negative) const;
|
|
|
|
|
void executeArray(const ColumnArray * key_column, ColumnUInt8::Container_t & vec_res, bool negative) const;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2013-03-19 12:25:59 +00:00
|
|
|
|
/// Если в левой части набор столбцов тех же типов, что элементы множества.
|
|
|
|
|
void executeOrdinary(const ConstColumnPlainPtrs & key_columns, ColumnUInt8::Container_t & vec_res, bool negative) const;
|
2014-07-06 19:48:39 +00:00
|
|
|
|
|
2013-06-20 12:12:27 +00:00
|
|
|
|
/// Проверить не превышены ли допустимые размеры множества ключей
|
|
|
|
|
bool checkSetSizeLimits() const;
|
2014-05-15 10:24:03 +00:00
|
|
|
|
|
2014-04-08 12:54:32 +00:00
|
|
|
|
/// вектор упорядоченных элементов Set
|
|
|
|
|
/// нужен для работы индекса по первичному ключу в секции In
|
|
|
|
|
typedef std::vector<Field> OrderedSetElements;
|
|
|
|
|
typedef std::unique_ptr<OrderedSetElements> OrderedSetElementsPtr;
|
|
|
|
|
OrderedSetElementsPtr ordered_set_elements;
|
2015-01-27 00:52:03 +00:00
|
|
|
|
|
|
|
|
|
/** Защищает работу с множеством в функциях insertFromBlock и execute.
|
|
|
|
|
* Эти функции могут вызываться одновременно из разных потоков только при использовании StorageSet,
|
|
|
|
|
* и StorageSet вызывает только эти две функции.
|
|
|
|
|
* Поэтому остальные функции по работе с множеством, не защинены.
|
|
|
|
|
*/
|
|
|
|
|
mutable Poco::RWLock rwlock;
|
2012-08-22 20:29:01 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-03-26 18:19:25 +00:00
|
|
|
|
typedef Poco::SharedPtr<Set> SetPtr;
|
2014-03-04 11:26:55 +00:00
|
|
|
|
typedef std::vector<SetPtr> Sets;
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|