1#include "duckdb/parser/query_node.hpp"
2#include "duckdb/planner/binder.hpp"
3#include "duckdb/planner/operator/logical_distinct.hpp"
4#include "duckdb/planner/operator/logical_limit.hpp"
5#include "duckdb/planner/operator/logical_limit_percent.hpp"
6#include "duckdb/planner/operator/logical_order.hpp"
7#include "duckdb/planner/bound_result_modifier.hpp"
8
9namespace duckdb {
10
11unique_ptr<LogicalOperator> Binder::VisitQueryNode(BoundQueryNode &node, unique_ptr<LogicalOperator> root) {
12 D_ASSERT(root);
13 for (auto &mod : node.modifiers) {
14 switch (mod->type) {
15 case ResultModifierType::DISTINCT_MODIFIER: {
16 auto &bound = mod->Cast<BoundDistinctModifier>();
17 auto distinct = make_uniq<LogicalDistinct>(args: std::move(bound.target_distincts), args&: bound.distinct_type);
18 distinct->AddChild(child: std::move(root));
19 root = std::move(distinct);
20 break;
21 }
22 case ResultModifierType::ORDER_MODIFIER: {
23 auto &bound = mod->Cast<BoundOrderModifier>();
24 if (root->type == LogicalOperatorType::LOGICAL_DISTINCT) {
25 auto &distinct = root->Cast<LogicalDistinct>();
26 if (distinct.distinct_type == DistinctType::DISTINCT_ON) {
27 auto order_by = make_uniq<BoundOrderModifier>();
28 for (auto &order_node : bound.orders) {
29 order_by->orders.push_back(x: order_node.Copy());
30 }
31 distinct.order_by = std::move(order_by);
32 }
33 }
34 auto order = make_uniq<LogicalOrder>(args: std::move(bound.orders));
35 order->AddChild(child: std::move(root));
36 root = std::move(order);
37 break;
38 }
39 case ResultModifierType::LIMIT_MODIFIER: {
40 auto &bound = mod->Cast<BoundLimitModifier>();
41 auto limit = make_uniq<LogicalLimit>(args&: bound.limit_val, args&: bound.offset_val, args: std::move(bound.limit),
42 args: std::move(bound.offset));
43 limit->AddChild(child: std::move(root));
44 root = std::move(limit);
45 break;
46 }
47 case ResultModifierType::LIMIT_PERCENT_MODIFIER: {
48 auto &bound = mod->Cast<BoundLimitPercentModifier>();
49 auto limit = make_uniq<LogicalLimitPercent>(args&: bound.limit_percent, args&: bound.offset_val, args: std::move(bound.limit),
50 args: std::move(bound.offset));
51 limit->AddChild(child: std::move(root));
52 root = std::move(limit);
53 break;
54 }
55 default:
56 throw BinderException("Unimplemented modifier type!");
57 }
58 }
59 return root;
60}
61
62} // namespace duckdb
63