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 | |
12 | namespace duckdb { |
13 | |
14 | bool 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 | |
21 | bool 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 | |
28 | bool 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 | |
38 | bool 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 | |
45 | bool 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 | |
52 | bool 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 | |
97 | hash_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 | |
104 | void 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 | |
113 | void 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 | |
119 | unique_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 | |
183 | unique_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 | |
250 | bool 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 | |
260 | bool 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 | |