Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup changes in support of introducing UNIQUE constraint check #870

Merged
merged 8 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions production/db/core/src/catalog_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ namespace db
return catalog::Getgaia_index(m_obj_ptr->data())->fields();
}

[[nodiscard]] gaia_id_t index_view_t::table_id() const
{
return m_obj_ptr->references()[c_parent_table_ref_offset];
}

table_view_t catalog_core_t::get_table(gaia_id_t table_id)
{
return table_view_t{id_to_ptr(table_id)};
Expand Down Expand Up @@ -175,8 +180,7 @@ list_catalog_obj_reference_chain(gaia_id_t table_id, uint16_t first_offset, uint
auto obj_ptr = id_to_ptr(table_id);
const gaia_id_t* references = obj_ptr->references();
gaia_id_t first_obj_id = references[first_offset];
auto generator = [id = first_obj_id, next_offset]() mutable -> std::optional<T_catalog_obj_view>
{
auto generator = [id = first_obj_id, next_offset]() mutable -> std::optional<T_catalog_obj_view> {
if (id == c_invalid_gaia_id)
{
return std::nullopt;
Expand Down
42 changes: 23 additions & 19 deletions production/db/core/src/index_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <iostream>
#include <utility>

#include "gaia/exceptions.hpp"

#include "gaia_internal/db/catalog_core.hpp"

#include "data_holder.hpp"
Expand Down Expand Up @@ -36,21 +38,21 @@ template <class T_index>
void truncate_index(index_writer_guard_t<T_index>& w, gaia_txn_id_t commit_ts)
{
auto index = w.get_index();
auto end = index.end();
auto iter = index.begin();
auto it_next = index.begin();
auto it_end = index.end();

while (iter != end)
while (it_next != it_end)
{
auto curr_iter = iter++;
auto ts = transactions::txn_metadata_t::get_commit_ts_from_begin_ts(curr_iter->second.txn_id);
auto it_current = it_next++;
auto ts = transactions::txn_metadata_t::get_commit_ts_from_begin_ts(it_current->second.txn_id);

// Ignore invalid txn_ids, txn could be in-flight at the point of testing.
if (ts <= commit_ts && ts != c_invalid_gaia_txn_id)
{
// Only erase entry if each key contains at least one additional entry with the same key.
if (iter != end && curr_iter->first == iter->first)
if (it_next != it_end && it_current->first == it_next->first)
{
iter = index.erase(curr_iter);
it_next = index.erase(it_current);
}
}
}
Expand Down Expand Up @@ -145,6 +147,14 @@ indexes_t::iterator index_builder_t::create_empty_index(gaia_id_t index_id, inde
}
}

template <typename T_index_type>
void update_index_entry(
base_index_t* base_index, bool is_unique, index_key_t&& key, index_record_t record)
{
auto index = static_cast<T_index_type*>(base_index);
index->insert_index_entry(std::move(key), record);
}

void index_builder_t::update_index(gaia_id_t index_id, index_key_t&& key, index_record_t record)
{
ASSERT_PRECONDITION(get_indexes(), "Indexes not initialized");
Expand All @@ -158,20 +168,16 @@ void index_builder_t::update_index(gaia_id_t index_id, index_key_t&& key, index_
it = create_empty_index(index_id, index_view);
}

bool is_unique_index = it->second->is_unique();

switch (it->second->type())
{
case catalog::index_type_t::range:
{
auto index = static_cast<range_index_t*>(it->second.get());
index->insert_index_entry(std::move(key), record);
}
break;
update_index_entry<range_index_t>(it->second.get(), is_unique_index, std::move(key), record);
break;
case catalog::index_type_t::hash:
{
auto index = static_cast<hash_index_t*>(it->second.get());
index->insert_index_entry(std::move(key), record);
}
break;
update_index_entry<hash_index_t>(it->second.get(), is_unique_index, std::move(key), record);
break;
}
}

Expand All @@ -184,13 +190,11 @@ void index_builder_t::update_index(
switch (log_record.operation)
{
case gaia_operation_t::create:
{
index_builder_t::update_index(
index_id,
index_builder_t::make_key(index_id, type_id, payload),
index_builder_t::make_insert_record(log_record.locator, log_record.new_offset));
break;
}
case gaia_operation_t::update:
{
auto old_obj = offset_to_ptr(log_record.old_offset);
Expand Down
2 changes: 1 addition & 1 deletion production/db/inc/index/base_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class index_not_found : public common::gaia_exception
explicit index_not_found(common::gaia_id_t index_id)
{
std::stringstream message;
message << "Cannot find index \"" << index_id << "\".";
message << "Cannot find index '" << index_id << "'.";
m_message = message.str();
}
};
Expand Down
12 changes: 7 additions & 5 deletions production/db/inc/index/index.inc
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,25 @@ std::optional<index_record_t> index_generator_t<T_structure>::operator()()
}

template <typename T_structure, typename T_iterator>
std::shared_ptr<common::iterators::generator_t<index_record_t>> index_t<T_structure, T_iterator>::generator(gaia_txn_id_t txn_id)
std::shared_ptr<common::iterators::generator_t<index_record_t>> index_t<T_structure, T_iterator>::generator(
gaia_txn_id_t txn_id)
{
return std::make_shared<index_generator_t<T_structure>>(get_lock(), m_data, txn_id);
}

// Find physical key corresponding to a logical_key + record or return the end iterator.
template <typename T_structure, typename T_iterator>
typename T_structure::iterator index_t<T_structure, T_iterator>::find_physical_key(index_key_t& key, index_record_t& record)
typename T_structure::iterator index_t<T_structure, T_iterator>::find_physical_key(
index_key_t& key, index_record_t& record)
{
auto it = m_data.find(key);
while (it != m_data.end() && it->first == key)
for (auto it = m_data.find(key);
it != m_data.end() && it->first == key;
++it)
{
if (it->second.locator == record.locator && it->second.txn_id == record.txn_id)
{
return it;
}
++it;
}

return m_data.end();
Expand Down
44 changes: 42 additions & 2 deletions production/inc/gaia/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#pragma once

#include <sstream>

#include "gaia/exception.hpp"

namespace gaia
Expand All @@ -13,10 +15,11 @@ namespace gaia
* \addtogroup Gaia
* @{
*/

namespace common
{
/**
* \addtogroup Common
* \addtogroup common
* @{
*/

Expand All @@ -32,7 +35,7 @@ class api_error : public gaia_exception
/**
* An exception class used for to indicate invalid Gaia configuration settings.
*/
class configuration_error : public gaia::common::gaia_exception
class configuration_error : public gaia_exception
{
public:
explicit configuration_error(const char* key, int value);
Expand All @@ -41,5 +44,42 @@ class configuration_error : public gaia::common::gaia_exception

/*@}*/
} // namespace common

namespace db
{
/**
* \addtogroup db
* @{
*/

namespace index
{
/**
* \addtogroup index
* @{
*/

/**
* An exception class used for to indicate the violation of a UNIQUE constraint.
*/
class unique_constraint_violation : public common::gaia_exception
{
public:
explicit unique_constraint_violation(const char* index_name, const char* table_name)
{
std::stringstream message;
message
<< "UNIQUE constraint violation for index: '" << index_name
<< "' of table '" << table_name << "'.";
m_message = message.str();
}
};

/*@}*/
} // namespace index

/*@}*/
} // namespace db

/*@}*/
} // namespace gaia
3 changes: 3 additions & 0 deletions production/inc/gaia_internal/db/catalog_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,14 @@ struct relationship_view_t : catalog_db_object_view_t

struct index_view_t : catalog_db_object_view_t
{
static constexpr common::reference_offset_t c_parent_table_ref_offset = 0;

using catalog_db_object_view_t::catalog_db_object_view_t;
[[nodiscard]] const char* name() const;
[[nodiscard]] bool unique() const;
[[nodiscard]] catalog::index_type_t type() const;
[[nodiscard]] const flatbuffers::Vector<common::gaia_id_t>* fields() const;
[[nodiscard]] common::gaia_id_t table_id() const;
};

using field_list_t = common::iterators::generator_range_t<field_view_t>;
Expand Down