1#include "duckdb/parser/tableref/joinref.hpp"
2
3#include "duckdb/common/limits.hpp"
4#include "duckdb/common/field_writer.hpp"
5#include "duckdb/common/serializer/format_serializer.hpp"
6#include "duckdb/common/serializer/format_deserializer.hpp"
7
8namespace duckdb {
9
10string JoinRef::ToString() const {
11 string result;
12 result = left->ToString() + " ";
13 switch (ref_type) {
14 case JoinRefType::REGULAR:
15 result += EnumUtil::ToString(value: type) + " JOIN ";
16 break;
17 case JoinRefType::NATURAL:
18 result += "NATURAL ";
19 result += EnumUtil::ToString(value: type) + " JOIN ";
20 break;
21 case JoinRefType::ASOF:
22 result += "ASOF ";
23 result += EnumUtil::ToString(value: type) + " JOIN ";
24 break;
25 case JoinRefType::CROSS:
26 result += ", ";
27 break;
28 case JoinRefType::POSITIONAL:
29 result += "POSITIONAL JOIN ";
30 break;
31 }
32 result += right->ToString();
33 if (condition) {
34 D_ASSERT(using_columns.empty());
35 result += " ON (";
36 result += condition->ToString();
37 result += ")";
38 } else if (!using_columns.empty()) {
39 result += " USING (";
40 for (idx_t i = 0; i < using_columns.size(); i++) {
41 if (i > 0) {
42 result += ", ";
43 }
44 result += using_columns[i];
45 }
46 result += ")";
47 }
48 return result;
49}
50
51bool JoinRef::Equals(const TableRef &other_p) const {
52 if (!TableRef::Equals(other: other_p)) {
53 return false;
54 }
55 auto &other = other_p.Cast<JoinRef>();
56 if (using_columns.size() != other.using_columns.size()) {
57 return false;
58 }
59 for (idx_t i = 0; i < using_columns.size(); i++) {
60 if (using_columns[i] != other.using_columns[i]) {
61 return false;
62 }
63 }
64 return left->Equals(other: *other.left) && right->Equals(other: *other.right) &&
65 ParsedExpression::Equals(left: condition, right: other.condition) && type == other.type;
66}
67
68unique_ptr<TableRef> JoinRef::Copy() {
69 auto copy = make_uniq<JoinRef>(args&: ref_type);
70 copy->left = left->Copy();
71 copy->right = right->Copy();
72 if (condition) {
73 copy->condition = condition->Copy();
74 }
75 copy->type = type;
76 copy->ref_type = ref_type;
77 copy->alias = alias;
78 copy->using_columns = using_columns;
79 return std::move(copy);
80}
81
82void JoinRef::Serialize(FieldWriter &writer) const {
83 writer.WriteSerializable(element: *left);
84 writer.WriteSerializable(element: *right);
85 writer.WriteOptional(element: condition);
86 writer.WriteField<JoinType>(element: type);
87 writer.WriteField<JoinRefType>(element: ref_type);
88 writer.WriteList<string>(elements: using_columns);
89}
90
91void JoinRef::FormatSerialize(FormatSerializer &serializer) const {
92 TableRef::FormatSerialize(serializer);
93 serializer.WriteProperty(tag: "left", value&: *left);
94 serializer.WriteProperty(tag: "right", value&: *right);
95 serializer.WriteOptionalProperty(tag: "condition", ptr: condition);
96 serializer.WriteProperty(tag: "join_type", value: type);
97 serializer.WriteProperty(tag: "ref_type", value: ref_type);
98 serializer.WriteProperty(tag: "using_columns", value: using_columns);
99}
100
101unique_ptr<TableRef> JoinRef::FormatDeserialize(FormatDeserializer &source) {
102 auto result = make_uniq<JoinRef>(args: JoinRefType::REGULAR);
103
104 source.ReadProperty(tag: "left", ret&: result->left);
105 source.ReadProperty(tag: "right", ret&: result->right);
106 source.ReadOptionalProperty(tag: "condition", ret&: result->condition);
107 source.ReadProperty(tag: "join_type", ret&: result->type);
108 source.ReadProperty(tag: "ref_type", ret&: result->ref_type);
109 source.ReadProperty(tag: "using_columns", ret&: result->using_columns);
110
111 return std::move(result);
112}
113
114unique_ptr<TableRef> JoinRef::Deserialize(FieldReader &reader) {
115 auto result = make_uniq<JoinRef>(args: JoinRefType::REGULAR);
116 result->left = reader.ReadRequiredSerializable<TableRef>();
117 result->right = reader.ReadRequiredSerializable<TableRef>();
118 result->condition = reader.ReadOptional<ParsedExpression>(default_value: nullptr);
119 result->type = reader.ReadRequired<JoinType>();
120 result->ref_type = reader.ReadRequired<JoinRefType>();
121 result->using_columns = reader.ReadRequiredList<string>();
122 return std::move(result);
123}
124
125} // namespace duckdb
126