#pragma once #include #include #include #include #include #include #include #include #include #include #include #include constexpr auto INDEX_FILE_PREFIX = "skp_idx_"; namespace DB { class MergeTreeData; class IMergeTreeIndex; using MergeTreeIndexPtr = std::shared_ptr; using MutableMergeTreeIndexPtr = std::shared_ptr; /// Stores some info about a single block of data. struct IMergeTreeIndexGranule { virtual ~IMergeTreeIndexGranule() = default; virtual void serializeBinary(WriteBuffer & ostr) const = 0; virtual void deserializeBinary(ReadBuffer & istr) = 0; virtual bool empty() const = 0; }; using MergeTreeIndexGranulePtr = std::shared_ptr; using MergeTreeIndexGranules = std::vector; /// Aggregates info about a single block of data. struct IMergeTreeIndexAggregator { virtual ~IMergeTreeIndexAggregator() = default; virtual bool empty() const = 0; virtual MergeTreeIndexGranulePtr getGranuleAndReset() = 0; /// Updates the stored info using rows of the specified block. /// Reads no more than `limit` rows. /// After finishing updating `pos` will store the position of the first row which was not read. virtual void update(const Block & block, size_t * pos, size_t limit) = 0; }; using MergeTreeIndexAggregatorPtr = std::shared_ptr; using MergeTreeIndexAggregators = std::vector; /// Condition on the index. class IMergeTreeIndexCondition { public: virtual ~IMergeTreeIndexCondition() = default; /// Checks if this index is useful for query. virtual bool alwaysUnknownOrTrue() const = 0; virtual bool mayBeTrueOnGranule(MergeTreeIndexGranulePtr granule) const = 0; }; using MergeTreeIndexConditionPtr = std::shared_ptr; /// Structure for storing basic index info like columns, expression, arguments, ... class IMergeTreeIndex { public: IMergeTreeIndex(const IndexDescription & index_) : index(index_) { } virtual ~IMergeTreeIndex() = default; /// gets filename without extension String getFileName() const { return INDEX_FILE_PREFIX + index.name; } /// Checks whether the column is in data skipping index. virtual bool mayBenefitFromIndexForIn(const ASTPtr & node) const = 0; virtual MergeTreeIndexGranulePtr createIndexGranule() const = 0; virtual MergeTreeIndexAggregatorPtr createIndexAggregator() const = 0; virtual MergeTreeIndexConditionPtr createIndexCondition( const SelectQueryInfo & query_info, const Context & context) const = 0; Names getColumnsRequiredForIndexCalc() const { return index.expression->getRequiredColumns(); } const IndexDescription & index; }; using MergeTreeIndices = std::vector; class MergeTreeIndexFactory : private boost::noncopyable { public: static MergeTreeIndexFactory & instance(); using Creator = std::function< std::shared_ptr( const IndexDescription & index)>; using Validator = std::function; void validate(const IndexDescription & index, bool attach) const; std::shared_ptr get(const IndexDescription & index) const; MergeTreeIndices getMany(const std::vector & indices) const; void registerCreator(const std::string & index_type, Creator creator); void registerValidator(const std::string & index_type, Validator creator); protected: MergeTreeIndexFactory(); private: using Creators = std::unordered_map; using Validators = std::unordered_map; Creators creators; Validators validators; }; std::shared_ptr minmaxIndexCreator( const IndexDescription & index); void minmaxIndexValidator(const IndexDescription & index, bool attach); std::shared_ptr setIndexCreator( const IndexDescription & index); void setIndexValidator(const IndexDescription & index, bool attach); std::shared_ptr bloomFilterIndexCreator( const IndexDescription & index); void bloomFilterIndexValidator(const IndexDescription & index, bool attach); std::shared_ptr bloomFilterIndexCreatorNew( const IndexDescription & index); void bloomFilterIndexValidatorNew(const IndexDescription & index, bool attach); }