1#include "duckdb/parser/tableref.hpp"
2
3#include "duckdb/common/printer.hpp"
4#include "duckdb/common/field_writer.hpp"
5#include "duckdb/parser/tableref/list.hpp"
6#include "duckdb/common/serializer/format_serializer.hpp"
7#include "duckdb/common/serializer/format_deserializer.hpp"
8#include "duckdb/common/to_string.hpp"
9
10namespace duckdb {
11
12string TableRef::BaseToString(string result) const {
13 vector<string> column_name_alias;
14 return BaseToString(result: std::move(result), column_name_alias);
15}
16
17string TableRef::BaseToString(string result, const vector<string> &column_name_alias) const {
18 if (!alias.empty()) {
19 result += StringUtil::Format(fmt_str: " AS %s", params: SQLIdentifier(alias));
20 }
21 if (!column_name_alias.empty()) {
22 D_ASSERT(!alias.empty());
23 result += "(";
24 for (idx_t i = 0; i < column_name_alias.size(); i++) {
25 if (i > 0) {
26 result += ", ";
27 }
28 result += KeywordHelper::WriteOptionallyQuoted(text: column_name_alias[i]);
29 }
30 result += ")";
31 }
32 if (sample) {
33 result += " TABLESAMPLE " + EnumUtil::ToString(value: sample->method);
34 result += "(" + sample->sample_size.ToString() + " " + string(sample->is_percentage ? "PERCENT" : "ROWS") + ")";
35 if (sample->seed >= 0) {
36 result += "REPEATABLE (" + to_string(val: sample->seed) + ")";
37 }
38 }
39
40 return result;
41}
42
43bool TableRef::Equals(const TableRef &other) const {
44 return type == other.type && alias == other.alias && SampleOptions::Equals(a: sample.get(), b: other.sample.get());
45}
46
47void TableRef::Serialize(Serializer &serializer) const {
48 FieldWriter writer(serializer);
49 writer.WriteField<TableReferenceType>(element: type);
50 writer.WriteString(val: alias);
51 writer.WriteOptional(element: sample);
52 Serialize(writer);
53 writer.Finalize();
54}
55
56void TableRef::FormatSerialize(FormatSerializer &serializer) const {
57 serializer.WriteProperty(tag: "type", value: type);
58 serializer.WriteProperty(tag: "alias", value: alias);
59 serializer.WriteOptionalProperty(tag: "sample", ptr: sample);
60}
61
62unique_ptr<TableRef> TableRef::FormatDeserialize(FormatDeserializer &deserializer) {
63 auto type = deserializer.ReadProperty<TableReferenceType>(tag: "type");
64 auto alias = deserializer.ReadProperty<string>(tag: "alias");
65 auto sample = deserializer.ReadOptionalProperty<unique_ptr<SampleOptions>>(tag: "sample");
66
67 unique_ptr<TableRef> result;
68
69 switch (type) {
70 case TableReferenceType::BASE_TABLE:
71 result = BaseTableRef::FormatDeserialize(source&: deserializer);
72 break;
73 case TableReferenceType::JOIN:
74 result = JoinRef::FormatDeserialize(source&: deserializer);
75 break;
76 case TableReferenceType::SUBQUERY:
77 result = SubqueryRef::FormatDeserialize(source&: deserializer);
78 break;
79 case TableReferenceType::TABLE_FUNCTION:
80 result = TableFunctionRef::FormatDeserialize(source&: deserializer);
81 break;
82 case TableReferenceType::EMPTY:
83 result = EmptyTableRef::FormatDeserialize(source&: deserializer);
84 break;
85 case TableReferenceType::EXPRESSION_LIST:
86 result = ExpressionListRef::FormatDeserialize(source&: deserializer);
87 break;
88 case TableReferenceType::PIVOT:
89 result = PivotRef::FormatDeserialize(source&: deserializer);
90 break;
91 case TableReferenceType::CTE:
92 case TableReferenceType::INVALID:
93 throw InternalException("Unsupported type for TableRef::FormatDeserialize");
94 }
95 result->alias = alias;
96 result->sample = std::move(sample);
97 return result;
98}
99
100unique_ptr<TableRef> TableRef::Deserialize(Deserializer &source) {
101 FieldReader reader(source);
102
103 auto type = reader.ReadRequired<TableReferenceType>();
104 auto alias = reader.ReadRequired<string>();
105 auto sample = reader.ReadOptional<SampleOptions>(default_value: nullptr);
106 unique_ptr<TableRef> result;
107 switch (type) {
108 case TableReferenceType::BASE_TABLE:
109 result = BaseTableRef::Deserialize(source&: reader);
110 break;
111 case TableReferenceType::JOIN:
112 result = JoinRef::Deserialize(source&: reader);
113 break;
114 case TableReferenceType::SUBQUERY:
115 result = SubqueryRef::Deserialize(source&: reader);
116 break;
117 case TableReferenceType::TABLE_FUNCTION:
118 result = TableFunctionRef::Deserialize(source&: reader);
119 break;
120 case TableReferenceType::EMPTY:
121 result = EmptyTableRef::Deserialize(source&: reader);
122 break;
123 case TableReferenceType::EXPRESSION_LIST:
124 result = ExpressionListRef::Deserialize(source&: reader);
125 break;
126 case TableReferenceType::PIVOT:
127 result = PivotRef::Deserialize(source&: reader);
128 break;
129 case TableReferenceType::CTE:
130 case TableReferenceType::INVALID:
131 throw InternalException("Unsupported type for TableRef::Deserialize");
132 }
133 reader.Finalize();
134
135 result->alias = alias;
136 result->sample = std::move(sample);
137 return result;
138}
139
140void TableRef::CopyProperties(TableRef &target) const {
141 D_ASSERT(type == target.type);
142 target.alias = alias;
143 target.query_location = query_location;
144 target.sample = sample ? sample->Copy() : nullptr;
145}
146
147void TableRef::Print() {
148 Printer::Print(str: ToString());
149}
150
151bool TableRef::Equals(const unique_ptr<TableRef> &left, const unique_ptr<TableRef> &right) {
152 if (left.get() == right.get()) {
153 return true;
154 }
155 if (!left || !right) {
156 return false;
157 }
158 return left->Equals(other: *right);
159}
160
161} // namespace duckdb
162