1#include "duckdb/optimizer/topn_optimizer.hpp"
2#include "duckdb/planner/operator/logical_order.hpp"
3#include "duckdb/planner/operator/logical_limit.hpp"
4#include "duckdb/planner/operator/logical_top_n.hpp"
5#include "duckdb/common/limits.hpp"
6
7namespace duckdb {
8
9unique_ptr<LogicalOperator> TopN::Optimize(unique_ptr<LogicalOperator> op) {
10 if (op->type == LogicalOperatorType::LOGICAL_LIMIT &&
11 op->children[0]->type == LogicalOperatorType::LOGICAL_ORDER_BY) {
12 auto &limit = op->Cast<LogicalLimit>();
13 auto &order_by = (op->children[0])->Cast<LogicalOrder>();
14
15 // This optimization doesn't apply when OFFSET is present without LIMIT
16 // Or if offset is not constant
17 if (limit.limit_val != NumericLimits<int64_t>::Maximum() || limit.offset) {
18 auto topn = make_uniq<LogicalTopN>(args: std::move(order_by.orders), args&: limit.limit_val, args&: limit.offset_val);
19 topn->AddChild(child: std::move(order_by.children[0]));
20 op = std::move(topn);
21 }
22 } else {
23 for (auto &child : op->children) {
24 child = Optimize(op: std::move(child));
25 }
26 }
27 return op;
28}
29
30} // namespace duckdb
31