1#include "duckdb/parser/expression/subquery_expression.hpp"
2
3#include "duckdb/common/exception.hpp"
4#include "duckdb/common/field_writer.hpp"
5#include "duckdb/common/serializer/format_deserializer.hpp"
6#include "duckdb/common/serializer/format_serializer.hpp"
7
8namespace duckdb {
9
10SubqueryExpression::SubqueryExpression()
11 : ParsedExpression(ExpressionType::SUBQUERY, ExpressionClass::SUBQUERY), subquery_type(SubqueryType::INVALID),
12 comparison_type(ExpressionType::INVALID) {
13}
14
15string SubqueryExpression::ToString() const {
16 switch (subquery_type) {
17 case SubqueryType::ANY:
18 return "(" + child->ToString() + " " + ExpressionTypeToOperator(type: comparison_type) + " ANY(" +
19 subquery->ToString() + "))";
20 case SubqueryType::EXISTS:
21 return "EXISTS(" + subquery->ToString() + ")";
22 case SubqueryType::NOT_EXISTS:
23 return "NOT EXISTS(" + subquery->ToString() + ")";
24 case SubqueryType::SCALAR:
25 return "(" + subquery->ToString() + ")";
26 default:
27 throw InternalException("Unrecognized type for subquery");
28 }
29}
30
31bool SubqueryExpression::Equal(const SubqueryExpression &a, const SubqueryExpression &b) {
32 if (!a.subquery || !b.subquery) {
33 return false;
34 }
35 if (!ParsedExpression::Equals(left: a.child, right: b.child)) {
36 return false;
37 }
38 return a.comparison_type == b.comparison_type && a.subquery_type == b.subquery_type &&
39 a.subquery->Equals(other: *b.subquery);
40}
41
42unique_ptr<ParsedExpression> SubqueryExpression::Copy() const {
43 auto copy = make_uniq<SubqueryExpression>();
44 copy->CopyProperties(other: *this);
45 copy->subquery = unique_ptr_cast<SQLStatement, SelectStatement>(src: subquery->Copy());
46 copy->subquery_type = subquery_type;
47 copy->child = child ? child->Copy() : nullptr;
48 copy->comparison_type = comparison_type;
49 return std::move(copy);
50}
51
52void SubqueryExpression::Serialize(FieldWriter &writer) const {
53 auto &serializer = writer.GetSerializer();
54
55 writer.WriteField<SubqueryType>(element: subquery_type);
56 // FIXME: this shouldn't use a serializer (probably)?
57 subquery->Serialize(serializer);
58 writer.WriteOptional(element: child);
59 writer.WriteField<ExpressionType>(element: comparison_type);
60}
61
62unique_ptr<ParsedExpression> SubqueryExpression::Deserialize(ExpressionType type, FieldReader &reader) {
63 // FIXME: this shouldn't use a source
64 auto &source = reader.GetSource();
65
66 auto subquery_type = reader.ReadRequired<SubqueryType>();
67 auto subquery = SelectStatement::Deserialize(source);
68
69 auto expression = make_uniq<SubqueryExpression>();
70 expression->subquery_type = subquery_type;
71 expression->subquery = std::move(subquery);
72 expression->child = reader.ReadOptional<ParsedExpression>(default_value: nullptr);
73 expression->comparison_type = reader.ReadRequired<ExpressionType>();
74 return std::move(expression);
75}
76
77void SubqueryExpression::FormatSerialize(FormatSerializer &serializer) const {
78 ParsedExpression::FormatSerialize(serializer);
79 serializer.WriteProperty(tag: "subquery_type", value: subquery_type);
80 serializer.WriteProperty(tag: "subquery", value&: *subquery);
81 serializer.WriteOptionalProperty(tag: "child", ptr: child);
82 serializer.WriteProperty(tag: "comparison_type", value: comparison_type);
83}
84
85unique_ptr<ParsedExpression> SubqueryExpression::FormatDeserialize(ExpressionType type,
86 FormatDeserializer &deserializer) {
87 auto expression = make_uniq<SubqueryExpression>();
88 deserializer.ReadProperty(tag: "subquery_type", ret&: expression->subquery_type);
89 deserializer.ReadProperty(tag: "subquery", ret&: expression->subquery);
90 deserializer.ReadOptionalProperty(tag: "child", ret&: expression->child);
91 deserializer.ReadProperty(tag: "comparison_type", ret&: expression->comparison_type);
92 return std::move(expression);
93}
94
95} // namespace duckdb
96