1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/planner/bound_result_modifier.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/limits.hpp" |
12 | #include "duckdb/parser/result_modifier.hpp" |
13 | #include "duckdb/planner/bound_statement.hpp" |
14 | #include "duckdb/planner/expression.hpp" |
15 | #include "duckdb/storage/statistics/base_statistics.hpp" |
16 | |
17 | namespace duckdb { |
18 | |
19 | //! A ResultModifier |
20 | class BoundResultModifier { |
21 | public: |
22 | explicit BoundResultModifier(ResultModifierType type); |
23 | virtual ~BoundResultModifier(); |
24 | |
25 | ResultModifierType type; |
26 | |
27 | public: |
28 | template <class TARGET> |
29 | TARGET &Cast() { |
30 | if (type != TARGET::TYPE) { |
31 | throw InternalException("Failed to cast result modifier to type - result modifier type mismatch" ); |
32 | } |
33 | return reinterpret_cast<TARGET &>(*this); |
34 | } |
35 | |
36 | template <class TARGET> |
37 | const TARGET &Cast() const { |
38 | if (type != TARGET::TYPE) { |
39 | throw InternalException("Failed to cast result modifier to type - result modifier type mismatch" ); |
40 | } |
41 | return reinterpret_cast<const TARGET &>(*this); |
42 | } |
43 | }; |
44 | |
45 | struct BoundOrderByNode { |
46 | public: |
47 | static constexpr const ResultModifierType TYPE = ResultModifierType::ORDER_MODIFIER; |
48 | |
49 | public: |
50 | BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression); |
51 | BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression, |
52 | unique_ptr<BaseStatistics> stats); |
53 | |
54 | OrderType type; |
55 | OrderByNullType null_order; |
56 | unique_ptr<Expression> expression; |
57 | unique_ptr<BaseStatistics> stats; |
58 | |
59 | public: |
60 | BoundOrderByNode Copy() const; |
61 | bool Equals(const BoundOrderByNode &other) const; |
62 | string ToString() const; |
63 | |
64 | void Serialize(Serializer &serializer) const; |
65 | static BoundOrderByNode Deserialize(Deserializer &source, PlanDeserializationState &state); |
66 | }; |
67 | |
68 | class BoundLimitModifier : public BoundResultModifier { |
69 | public: |
70 | static constexpr const ResultModifierType TYPE = ResultModifierType::LIMIT_MODIFIER; |
71 | |
72 | public: |
73 | BoundLimitModifier(); |
74 | |
75 | //! LIMIT |
76 | int64_t limit_val = NumericLimits<int64_t>::Maximum(); |
77 | //! OFFSET |
78 | int64_t offset_val = 0; |
79 | //! Expression in case limit is not constant |
80 | unique_ptr<Expression> limit; |
81 | //! Expression in case limit is not constant |
82 | unique_ptr<Expression> offset; |
83 | }; |
84 | |
85 | class BoundOrderModifier : public BoundResultModifier { |
86 | public: |
87 | static constexpr const ResultModifierType TYPE = ResultModifierType::ORDER_MODIFIER; |
88 | |
89 | public: |
90 | BoundOrderModifier(); |
91 | |
92 | //! List of order nodes |
93 | vector<BoundOrderByNode> orders; |
94 | |
95 | unique_ptr<BoundOrderModifier> Copy() const; |
96 | static bool Equals(const BoundOrderModifier &left, const BoundOrderModifier &right); |
97 | static bool Equals(const unique_ptr<BoundOrderModifier> &left, const unique_ptr<BoundOrderModifier> &right); |
98 | |
99 | void Serialize(Serializer &serializer) const; |
100 | static unique_ptr<BoundOrderModifier> Deserialize(Deserializer &source, PlanDeserializationState &state); |
101 | }; |
102 | |
103 | enum class DistinctType : uint8_t { DISTINCT = 0, DISTINCT_ON = 1 }; |
104 | |
105 | class BoundDistinctModifier : public BoundResultModifier { |
106 | public: |
107 | static constexpr const ResultModifierType TYPE = ResultModifierType::DISTINCT_MODIFIER; |
108 | |
109 | public: |
110 | BoundDistinctModifier(); |
111 | |
112 | //! Whether or not this is a DISTINCT or DISTINCT ON |
113 | DistinctType distinct_type; |
114 | //! list of distinct on targets |
115 | vector<unique_ptr<Expression>> target_distincts; |
116 | }; |
117 | |
118 | class BoundLimitPercentModifier : public BoundResultModifier { |
119 | public: |
120 | static constexpr const ResultModifierType TYPE = ResultModifierType::LIMIT_PERCENT_MODIFIER; |
121 | |
122 | public: |
123 | BoundLimitPercentModifier(); |
124 | |
125 | //! LIMIT % |
126 | double limit_percent = 100.0; |
127 | //! OFFSET |
128 | int64_t offset_val = 0; |
129 | //! Expression in case limit is not constant |
130 | unique_ptr<Expression> limit; |
131 | //! Expression in case limit is not constant |
132 | unique_ptr<Expression> offset; |
133 | }; |
134 | |
135 | } // namespace duckdb |
136 | |