1#include "duckdb/main/client_context.hpp"
2
3#include "duckdb/parser/parsed_expression.hpp"
4#include "duckdb/common/field_writer.hpp"
5#include "duckdb/common/types/hash.hpp"
6#include "duckdb/parser/expression/list.hpp"
7#include "duckdb/parser/parsed_expression_iterator.hpp"
8#include "duckdb/common/serializer/format_serializer.hpp"
9#include "duckdb/common/serializer/format_deserializer.hpp"
10#include "duckdb/parser/expression_util.hpp"
11
12namespace duckdb {
13
14bool ParsedExpression::IsAggregate() const {
15 bool is_aggregate = false;
16 ParsedExpressionIterator::EnumerateChildren(
17 expression: *this, callback: [&](const ParsedExpression &child) { is_aggregate |= child.IsAggregate(); });
18 return is_aggregate;
19}
20
21bool ParsedExpression::IsWindow() const {
22 bool is_window = false;
23 ParsedExpressionIterator::EnumerateChildren(expression: *this,
24 callback: [&](const ParsedExpression &child) { is_window |= child.IsWindow(); });
25 return is_window;
26}
27
28bool ParsedExpression::IsScalar() const {
29 bool is_scalar = true;
30 ParsedExpressionIterator::EnumerateChildren(expression: *this, callback: [&](const ParsedExpression &child) {
31 if (!child.IsScalar()) {
32 is_scalar = false;
33 }
34 });
35 return is_scalar;
36}
37
38bool ParsedExpression::HasParameter() const {
39 bool has_parameter = false;
40 ParsedExpressionIterator::EnumerateChildren(
41 expression: *this, callback: [&](const ParsedExpression &child) { has_parameter |= child.HasParameter(); });
42 return has_parameter;
43}
44
45bool ParsedExpression::HasSubquery() const {
46 bool has_subquery = false;
47 ParsedExpressionIterator::EnumerateChildren(
48 expression: *this, callback: [&](const ParsedExpression &child) { has_subquery |= child.HasSubquery(); });
49 return has_subquery;
50}
51
52bool ParsedExpression::Equals(const BaseExpression &other) const {
53 if (!BaseExpression::Equals(other)) {
54 return false;
55 }
56 switch (expression_class) {
57 case ExpressionClass::BETWEEN:
58 return BetweenExpression::Equal(a: Cast<BetweenExpression>(), b: other.Cast<BetweenExpression>());
59 case ExpressionClass::CASE:
60 return CaseExpression::Equal(a: Cast<CaseExpression>(), b: other.Cast<CaseExpression>());
61 case ExpressionClass::CAST:
62 return CastExpression::Equal(a: Cast<CastExpression>(), b: other.Cast<CastExpression>());
63 case ExpressionClass::COLLATE:
64 return CollateExpression::Equal(a: Cast<CollateExpression>(), b: other.Cast<CollateExpression>());
65 case ExpressionClass::COLUMN_REF:
66 return ColumnRefExpression::Equal(a: Cast<ColumnRefExpression>(), b: other.Cast<ColumnRefExpression>());
67 case ExpressionClass::COMPARISON:
68 return ComparisonExpression::Equal(a: Cast<ComparisonExpression>(), b: other.Cast<ComparisonExpression>());
69 case ExpressionClass::CONJUNCTION:
70 return ConjunctionExpression::Equal(a: Cast<ConjunctionExpression>(), b: other.Cast<ConjunctionExpression>());
71 case ExpressionClass::CONSTANT:
72 return ConstantExpression::Equal(a: Cast<ConstantExpression>(), b: other.Cast<ConstantExpression>());
73 case ExpressionClass::DEFAULT:
74 return true;
75 case ExpressionClass::FUNCTION:
76 return FunctionExpression::Equal(a: Cast<FunctionExpression>(), b: other.Cast<FunctionExpression>());
77 case ExpressionClass::LAMBDA:
78 return LambdaExpression::Equal(a: Cast<LambdaExpression>(), b: other.Cast<LambdaExpression>());
79 case ExpressionClass::OPERATOR:
80 return OperatorExpression::Equal(a: Cast<OperatorExpression>(), b: other.Cast<OperatorExpression>());
81 case ExpressionClass::PARAMETER:
82 return ParameterExpression::Equal(a: Cast<ParameterExpression>(), b: other.Cast<ParameterExpression>());
83 case ExpressionClass::POSITIONAL_REFERENCE:
84 return PositionalReferenceExpression::Equal(a: Cast<PositionalReferenceExpression>(),
85 b: other.Cast<PositionalReferenceExpression>());
86 case ExpressionClass::STAR:
87 return StarExpression::Equal(a: Cast<StarExpression>(), b: other.Cast<StarExpression>());
88 case ExpressionClass::SUBQUERY:
89 return SubqueryExpression::Equal(a: Cast<SubqueryExpression>(), b: other.Cast<SubqueryExpression>());
90 case ExpressionClass::WINDOW:
91 return WindowExpression::Equal(a: Cast<WindowExpression>(), b: other.Cast<WindowExpression>());
92 default:
93 throw SerializationException("Unsupported type for expression comparison!");
94 }
95}
96
97hash_t ParsedExpression::Hash() const {
98 hash_t hash = duckdb::Hash<uint32_t>(value: (uint32_t)type);
99 ParsedExpressionIterator::EnumerateChildren(
100 expression: *this, callback: [&](const ParsedExpression &child) { hash = CombineHash(left: child.Hash(), right: hash); });
101 return hash;
102}
103
104void ParsedExpression::Serialize(Serializer &serializer) const {
105 FieldWriter writer(serializer);
106 writer.WriteField<ExpressionClass>(element: GetExpressionClass());
107 writer.WriteField<ExpressionType>(element: type);
108 writer.WriteString(val: alias);
109 Serialize(writer);
110 writer.Finalize();
111}
112
113void ParsedExpression::FormatSerialize(FormatSerializer &serializer) const {
114 serializer.WriteProperty(tag: "class", value: GetExpressionClass());
115 serializer.WriteProperty(tag: "type", value: type);
116 serializer.WriteProperty(tag: "alias", value: alias);
117}
118
119unique_ptr<ParsedExpression> ParsedExpression::FormatDeserialize(FormatDeserializer &deserializer) {
120 auto expression_class = deserializer.ReadProperty<ExpressionClass>(tag: "class");
121 auto type = deserializer.ReadProperty<ExpressionType>(tag: "type");
122 auto alias = deserializer.ReadProperty<string>(tag: "alias");
123 unique_ptr<ParsedExpression> result;
124 switch (expression_class) {
125 case ExpressionClass::BETWEEN:
126 result = BetweenExpression::FormatDeserialize(type, deserializer);
127 break;
128 case ExpressionClass::CASE:
129 result = CaseExpression::FormatDeserialize(type, deserializer);
130 break;
131 case ExpressionClass::CAST:
132 result = CastExpression::FormatDeserialize(type, deserializer);
133 break;
134 case ExpressionClass::COLLATE:
135 result = CollateExpression::FormatDeserialize(type, deserializer);
136 break;
137 case ExpressionClass::COLUMN_REF:
138 result = ColumnRefExpression::FormatDeserialize(type, deserializer);
139 break;
140 case ExpressionClass::COMPARISON:
141 result = ComparisonExpression::FormatDeserialize(type, deserializer);
142 break;
143 case ExpressionClass::CONJUNCTION:
144 result = ConjunctionExpression::FormatDeserialize(type, deserializer);
145 break;
146 case ExpressionClass::CONSTANT:
147 result = ConstantExpression::FormatDeserialize(type, deserializer);
148 break;
149 case ExpressionClass::DEFAULT:
150 result = make_uniq<DefaultExpression>();
151 break;
152 case ExpressionClass::FUNCTION:
153 result = FunctionExpression::FormatDeserialize(type, deserializer);
154 break;
155 case ExpressionClass::LAMBDA:
156 result = LambdaExpression::FormatDeserialize(type, deserializer);
157 break;
158 case ExpressionClass::OPERATOR:
159 result = OperatorExpression::FormatDeserialize(type, deserializer);
160 break;
161 case ExpressionClass::PARAMETER:
162 result = ParameterExpression::FormatDeserialize(type, deserializer);
163 break;
164 case ExpressionClass::POSITIONAL_REFERENCE:
165 result = PositionalReferenceExpression::FormatDeserialize(type, deserializer);
166 break;
167 case ExpressionClass::STAR:
168 result = StarExpression::FormatDeserialize(type, deserializer);
169 break;
170 case ExpressionClass::SUBQUERY:
171 result = SubqueryExpression::FormatDeserialize(type, deserializer);
172 break;
173 case ExpressionClass::WINDOW:
174 result = WindowExpression::FormatDeserialize(type, deserializer);
175 break;
176 default:
177 throw SerializationException("Unsupported type for expression deserialization!");
178 }
179 result->alias = alias;
180 return result;
181}
182
183unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source) {
184 FieldReader reader(source);
185 auto expression_class = reader.ReadRequired<ExpressionClass>();
186 auto type = reader.ReadRequired<ExpressionType>();
187 auto alias = reader.ReadRequired<string>();
188 unique_ptr<ParsedExpression> result;
189 switch (expression_class) {
190 case ExpressionClass::BETWEEN:
191 result = BetweenExpression::Deserialize(type, source&: reader);
192 break;
193 case ExpressionClass::CASE:
194 result = CaseExpression::Deserialize(type, source&: reader);
195 break;
196 case ExpressionClass::CAST:
197 result = CastExpression::Deserialize(type, source&: reader);
198 break;
199 case ExpressionClass::COLLATE:
200 result = CollateExpression::Deserialize(type, source&: reader);
201 break;
202 case ExpressionClass::COLUMN_REF:
203 result = ColumnRefExpression::Deserialize(type, source&: reader);
204 break;
205 case ExpressionClass::COMPARISON:
206 result = ComparisonExpression::Deserialize(type, source&: reader);
207 break;
208 case ExpressionClass::CONJUNCTION:
209 result = ConjunctionExpression::Deserialize(type, source&: reader);
210 break;
211 case ExpressionClass::CONSTANT:
212 result = ConstantExpression::Deserialize(type, source&: reader);
213 break;
214 case ExpressionClass::DEFAULT:
215 result = DefaultExpression::Deserialize(type, source&: reader);
216 break;
217 case ExpressionClass::FUNCTION:
218 result = FunctionExpression::Deserialize(type, source&: reader);
219 break;
220 case ExpressionClass::LAMBDA:
221 result = LambdaExpression::Deserialize(type, source&: reader);
222 break;
223 case ExpressionClass::OPERATOR:
224 result = OperatorExpression::Deserialize(type, source&: reader);
225 break;
226 case ExpressionClass::PARAMETER:
227 result = ParameterExpression::Deserialize(type, source&: reader);
228 break;
229 case ExpressionClass::POSITIONAL_REFERENCE:
230 result = PositionalReferenceExpression::Deserialize(type, source&: reader);
231 break;
232 case ExpressionClass::STAR:
233 result = StarExpression::Deserialize(type, source&: reader);
234 break;
235 case ExpressionClass::SUBQUERY:
236 result = SubqueryExpression::Deserialize(type, source&: reader);
237 break;
238 case ExpressionClass::WINDOW:
239 result = WindowExpression::Deserialize(type, source&: reader);
240 break;
241 default:
242 throw SerializationException("Unsupported type for expression deserialization: '%s'!",
243 ExpressionClassToString(type: expression_class));
244 }
245 result->alias = alias;
246 reader.Finalize();
247 return result;
248}
249
250bool ParsedExpression::Equals(const unique_ptr<ParsedExpression> &left, const unique_ptr<ParsedExpression> &right) {
251 if (left.get() == right.get()) {
252 return true;
253 }
254 if (!left || !right) {
255 return false;
256 }
257 return left->Equals(other: *right);
258}
259
260bool ParsedExpression::ListEquals(const vector<unique_ptr<ParsedExpression>> &left,
261 const vector<unique_ptr<ParsedExpression>> &right) {
262 return ExpressionUtil::ListEquals(a: left, b: right);
263}
264
265} // namespace duckdb
266