aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Access/EnabledRowPolicies.cpp
blob: 8ab1bf5928b758a1698256614978ef3c2df35f08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <Access/EnabledRowPolicies.h>
#include <Parsers/makeASTForLogicalFunction.h>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>


namespace DB
{

bool RowPolicyFilter::empty() const
{
    bool value;
    return !expression || (tryGetLiteralBool(expression.get(), value) && value);
}

size_t EnabledRowPolicies::Hash::operator()(const MixedFiltersKey & key) const
{
    return std::hash<std::string_view>{}(key.database) - std::hash<std::string_view>{}(key.table_name) + static_cast<size_t>(key.filter_type);
}

EnabledRowPolicies::EnabledRowPolicies() : params()
{
}

EnabledRowPolicies::EnabledRowPolicies(const Params & params_) : params(params_)
{
}

EnabledRowPolicies::~EnabledRowPolicies() = default;


RowPolicyFilterPtr EnabledRowPolicies::getFilter(const String & database, const String & table_name, RowPolicyFilterType filter_type) const
{
    /// We don't lock `mutex` here.
    auto loaded = mixed_filters.load();
    auto it = loaded->find({database, table_name, filter_type});
    if (it == loaded->end())
    {   /// Look for a policy for database if a table policy not found
        it = loaded->find({database, RowPolicyName::ANY_TABLE_MARK, filter_type});
        if (it == loaded->end())
        {
            return {};
        }
    }

    return it->second;
}

RowPolicyFilterPtr EnabledRowPolicies::getFilter(const String & database, const String & table_name, RowPolicyFilterType filter_type, RowPolicyFilterPtr combine_with_filter) const
{
    RowPolicyFilterPtr filter = getFilter(database, table_name, filter_type);
    if (filter && combine_with_filter)
    {
        auto new_filter = std::make_shared<RowPolicyFilter>(*filter);

        if (filter->empty())
        {
            new_filter->expression = combine_with_filter->expression;
        }
        else if (combine_with_filter->empty())
        {
            new_filter->expression = filter->expression;
        }
        else
        {
            new_filter->expression = makeASTForLogicalAnd({filter->expression, combine_with_filter->expression});
        }

        std::copy(combine_with_filter->policies.begin(), combine_with_filter->policies.end(), std::back_inserter(new_filter->policies));
        filter = new_filter;
    }
    else if (!filter)
    {
        filter = combine_with_filter;
    }

    return filter;
}

}