From 68c3879d956e5996e9ec39e91a5cd960475ebb88 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sat, 29 Dec 2018 14:12:41 +0300 Subject: [PATCH] index condition --- .../Storages/MergeTree/MergeTreeDataPart.h | 3 + .../MergeTree/MergeTreeDataSelectExecutor.cpp | 3 +- .../Storages/MergeTree/MergeTreeIndexes.cpp | 22 +++++++ .../src/Storages/MergeTree/MergeTreeIndexes.h | 65 ++++++++++++++----- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h index b277dfaa237..1ae6aa602d0 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -207,6 +208,8 @@ struct MergeTreeDataPart MinMaxIndex minmax_idx; + MergeTreeIndexParts index_parts; + Checksums checksums; /// Columns description. diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index dd5a35ad710..1e9613298dc 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -886,7 +886,8 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( Row index_left(used_key_size); Row index_right(used_key_size); - while (!ranges_stack.empty()) + while (!ranges_stack.empty())/// In other words, it removes subranges from whole range, that definitely could not contain required keys. + { MarkRange range = ranges_stack.back(); ranges_stack.pop_back(); diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexes.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexes.cpp index de665bedc5f..d181c0e0deb 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexes.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexes.cpp @@ -7,8 +7,30 @@ namespace ErrorCodes { extern const int LOGICAL_ERROR; extern const int INCORRECT_QUERY; + extern const int UNKNOWN_EXCEPTION; } +void MergeTreeIndexPart::update(const Block & block, const Names & column_names) { + updateImpl(block, column_names); +} + +void MergeTreeIndexPart::merge(const MergeTreeIndexPart & other) { + if (other.indexType() != indexType()) { + throw Exception("MergeTreeIndexPart: Merging index part with another index type.", + ErrorCodes::LOGICAL_ERROR); + } + mergeImpl(other); +} + +INDEX_TYPE MergeTreeIndexPart::indexType() const { + return owner->indexType(); +} + +INDEX_TYPE IndexCondition::indexType() const { + return owner->indexType(); +} + + void MergeTreeIndexFactory::registerIndex(const std::string &name, Creator creator) { if (!indexes.emplace(name, std::move(creator)).second) throw Exception("MergeTreeIndexFactory: the Index creator name '" + name + "' is not unique", diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexes.h b/dbms/src/Storages/MergeTree/MergeTreeIndexes.h index 4b150896a46..88f75b11e79 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexes.h +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexes.h @@ -6,42 +6,74 @@ #include #include #include +#include +#include #include #include namespace DB { -enum class INDEX_TYPES { +enum class INDEX_TYPE { NONE = 0 }; class MergeTreeIndex; +using MergeTreeIndexPtr = std::shared_ptr; +using MergeTreeIndexes = std::vector; + +/// Data structure storing some data for each MergeTreeDataPart struct MergeTreeIndexPart { friend MergeTreeIndex; public: - virtual ~MergeTreeIndexPart() {}; + virtual ~MergeTreeIndexPart() = default; - virtual void update(const Block & block, const Names & column_names) = 0; - virtual void merge(const MergeTreeIndexPart & other) = 0; + virtual INDEX_TYPE indexType() const; - virtual INDEX_TYPES indexType() const { - return INDEX_TYPES::NONE; - } + void update(const Block & block, const Names & column_names); + void merge(const MergeTreeIndexPart & other); protected: - MergeTreeIndexPart() {}; + MergeTreeIndexPart() = default; + + virtual void updateImpl(const Block & block, const Names & column_names) = 0; + virtual void mergeImpl(const MergeTreeIndexPart & other) = 0; + + MergeTreeIndexPtr owner; }; -using MergeTreeIndexPartPtr = std::unique_ptr; +using MergeTreeIndexPartPtr = std::shared_ptr; using MergeTreeIndexParts = std::vector; +/// Condition on the index. +class IndexCondition { + friend MergeTreeIndex; + +public: + virtual ~IndexCondition() = default; + + virtual INDEX_TYPE indexType() const; + + // methods like KeyCondition + virtual bool alwaysUnknownOrTrue() const = 0; + virtual bool maybeTrueInRange(const MarkRange & range) const = 0; + +protected: + IndexCondition() = default; + + MergeTreeIndexPtr owner; +}; + +using IndexConditionPtr = std::shared_ptr; + + +/// Structure for storing index info like columns, expression, arguments, ... class MergeTreeIndex { public: @@ -50,22 +82,19 @@ public: virtual ~MergeTreeIndex() {}; - virtual INDEX_TYPES indexType() const { - return INDEX_TYPES::NONE; - } - - virtual bool alwaysUnknownOrTrue() const = 0; - virtual bool maybeTrueOn(MergeTreeIndexPartPtr part) const = 0; + virtual INDEX_TYPE indexType() const = 0; virtual MergeTreeIndexPartPtr createEmptyIndexPart() const = 0; + virtual IndexConditionPtr createIndexCondition(const SelectQueryInfo & query_info, + const Context & context, + const Names & key_column_names, + const ExpressionActionsPtr & key_expr) const = 0; String name; ExpressionActionsPtr expr; Block sample; }; -using MergeTreeIndexPtr = std::unique_ptr; -using MergeTreeIndexes = std::vector; class MergeTreeIndexFactory : public ext::singleton { @@ -83,7 +112,7 @@ public: } protected: - MergeTreeIndexFactory() {}; + MergeTreeIndexFactory() = default; private: using Indexes = std::unordered_map;