1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/parser/result_modifier.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/common.hpp"
12#include "duckdb/common/vector.hpp"
13#include "duckdb/common/enums/order_type.hpp"
14#include "duckdb/parser/parsed_expression.hpp"
15
16namespace duckdb {
17class FieldWriter;
18class FieldReader;
19class FormatDeserializer;
20class FormatSerializer;
21
22enum class ResultModifierType : uint8_t {
23 LIMIT_MODIFIER = 1,
24 ORDER_MODIFIER = 2,
25 DISTINCT_MODIFIER = 3,
26 LIMIT_PERCENT_MODIFIER = 4
27};
28
29const char *ToString(ResultModifierType value);
30ResultModifierType ResultModifierFromString(const char *value);
31
32//! A ResultModifier
33class ResultModifier {
34public:
35 explicit ResultModifier(ResultModifierType type) : type(type) {
36 }
37 virtual ~ResultModifier() {
38 }
39
40 ResultModifierType type;
41
42public:
43 //! Returns true if the two result modifiers are equivalent
44 virtual bool Equals(const ResultModifier &other) const;
45
46 //! Create a copy of this ResultModifier
47 virtual unique_ptr<ResultModifier> Copy() const = 0;
48 //! Serializes a ResultModifier to a stand-alone binary blob
49 void Serialize(Serializer &serializer) const;
50 //! Serializes a ResultModifier to a stand-alone binary blob
51 virtual void Serialize(FieldWriter &writer) const = 0;
52 //! Deserializes a blob back into a ResultModifier
53 static unique_ptr<ResultModifier> Deserialize(Deserializer &source);
54
55 virtual void FormatSerialize(FormatSerializer &serializer) const;
56 static unique_ptr<ResultModifier> FormatDeserialize(FormatDeserializer &deserializer);
57
58public:
59 template <class TARGET>
60 TARGET &Cast() {
61 if (type != TARGET::TYPE) {
62 throw InternalException("Failed to cast result modifier to type - result modifier type mismatch");
63 }
64 return reinterpret_cast<TARGET &>(*this);
65 }
66
67 template <class TARGET>
68 const TARGET &Cast() const {
69 if (type != TARGET::TYPE) {
70 throw InternalException("Failed to cast result modifier to type - result modifier type mismatch");
71 }
72 return reinterpret_cast<const TARGET &>(*this);
73 }
74};
75
76//! Single node in ORDER BY statement
77struct OrderByNode {
78 OrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<ParsedExpression> expression)
79 : type(type), null_order(null_order), expression(std::move(expression)) {
80 }
81
82 //! Sort order, ASC or DESC
83 OrderType type;
84 //! The NULL sort order, NULLS_FIRST or NULLS_LAST
85 OrderByNullType null_order;
86 //! Expression to order by
87 unique_ptr<ParsedExpression> expression;
88
89public:
90 void Serialize(Serializer &serializer) const;
91 string ToString() const;
92 static OrderByNode Deserialize(Deserializer &source);
93
94 void FormatSerialize(FormatSerializer &serializer) const;
95 static OrderByNode FormatDeserialize(FormatDeserializer &deserializer);
96};
97
98class LimitModifier : public ResultModifier {
99public:
100 static constexpr const ResultModifierType TYPE = ResultModifierType::LIMIT_MODIFIER;
101
102public:
103 LimitModifier() : ResultModifier(ResultModifierType::LIMIT_MODIFIER) {
104 }
105
106 //! LIMIT count
107 unique_ptr<ParsedExpression> limit;
108 //! OFFSET
109 unique_ptr<ParsedExpression> offset;
110
111public:
112 bool Equals(const ResultModifier &other) const override;
113 unique_ptr<ResultModifier> Copy() const override;
114 void Serialize(FieldWriter &writer) const override;
115 static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
116
117 void FormatSerialize(FormatSerializer &serializer) const override;
118 static unique_ptr<ResultModifier> FormatDeserialize(FormatDeserializer &deserializer);
119};
120
121class OrderModifier : public ResultModifier {
122public:
123 static constexpr const ResultModifierType TYPE = ResultModifierType::ORDER_MODIFIER;
124
125public:
126 OrderModifier() : ResultModifier(ResultModifierType::ORDER_MODIFIER) {
127 }
128
129 //! List of order nodes
130 vector<OrderByNode> orders;
131
132public:
133 bool Equals(const ResultModifier &other) const override;
134 unique_ptr<ResultModifier> Copy() const override;
135 void Serialize(FieldWriter &writer) const override;
136 static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
137
138 void FormatSerialize(FormatSerializer &serializer) const override;
139 static unique_ptr<ResultModifier> FormatDeserialize(FormatDeserializer &deserializer);
140
141 static bool Equals(const unique_ptr<OrderModifier> &left, const unique_ptr<OrderModifier> &right);
142};
143
144class DistinctModifier : public ResultModifier {
145public:
146 static constexpr const ResultModifierType TYPE = ResultModifierType::DISTINCT_MODIFIER;
147
148public:
149 DistinctModifier() : ResultModifier(ResultModifierType::DISTINCT_MODIFIER) {
150 }
151
152 //! list of distinct on targets (if any)
153 vector<unique_ptr<ParsedExpression>> distinct_on_targets;
154
155public:
156 bool Equals(const ResultModifier &other) const override;
157 unique_ptr<ResultModifier> Copy() const override;
158 void Serialize(FieldWriter &writer) const override;
159 static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
160
161 void FormatSerialize(FormatSerializer &serializer) const override;
162 static unique_ptr<ResultModifier> FormatDeserialize(FormatDeserializer &deserializer);
163};
164
165class LimitPercentModifier : public ResultModifier {
166public:
167 static constexpr const ResultModifierType TYPE = ResultModifierType::LIMIT_PERCENT_MODIFIER;
168
169public:
170 LimitPercentModifier() : ResultModifier(ResultModifierType::LIMIT_PERCENT_MODIFIER) {
171 }
172
173 //! LIMIT %
174 unique_ptr<ParsedExpression> limit;
175 //! OFFSET
176 unique_ptr<ParsedExpression> offset;
177
178public:
179 bool Equals(const ResultModifier &other) const override;
180 unique_ptr<ResultModifier> Copy() const override;
181 void Serialize(FieldWriter &writer) const override;
182 static unique_ptr<ResultModifier> Deserialize(FieldReader &reader);
183
184 void FormatSerialize(FormatSerializer &serializer) const override;
185 static unique_ptr<ResultModifier> FormatDeserialize(FormatDeserializer &deserializer);
186};
187
188} // namespace duckdb
189