1#pragma once
2
3#include <Columns/IColumn.h>
4#include <Interpreters/BloomFilter.h>
5#include <Storages/MergeTree/KeyCondition.h>
6#include <Storages/MergeTree/MergeTreeIndices.h>
7#include <Storages/MergeTree/MergeTreeIndexGranuleBloomFilter.h>
8
9namespace DB
10{
11
12class MergeTreeIndexConditionBloomFilter : public IMergeTreeIndexCondition
13{
14public:
15 struct RPNElement
16 {
17 enum Function
18 {
19 /// Atoms of a Boolean expression.
20 FUNCTION_EQUALS,
21 FUNCTION_NOT_EQUALS,
22 FUNCTION_HAS,
23 FUNCTION_IN,
24 FUNCTION_NOT_IN,
25 FUNCTION_UNKNOWN, /// Can take any value.
26 /// Operators of the logical expression.
27 FUNCTION_NOT,
28 FUNCTION_AND,
29 FUNCTION_OR,
30 /// Constants
31 ALWAYS_FALSE,
32 ALWAYS_TRUE,
33 };
34
35 RPNElement(Function function_ = FUNCTION_UNKNOWN) : function(function_) {}
36
37 Function function = FUNCTION_UNKNOWN;
38 std::vector<std::pair<size_t, ColumnPtr>> predicate;
39 };
40
41 MergeTreeIndexConditionBloomFilter(const SelectQueryInfo & info_, const Context & context_, const Block & header_, size_t hash_functions_);
42
43 bool alwaysUnknownOrTrue() const override;
44
45 bool mayBeTrueOnGranule(MergeTreeIndexGranulePtr granule) const override
46 {
47 if (const auto & bf_granule = typeid_cast<const MergeTreeIndexGranuleBloomFilter *>(granule.get()))
48 return mayBeTrueOnGranule(bf_granule);
49
50 throw Exception("LOGICAL ERROR: require bloom filter index granule.", ErrorCodes::LOGICAL_ERROR);
51 }
52
53private:
54 const Block & header;
55 const Context & context;
56 const SelectQueryInfo & query_info;
57 const size_t hash_functions;
58 std::vector<RPNElement> rpn;
59
60 SetPtr getPreparedSet(const ASTPtr & node);
61
62 bool mayBeTrueOnGranule(const MergeTreeIndexGranuleBloomFilter * granule) const;
63
64 bool traverseAtomAST(const ASTPtr & node, Block & block_with_constants, RPNElement & out);
65
66 bool traverseASTIn(const String & function_name, const ASTPtr & key_ast, const SetPtr & prepared_set, RPNElement & out);
67
68 bool traverseASTIn(
69 const String & function_name, const ASTPtr & key_ast, const DataTypePtr & type, const ColumnPtr & column, RPNElement & out);
70
71 bool traverseASTEquals(
72 const String & function_name, const ASTPtr & key_ast, const DataTypePtr & value_type, const Field & value_field, RPNElement & out);
73};
74
75}
76