#pragma once #include #include #include #include #include #include namespace DB { class IAST; using ASTPtr = std::shared_ptr; /// Provides fast access to row policies' conditions for a specific user and tables. class RowPolicyContext { public: /// Default constructor makes a row policy usage context which restricts nothing. RowPolicyContext(); ~RowPolicyContext(); using ConditionIndex = RowPolicy::ConditionIndex; /// Returns prepared filter for a specific table and operations. /// The function can return nullptr, that means there is no filters applied. /// The returned filter can be a combination of the filters defined by multiple row policies. ASTPtr getCondition(const String & database, const String & table_name, ConditionIndex index) const; /// Combines two conditions into one by using the logical AND operator. static ASTPtr combineConditionsUsingAnd(const ASTPtr & lhs, const ASTPtr & rhs); /// Returns IDs of all the policies used by the current user. std::vector getCurrentPolicyIDs() const; /// Returns IDs of the policies used by a concrete table. std::vector getCurrentPolicyIDs(const String & database, const String & table_name) const; private: friend class RowPolicyContextFactory; friend struct ext::shared_ptr_helper; RowPolicyContext(const UUID & user_id_, const std::vector & enabled_roles_); /// RowPolicyContext should be created by RowPolicyContextFactory. using DatabaseAndTableName = std::pair; using DatabaseAndTableNameRef = std::pair; struct Hash { size_t operator()(const DatabaseAndTableNameRef & database_and_table_name) const; }; static constexpr size_t MAX_CONDITION_INDEX = RowPolicy::MAX_CONDITION_INDEX; using ParsedConditions = std::array; struct MixedConditions { std::unique_ptr database_and_table_name_keeper; ParsedConditions mixed_conditions; std::vector policy_ids; }; using MapOfMixedConditions = std::unordered_map; const UUID user_id; const std::vector enabled_roles; mutable boost::atomic_shared_ptr map_of_mixed_conditions; }; using RowPolicyContextPtr = std::shared_ptr; }