2012-08-22 20:29:01 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/IAST.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Interpreters/HashSet.h>
|
|
|
|
|
#include <DB/Interpreters/Aggregator.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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:
|
2012-08-23 20:22:44 +00:00
|
|
|
|
Set() : type(EMPTY), log(&Logger::get("Set")) {}
|
|
|
|
|
bool empty() { return type == EMPTY; }
|
|
|
|
|
|
|
|
|
|
/** Создать множество по потоку блоков (для подзапроса). */
|
|
|
|
|
void create(BlockInputStreamPtr stream);
|
|
|
|
|
|
|
|
|
|
/** Создать множество по выражению (для перечисления в самом запросе). */
|
2012-08-23 22:40:51 +00:00
|
|
|
|
void create(ASTPtr node); // TODO
|
2012-08-23 20:22:44 +00:00
|
|
|
|
|
|
|
|
|
/** Для указанных столбцов блока проверить принадлежность их значений множеству.
|
|
|
|
|
* Записать результат в столбец в позиции result.
|
|
|
|
|
*/
|
|
|
|
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result, bool negative) const;
|
|
|
|
|
|
|
|
|
|
private:
|
2012-08-22 20:29:01 +00:00
|
|
|
|
/** Разные структуры данных, которые могут использоваться для проверки принадлежности
|
|
|
|
|
* одного или нескольких столбцов значений множеству.
|
|
|
|
|
*/
|
|
|
|
|
typedef std::set<Row> SetGeneric;
|
|
|
|
|
typedef HashSet<UInt64> SetUInt64;
|
|
|
|
|
typedef HashSet<StringRef, StringRefHash, StringRefZeroTraits> SetString;
|
|
|
|
|
typedef HashSet<UInt128, UInt128Hash, UInt128ZeroTraits> SetHashed;
|
2012-08-23 20:22:44 +00:00
|
|
|
|
|
2012-08-22 20:29:01 +00:00
|
|
|
|
/// Наиболее общий вариант. Самый медленный. На данный момент, не используется.
|
|
|
|
|
SetGeneric generic;
|
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда есть один числовой ключ (не с плавающей запятой).
|
|
|
|
|
SetUInt64 key64;
|
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда есть один строковый ключ.
|
|
|
|
|
SetString key_string;
|
|
|
|
|
StringPool string_pool;
|
|
|
|
|
|
|
|
|
|
/** Сравнивает 128 битные хэши.
|
|
|
|
|
* Если все ключи фиксированной длины, влезающие целиком в 128 бит, то укладывает их без изменений в 128 бит.
|
|
|
|
|
* Иначе - вычисляет md5 от набора из всех ключей.
|
|
|
|
|
* (При этом, строки, содержащие нули посередине, могут склеиться.)
|
2012-08-23 20:22:44 +00:00
|
|
|
|
*/
|
2012-08-22 20:29:01 +00:00
|
|
|
|
SetHashed hashed;
|
|
|
|
|
|
|
|
|
|
enum Type
|
|
|
|
|
{
|
|
|
|
|
EMPTY = 0,
|
|
|
|
|
GENERIC = 1,
|
|
|
|
|
KEY_64 = 2,
|
|
|
|
|
KEY_STRING = 3,
|
|
|
|
|
HASHED = 4,
|
|
|
|
|
};
|
|
|
|
|
Type type;
|
2012-08-23 22:40:51 +00:00
|
|
|
|
|
|
|
|
|
/** Типы данных, из которых было создано множество.
|
|
|
|
|
* При проверке на принадлежность множеству, типы проверяемых столбцов должны с ними совпадать.
|
|
|
|
|
*/
|
|
|
|
|
DataTypes data_types;
|
2012-08-23 20:22:44 +00:00
|
|
|
|
|
|
|
|
|
Logger * log;
|
|
|
|
|
|
|
|
|
|
typedef std::vector<size_t> Sizes;
|
2012-08-23 22:27:10 +00:00
|
|
|
|
static Type chooseMethod(Columns & key_columns, bool & keys_fit_128_bits, Sizes & key_sizes);
|
2012-08-22 20:29:01 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef SharedPtr<Set> SetPtr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|