1#include "duckdb/parser/constraints/foreign_key_constraint.hpp"
2
3#include "duckdb/common/field_writer.hpp"
4#include "duckdb/common/limits.hpp"
5#include "duckdb/parser/keyword_helper.hpp"
6
7namespace duckdb {
8
9ForeignKeyConstraint::ForeignKeyConstraint(vector<string> pk_columns, vector<string> fk_columns, ForeignKeyInfo info)
10 : Constraint(ConstraintType::FOREIGN_KEY), pk_columns(std::move(pk_columns)), fk_columns(std::move(fk_columns)),
11 info(std::move(info)) {
12}
13
14string ForeignKeyConstraint::ToString() const {
15 if (info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) {
16 string base = "FOREIGN KEY (";
17
18 for (idx_t i = 0; i < fk_columns.size(); i++) {
19 if (i > 0) {
20 base += ", ";
21 }
22 base += KeywordHelper::WriteOptionallyQuoted(text: fk_columns[i]);
23 }
24 base += ") REFERENCES ";
25 if (!info.schema.empty()) {
26 base += info.schema;
27 base += ".";
28 }
29 base += info.table;
30 base += "(";
31
32 for (idx_t i = 0; i < pk_columns.size(); i++) {
33 if (i > 0) {
34 base += ", ";
35 }
36 base += KeywordHelper::WriteOptionallyQuoted(text: pk_columns[i]);
37 }
38 base += ")";
39
40 return base;
41 }
42
43 return "";
44}
45
46unique_ptr<Constraint> ForeignKeyConstraint::Copy() const {
47 return make_uniq<ForeignKeyConstraint>(args: pk_columns, args: fk_columns, args: info);
48}
49
50void ForeignKeyConstraint::Serialize(FieldWriter &writer) const {
51 D_ASSERT(pk_columns.size() <= NumericLimits<uint32_t>::Maximum());
52 writer.WriteList<string>(elements: pk_columns);
53 D_ASSERT(fk_columns.size() <= NumericLimits<uint32_t>::Maximum());
54 writer.WriteList<string>(elements: fk_columns);
55 writer.WriteField<ForeignKeyType>(element: info.type);
56 writer.WriteString(val: info.schema);
57 writer.WriteString(val: info.table);
58 writer.WriteIndexList<PhysicalIndex>(elements: info.pk_keys);
59 writer.WriteIndexList<PhysicalIndex>(elements: info.fk_keys);
60}
61
62unique_ptr<Constraint> ForeignKeyConstraint::Deserialize(FieldReader &source) {
63 ForeignKeyInfo read_info;
64 auto pk_columns = source.ReadRequiredList<string>();
65 auto fk_columns = source.ReadRequiredList<string>();
66 read_info.type = source.ReadRequired<ForeignKeyType>();
67 read_info.schema = source.ReadRequired<string>();
68 read_info.table = source.ReadRequired<string>();
69 read_info.pk_keys = source.ReadRequiredIndexList<PhysicalIndex>();
70 read_info.fk_keys = source.ReadRequiredIndexList<PhysicalIndex>();
71
72 // column list parsed constraint
73 return make_uniq<ForeignKeyConstraint>(args&: pk_columns, args&: fk_columns, args: std::move(read_info));
74}
75
76} // namespace duckdb
77