1#include "duckdb/storage/table/table_index_list.hpp"
2#include "duckdb/storage/data_table.hpp"
3#include "duckdb/common/types/conflict_manager.hpp"
4#include "duckdb/execution/index/art/art.hpp"
5
6namespace duckdb {
7void TableIndexList::AddIndex(unique_ptr<Index> index) {
8 D_ASSERT(index);
9 lock_guard<mutex> lock(indexes_lock);
10 indexes.push_back(x: std::move(index));
11}
12
13void TableIndexList::RemoveIndex(Index &index) {
14 lock_guard<mutex> lock(indexes_lock);
15
16 for (idx_t index_idx = 0; index_idx < indexes.size(); index_idx++) {
17 auto &index_entry = indexes[index_idx];
18 if (index_entry.get() == &index) {
19 indexes.erase(position: indexes.begin() + index_idx);
20 break;
21 }
22 }
23}
24
25bool TableIndexList::Empty() {
26 lock_guard<mutex> lock(indexes_lock);
27 return indexes.empty();
28}
29
30idx_t TableIndexList::Count() {
31 lock_guard<mutex> lock(indexes_lock);
32 return indexes.size();
33}
34
35void TableIndexList::Move(TableIndexList &other) {
36 D_ASSERT(indexes.empty());
37 indexes = std::move(other.indexes);
38}
39
40Index *TableIndexList::FindForeignKeyIndex(const vector<PhysicalIndex> &fk_keys, ForeignKeyType fk_type) {
41 Index *result = nullptr;
42 Scan(callback: [&](Index &index) {
43 if (DataTable::IsForeignKeyIndex(fk_keys, index, fk_type)) {
44 result = &index;
45 }
46 return false;
47 });
48 return result;
49}
50
51void TableIndexList::VerifyForeignKey(const vector<PhysicalIndex> &fk_keys, DataChunk &chunk,
52 ConflictManager &conflict_manager) {
53 auto fk_type = conflict_manager.LookupType() == VerifyExistenceType::APPEND_FK
54 ? ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE
55 : ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE;
56
57 // check whether or not the chunk can be inserted or deleted into the referenced table' storage
58 auto index = FindForeignKeyIndex(fk_keys, fk_type);
59 if (!index) {
60 throw InternalException("Internal Foreign Key error: could not find index to verify...");
61 }
62 conflict_manager.SetIndexCount(1);
63 index->CheckConstraintsForChunk(input&: chunk, conflict_manager);
64}
65
66vector<column_t> TableIndexList::GetRequiredColumns() {
67 lock_guard<mutex> lock(indexes_lock);
68 set<column_t> unique_indexes;
69 for (auto &index : indexes) {
70 for (auto col_index : index->column_ids) {
71 unique_indexes.insert(x: col_index);
72 }
73 }
74 vector<column_t> result;
75 result.reserve(n: unique_indexes.size());
76 for (auto column_index : unique_indexes) {
77 result.emplace_back(args&: column_index);
78 }
79 return result;
80}
81
82vector<BlockPointer> TableIndexList::SerializeIndexes(duckdb::MetaBlockWriter &writer) {
83 vector<BlockPointer> blocks_info;
84 for (auto &index : indexes) {
85 blocks_info.emplace_back(args: index->Serialize(writer));
86 }
87 return blocks_info;
88}
89
90} // namespace duckdb
91