1#include "duckdb/parser/query_node/set_operation_node.hpp"
2
3#include "duckdb/common/field_writer.hpp"
4#include "duckdb/common/serializer/format_serializer.hpp"
5#include "duckdb/common/serializer/format_deserializer.hpp"
6
7namespace duckdb {
8
9string SetOperationNode::ToString() const {
10 string result;
11 result = cte_map.ToString();
12 result += "(" + left->ToString() + ") ";
13 bool is_distinct = false;
14 for (idx_t modifier_idx = 0; modifier_idx < modifiers.size(); modifier_idx++) {
15 if (modifiers[modifier_idx]->type == ResultModifierType::DISTINCT_MODIFIER) {
16 is_distinct = true;
17 break;
18 }
19 }
20
21 switch (setop_type) {
22 case SetOperationType::UNION:
23 result += is_distinct ? "UNION" : "UNION ALL";
24 break;
25 case SetOperationType::UNION_BY_NAME:
26 result += is_distinct ? "UNION BY NAME" : "UNION ALL BY NAME";
27 break;
28 case SetOperationType::EXCEPT:
29 D_ASSERT(is_distinct);
30 result += "EXCEPT";
31 break;
32 case SetOperationType::INTERSECT:
33 D_ASSERT(is_distinct);
34 result += "INTERSECT";
35 break;
36 default:
37 throw InternalException("Unsupported set operation type");
38 }
39 result += " (" + right->ToString() + ")";
40 return result + ResultModifiersToString();
41}
42
43bool SetOperationNode::Equals(const QueryNode *other_p) const {
44 if (!QueryNode::Equals(other: other_p)) {
45 return false;
46 }
47 if (this == other_p) {
48 return true;
49 }
50 auto &other = other_p->Cast<SetOperationNode>();
51 if (setop_type != other.setop_type) {
52 return false;
53 }
54 if (!left->Equals(other: other.left.get())) {
55 return false;
56 }
57 if (!right->Equals(other: other.right.get())) {
58 return false;
59 }
60 return true;
61}
62
63unique_ptr<QueryNode> SetOperationNode::Copy() const {
64 auto result = make_uniq<SetOperationNode>();
65 result->setop_type = setop_type;
66 result->left = left->Copy();
67 result->right = right->Copy();
68 this->CopyProperties(other&: *result);
69 return std::move(result);
70}
71
72void SetOperationNode::Serialize(FieldWriter &writer) const {
73 writer.WriteField<SetOperationType>(element: setop_type);
74 writer.WriteSerializable(element: *left);
75 writer.WriteSerializable(element: *right);
76}
77
78unique_ptr<QueryNode> SetOperationNode::Deserialize(FieldReader &reader) {
79 auto result = make_uniq<SetOperationNode>();
80 result->setop_type = reader.ReadRequired<SetOperationType>();
81 result->left = reader.ReadRequiredSerializable<QueryNode>();
82 result->right = reader.ReadRequiredSerializable<QueryNode>();
83 return std::move(result);
84}
85
86void SetOperationNode::FormatSerialize(duckdb::FormatSerializer &serializer) const {
87 QueryNode::FormatSerialize(serializer);
88 serializer.WriteProperty(tag: "set_op_type", value: setop_type);
89 serializer.WriteProperty(tag: "left", value&: *left);
90 serializer.WriteProperty(tag: "right", value&: *right);
91}
92
93unique_ptr<QueryNode> SetOperationNode::FormatDeserialize(duckdb::FormatDeserializer &deserializer) {
94 auto result = make_uniq<SetOperationNode>();
95 deserializer.ReadProperty(tag: "set_op_type", ret&: result->setop_type);
96 deserializer.ReadProperty(tag: "left", ret&: result->left);
97 deserializer.ReadProperty(tag: "right", ret&: result->right);
98 return std::move(result);
99}
100
101} // namespace duckdb
102