//===----------------------------------------------------------------------===// // DuckDB // // duckdb/optimizer/filter_pushdown.hpp // // //===----------------------------------------------------------------------===// #pragma once #include "duckdb/common/unordered_set.hpp" #include "duckdb/optimizer/filter_combiner.hpp" #include "duckdb/optimizer/rule.hpp" namespace duckdb { class Optimizer; class FilterPushdown { public: explicit FilterPushdown(Optimizer &optimizer); //! Perform filter pushdown unique_ptr Rewrite(unique_ptr op); struct Filter { unordered_set bindings; unique_ptr filter; Filter() { } explicit Filter(unique_ptr filter) : filter(std::move(filter)) { } void ExtractBindings(); }; private: vector> filters; Optimizer &optimizer; //! Push down a LogicalAggregate op unique_ptr PushdownAggregate(unique_ptr op); //! Push down a LogicalFilter op unique_ptr PushdownFilter(unique_ptr op); //! Push down a LogicalCrossProduct op unique_ptr PushdownCrossProduct(unique_ptr op); //! Push down a join operator unique_ptr PushdownJoin(unique_ptr op); //! Push down a LogicalProjection op unique_ptr PushdownProjection(unique_ptr op); //! Push down a LogicalSetOperation op unique_ptr PushdownSetOperation(unique_ptr op); //! Push down a LogicalGet op unique_ptr PushdownGet(unique_ptr op); //! Push down a LogicalLimit op unique_ptr PushdownLimit(unique_ptr op); // Pushdown an inner join unique_ptr PushdownInnerJoin(unique_ptr op, unordered_set &left_bindings, unordered_set &right_bindings); // Pushdown a left join unique_ptr PushdownLeftJoin(unique_ptr op, unordered_set &left_bindings, unordered_set &right_bindings); // Pushdown a mark join unique_ptr PushdownMarkJoin(unique_ptr op, unordered_set &left_bindings, unordered_set &right_bindings); // Pushdown a single join unique_ptr PushdownSingleJoin(unique_ptr op, unordered_set &left_bindings, unordered_set &right_bindings); //! Push any remaining filters into a LogicalFilter at this level unique_ptr PushFinalFilters(unique_ptr op); // Finish pushing down at this operator, creating a LogicalFilter to store any of the stored filters and recursively // pushing down into its children (if any) unique_ptr FinishPushdown(unique_ptr op); //! Adds a filter to the set of filters. Returns FilterResult::UNSATISFIABLE if the subtree should be stripped, or //! FilterResult::SUCCESS otherwise FilterResult AddFilter(unique_ptr expr); //! Generate filters from the current set of filters stored in the FilterCombiner void GenerateFilters(); //! if there are filters in this FilterPushdown node, push them into the combiner void PushFilters(); FilterCombiner combiner; }; } // namespace duckdb