1#include "duckdb/storage/index.hpp"
2#include "duckdb/execution/expression_executor.hpp"
3#include "duckdb/planner/expression_iterator.hpp"
4#include "duckdb/planner/expression/bound_columnref_expression.hpp"
5#include "duckdb/planner/expression/bound_reference_expression.hpp"
6#include "duckdb/storage/table/append_state.hpp"
7#include "duckdb/execution/index/art/art.hpp"
8
9namespace duckdb {
10
11Index::Index(AttachedDatabase &db, IndexType type, TableIOManager &table_io_manager,
12 const vector<column_t> &column_ids_p, const vector<unique_ptr<Expression>> &unbound_expressions,
13 IndexConstraintType constraint_type_p)
14
15 : type(type), table_io_manager(table_io_manager), column_ids(column_ids_p), constraint_type(constraint_type_p),
16 db(db), buffer_manager(BufferManager::GetBufferManager(db)) {
17
18 for (auto &expr : unbound_expressions) {
19 types.push_back(x: expr->return_type.InternalType());
20 logical_types.push_back(x: expr->return_type);
21 auto unbound_expression = expr->Copy();
22 bound_expressions.push_back(x: BindExpression(expr: unbound_expression->Copy()));
23 this->unbound_expressions.emplace_back(args: std::move(unbound_expression));
24 }
25 for (auto &bound_expr : bound_expressions) {
26 executor.AddExpression(expr: *bound_expr);
27 }
28
29 // create the column id set
30 column_id_set.insert(first: column_ids.begin(), last: column_ids.end());
31}
32
33void Index::InitializeLock(IndexLock &state) {
34 state.index_lock = unique_lock<mutex>(lock);
35}
36
37PreservedError Index::Append(DataChunk &entries, Vector &row_identifiers) {
38 IndexLock state;
39 InitializeLock(state);
40 return Append(state, entries, row_identifiers);
41}
42
43void Index::Delete(DataChunk &entries, Vector &row_identifiers) {
44 IndexLock state;
45 InitializeLock(state);
46 Delete(state, entries, row_identifiers);
47}
48
49bool Index::MergeIndexes(Index &other_index) {
50
51 IndexLock state;
52 InitializeLock(state);
53
54 switch (this->type) {
55 case IndexType::ART:
56 return Cast<ART>().MergeIndexes(state, other_index);
57 default:
58 throw InternalException("Unimplemented index type for merge");
59 }
60}
61
62string Index::VerifyAndToString(const bool only_verify) {
63
64 IndexLock state;
65 InitializeLock(state);
66
67 switch (this->type) {
68 case IndexType::ART:
69 return Cast<ART>().VerifyAndToString(state, only_verify);
70 default:
71 throw InternalException("Unimplemented index type for VerifyAndToString");
72 }
73}
74
75void Index::Vacuum() {
76
77 IndexLock state;
78 InitializeLock(state);
79
80 switch (this->type) {
81 case IndexType::ART:
82 return Cast<ART>().Vacuum(state);
83 default:
84 throw InternalException("Unimplemented index type for vacuum");
85 }
86}
87
88void Index::ExecuteExpressions(DataChunk &input, DataChunk &result) {
89 executor.Execute(input, result);
90}
91
92unique_ptr<Expression> Index::BindExpression(unique_ptr<Expression> expr) {
93 if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
94 auto &bound_colref = expr->Cast<BoundColumnRefExpression>();
95 return make_uniq<BoundReferenceExpression>(args&: expr->return_type, args&: column_ids[bound_colref.binding.column_index]);
96 }
97 ExpressionIterator::EnumerateChildren(
98 expression&: *expr, callback: [this](unique_ptr<Expression> &expr) { expr = BindExpression(expr: std::move(expr)); });
99 return expr;
100}
101
102bool Index::IndexIsUpdated(const vector<PhysicalIndex> &column_ids) const {
103 for (auto &column : column_ids) {
104 if (column_id_set.find(x: column.index) != column_id_set.end()) {
105 return true;
106 }
107 }
108 return false;
109}
110
111BlockPointer Index::Serialize(MetaBlockWriter &writer) {
112 throw NotImplementedException("The implementation of this index serialization does not exist.");
113}
114
115string Index::AppendRowError(DataChunk &input, idx_t index) {
116 string error;
117 for (idx_t c = 0; c < input.ColumnCount(); c++) {
118 if (c > 0) {
119 error += ", ";
120 }
121 error += input.GetValue(col_idx: c, index).ToString();
122 }
123 return error;
124}
125
126} // namespace duckdb
127