Fix for MOT DDLs in a transaction
This commit is contained in:
@ -31,7 +31,7 @@
|
||||
namespace MOT {
|
||||
IMPLEMENT_CLASS_LOGGER(Index, Storage);
|
||||
|
||||
std::atomic<uint32_t> Index::m_indexCounter(0);
|
||||
std::atomic<uint32_t> MOT::Index::m_indexCounter(0);
|
||||
|
||||
uint64_t Index::GetSize() const
|
||||
{
|
||||
@ -497,4 +497,14 @@ Index* Index::CloneEmpty()
|
||||
|
||||
return clonedIndex;
|
||||
}
|
||||
|
||||
MOTIndexArr::MOTIndexArr(MOT::Table* table)
|
||||
{
|
||||
m_numIndexes = 0;
|
||||
m_table = table;
|
||||
errno_t erc = memset_s(m_indexArr, MAX_NUM_INDEXES * sizeof(MOT::Index*), 0, MAX_NUM_INDEXES * sizeof(MOT::Index*));
|
||||
securec_check(erc, "\0", "\0");
|
||||
erc = memset_s(m_origIx, MAX_NUM_INDEXES * sizeof(uint16_t), 0, MAX_NUM_INDEXES * sizeof(uint16_t));
|
||||
securec_check(erc, "\0", "\0");
|
||||
}
|
||||
} // namespace MOT
|
||||
|
@ -96,6 +96,9 @@ public:
|
||||
m_unique = isUnique;
|
||||
|
||||
m_indexId = m_indexCounter.fetch_add(1, std::memory_order_relaxed);
|
||||
if (m_indexExtId == 0) {
|
||||
m_indexExtId = m_indexId;
|
||||
}
|
||||
if (m_keyLength > MAX_KEY_SIZE)
|
||||
return RC_INDEX_EXCEEDS_MAX_SIZE;
|
||||
|
||||
@ -717,6 +720,57 @@ protected:
|
||||
|
||||
DECLARE_CLASS_LOGGER()
|
||||
};
|
||||
|
||||
/**
|
||||
* @class MOTIndexArr
|
||||
* @brief This class contains a temporary copy of index array of the table.
|
||||
*/
|
||||
class MOTIndexArr {
|
||||
public:
|
||||
explicit MOTIndexArr(MOT::Table* table);
|
||||
|
||||
MOT::Index* GetIndex(uint16_t ix)
|
||||
{
|
||||
if (likely(ix < m_numIndexes)) {
|
||||
return m_indexArr[ix];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16_t GetIndexIx(uint16_t ix)
|
||||
{
|
||||
if (likely(ix < m_numIndexes)) {
|
||||
return m_origIx[ix];
|
||||
}
|
||||
|
||||
return MAX_NUM_INDEXES;
|
||||
}
|
||||
|
||||
void Add(uint16_t ix, MOT::Index* index)
|
||||
{
|
||||
if (likely(m_numIndexes < MAX_NUM_INDEXES)) {
|
||||
m_indexArr[m_numIndexes] = index;
|
||||
m_origIx[m_numIndexes] = ix;
|
||||
m_numIndexes++;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t GetNumIndexes()
|
||||
{
|
||||
return m_numIndexes;
|
||||
}
|
||||
|
||||
MOT::Table* GetTable()
|
||||
{
|
||||
return m_table;
|
||||
}
|
||||
private:
|
||||
MOT::Index* m_indexArr[MAX_NUM_INDEXES];
|
||||
MOT::Table* m_table;
|
||||
uint16_t m_origIx[MAX_NUM_INDEXES];
|
||||
uint16_t m_numIndexes;
|
||||
};
|
||||
} // namespace MOT
|
||||
|
||||
#endif /* INDEX_H */
|
||||
|
@ -138,7 +138,7 @@ void Table::ClearThreadMemoryCache()
|
||||
}
|
||||
}
|
||||
|
||||
void Table::IncIndexColumnUsage(Index* index)
|
||||
void Table::IncIndexColumnUsage(MOT::Index* index)
|
||||
{
|
||||
int16_t const* index_cols = index->GetColumnKeyFields();
|
||||
for (int16_t i = 0; i < index->GetNumFields(); i++) {
|
||||
@ -149,7 +149,7 @@ void Table::IncIndexColumnUsage(Index* index)
|
||||
}
|
||||
}
|
||||
|
||||
void Table::DecIndexColumnUsage(Index* index)
|
||||
void Table::DecIndexColumnUsage(MOT::Index* index)
|
||||
{
|
||||
int16_t const* index_cols = index->GetColumnKeyFields();
|
||||
for (int16_t i = 0; i < index->GetNumFields(); i++) {
|
||||
@ -179,7 +179,7 @@ bool Table::IsTableEmpty(uint32_t tid)
|
||||
return res;
|
||||
}
|
||||
|
||||
void Table::SetPrimaryIndex(Index* index)
|
||||
void Table::SetPrimaryIndex(MOT::Index* index)
|
||||
{
|
||||
if (index != nullptr) {
|
||||
index->SetTable(this);
|
||||
@ -188,11 +188,11 @@ void Table::SetPrimaryIndex(Index* index)
|
||||
m_indexes[0] = index;
|
||||
}
|
||||
|
||||
bool Table::UpdatePrimaryIndex(Index* index, TxnManager* txn, uint32_t tid)
|
||||
bool Table::UpdatePrimaryIndex(MOT::Index* index, TxnManager* txn, uint32_t tid)
|
||||
{
|
||||
if (this->m_primaryIndex) {
|
||||
if (txn == nullptr) {
|
||||
if (DeletePrimaryIndex(this->m_primaryIndex) != RC_OK) {
|
||||
if (DeleteIndex(this->m_primaryIndex) != RC_OK) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -212,15 +212,16 @@ bool Table::UpdatePrimaryIndex(Index* index, TxnManager* txn, uint32_t tid)
|
||||
return true;
|
||||
}
|
||||
|
||||
RC Table::DeletePrimaryIndex(MOT::Index* index)
|
||||
RC Table::DeleteIndex(MOT::Index* index)
|
||||
{
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
DecIndexColumnUsage(index);
|
||||
delete index;
|
||||
|
||||
return RC::RC_OK;
|
||||
}
|
||||
|
||||
bool Table::AddSecondaryIndex(const string& indexName, Index* index, TxnManager* txn, uint32_t tid)
|
||||
bool Table::AddSecondaryIndex(const string& indexName, MOT::Index* index, TxnManager* txn, uint32_t tid)
|
||||
{
|
||||
// OA: Should we check for duplicate indices with same name?
|
||||
// first create secondary index data
|
||||
@ -247,7 +248,7 @@ bool Table::AddSecondaryIndex(const string& indexName, Index* index, TxnManager*
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Table::CreateSecondaryIndexDataNonTransactional(Index* index, uint32_t tid)
|
||||
bool Table::CreateSecondaryIndexDataNonTransactional(MOT::Index* index, uint32_t tid)
|
||||
{
|
||||
MaxKey key;
|
||||
bool ret = true;
|
||||
@ -286,7 +287,7 @@ bool Table::CreateSecondaryIndexDataNonTransactional(Index* index, uint32_t tid)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool Table::CreateSecondaryIndexData(Index* index, TxnManager* txn)
|
||||
bool Table::CreateSecondaryIndexData(MOT::Index* index, TxnManager* txn)
|
||||
{
|
||||
RC status = RC_OK;
|
||||
bool error = false;
|
||||
@ -459,6 +460,7 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
|
||||
|
||||
key = txn->GetTxnKey(ix);
|
||||
if (key == nullptr) {
|
||||
DestroyRow(row);
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Insert Row", "Failed to create primary key");
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
@ -485,6 +487,7 @@ RC Table::InsertRow(Row* row, TxnManager* txn)
|
||||
MOTCurrTxn->DestroyTxnKey(cleanupKeys[j]);
|
||||
}
|
||||
}
|
||||
DestroyRow(row);
|
||||
MOTCurrTxn->Rollback();
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
@ -560,7 +563,7 @@ Row* Table::RemoveKeyFromIndex(Row* row, Sentinel* sentinel, uint64_t tid, GcMan
|
||||
{
|
||||
MaxKey key;
|
||||
Row* OutputRow = nullptr;
|
||||
Index* ix = sentinel->GetIndex();
|
||||
MOT::Index* ix = sentinel->GetIndex();
|
||||
Sentinel* currSentinel = nullptr;
|
||||
MOT_ASSERT(sentinel != nullptr);
|
||||
RC rc = sentinel->RefCountUpdate(DEC, tid);
|
||||
@ -832,12 +835,13 @@ char* Table::DesrializeMeta(char* dataIn, CommonColumnMeta& meta)
|
||||
return dataIn;
|
||||
}
|
||||
|
||||
size_t Table::SerializeItemSize(Index* index)
|
||||
size_t Table::SerializeItemSize(MOT::Index* index)
|
||||
{
|
||||
size_t ret = SerializableSTR::SerializeSize(index->m_name) +
|
||||
SerializablePOD<uint32_t>::SerializeSize(index->m_keyLength) +
|
||||
SerializablePOD<IndexOrder>::SerializeSize(index->m_indexOrder) +
|
||||
SerializablePOD<IndexingMethod>::SerializeSize(index->m_indexingMethod) +
|
||||
SerializablePOD<uint64_t>::SerializeSize(index->m_indexExtId) +
|
||||
SerializablePOD<bool>::SerializeSize(index->GetUnique()) +
|
||||
SerializablePOD<int16_t>::SerializeSize(index->m_numKeyFields) +
|
||||
SerializablePOD<uint32_t>::SerializeSize(index->m_numTableFields) +
|
||||
@ -847,7 +851,7 @@ size_t Table::SerializeItemSize(Index* index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* Table::SerializeItem(char* dataOut, Index* index)
|
||||
char* Table::SerializeItem(char* dataOut, MOT::Index* index)
|
||||
{
|
||||
if (!index || !dataOut) {
|
||||
return nullptr;
|
||||
@ -860,6 +864,7 @@ char* Table::SerializeItem(char* dataOut, Index* index)
|
||||
dataOut = SerializablePOD<uint32_t>::Serialize(dataOut, keyLength);
|
||||
dataOut = SerializablePOD<IndexOrder>::Serialize(dataOut, index->m_indexOrder);
|
||||
dataOut = SerializablePOD<IndexingMethod>::Serialize(dataOut, index->m_indexingMethod);
|
||||
dataOut = SerializablePOD<uint64_t>::Serialize(dataOut, index->m_indexExtId);
|
||||
dataOut = SerializablePOD<bool>::Serialize(dataOut, index->GetUnique());
|
||||
dataOut = SerializablePOD<int16_t>::Serialize(dataOut, index->m_numKeyFields);
|
||||
dataOut = SerializablePOD<uint32_t>::Serialize(dataOut, index->m_numTableFields);
|
||||
@ -869,24 +874,21 @@ char* Table::SerializeItem(char* dataOut, Index* index)
|
||||
return dataOut;
|
||||
}
|
||||
|
||||
RC Table::RemoveSecondaryIndex(char* name, TxnManager* txn)
|
||||
RC Table::RemoveSecondaryIndex(MOT::Index* index, TxnManager* txn)
|
||||
{
|
||||
int rmIx = -1;
|
||||
std::string ixName(name);
|
||||
Index* index = nullptr;
|
||||
RC res = RC_OK;
|
||||
do {
|
||||
SecondaryIndexMap::iterator itr = m_secondaryIndexes.find(ixName);
|
||||
SecondaryIndexMap::iterator itr = m_secondaryIndexes.find(index->GetName());
|
||||
if (MOT_EXPECT_TRUE(itr != m_secondaryIndexes.end())) {
|
||||
index = itr->second;
|
||||
MOT_LOG_DEBUG("logging drop index operation (tableId %u), index name: %s index id = %d \n",
|
||||
GetTableId(),
|
||||
index->GetName().c_str(),
|
||||
index->GetIndexId());
|
||||
m_secondaryIndexes.erase(itr);
|
||||
} else {
|
||||
if (m_numIndexes > 0 && (strcmp(m_indexes[0]->GetName().c_str(), name) == 0)) {
|
||||
MOT_LOG_INFO("Trying to remove primary index %s, not supported", name);
|
||||
if (m_numIndexes > 0 && (strcmp(m_indexes[0]->GetName().c_str(), index->GetName().c_str()) == 0)) {
|
||||
MOT_LOG_INFO("Trying to remove primary index %s, not supported", index->GetName().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -926,6 +928,7 @@ char* Table::DesrializeMeta(char* dataIn, CommonIndexMeta& meta)
|
||||
dataIn = SerializablePOD<uint32_t>::Deserialize(dataIn, meta.m_keyLength);
|
||||
dataIn = SerializablePOD<IndexOrder>::Deserialize(dataIn, meta.m_indexOrder);
|
||||
dataIn = SerializablePOD<IndexingMethod>::Deserialize(dataIn, meta.m_indexingMethod);
|
||||
dataIn = SerializablePOD<uint64_t>::Deserialize(dataIn, meta.m_indexExtId);
|
||||
dataIn = SerializablePOD<bool>::Deserialize(dataIn, meta.m_unique);
|
||||
dataIn = SerializablePOD<int16_t>::Deserialize(dataIn, meta.m_numKeyFields);
|
||||
dataIn = SerializablePOD<uint32_t>::Deserialize(dataIn, meta.m_numTableFields);
|
||||
@ -936,11 +939,11 @@ char* Table::DesrializeMeta(char* dataIn, CommonIndexMeta& meta)
|
||||
return dataIn;
|
||||
}
|
||||
|
||||
RC Table::CreateIndexFromMeta(
|
||||
CommonIndexMeta& meta, bool primary, uint32_t tid, bool addToTable /* = true */, Index** outIndex /* = nullptr */)
|
||||
RC Table::CreateIndexFromMeta(CommonIndexMeta& meta, bool primary, uint32_t tid, bool addToTable /* = true */,
|
||||
MOT::Index** outIndex /* = nullptr */)
|
||||
{
|
||||
IndexTreeFlavor flavor = DEFAULT_TREE_FLAVOR;
|
||||
Index* ix = nullptr;
|
||||
MOT::Index* ix = nullptr;
|
||||
|
||||
MOT_LOG_DEBUG("%s: %s (%s)", __func__, meta.m_name.c_str(), primary ? "primary" : "secondary");
|
||||
if (meta.m_indexingMethod == IndexingMethod::INDEXING_METHOD_TREE) {
|
||||
@ -973,6 +976,7 @@ RC Table::CreateIndexFromMeta(
|
||||
ix->SetFakePrimary(meta.m_fake);
|
||||
ix->SetNumIndexFields(meta.m_numKeyFields);
|
||||
ix->SetTable(this);
|
||||
ix->SetExtId(meta.m_indexExtId);
|
||||
if (ix->IndexInit(meta.m_keyLength, meta.m_unique, meta.m_name, nullptr) != RC_OK) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Create Index from meta-data", "Failed to initialize index");
|
||||
delete ix;
|
||||
@ -1139,7 +1143,7 @@ RC Table::DropImpl()
|
||||
MOT_LOG_DEBUG("DropImpl numIndexes = %d \n", m_numIndexes);
|
||||
for (int i = m_numIndexes - 1; i >= 0; i--) {
|
||||
if (m_indexes[i] != nullptr) {
|
||||
Index* index = m_indexes[i];
|
||||
MOT::Index* index = m_indexes[i];
|
||||
// first remove index from table metadata to prevent it's usage
|
||||
m_indexes[i] = nullptr;
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
|
@ -63,7 +63,7 @@ class alignas(CL_SIZE) Table : public Serializable {
|
||||
// allow privileged access
|
||||
friend TxnManager;
|
||||
friend TxnInsertAction;
|
||||
friend Index;
|
||||
friend MOT::Index;
|
||||
friend RecoveryManager;
|
||||
friend TxnDDLAccess;
|
||||
|
||||
@ -148,7 +148,7 @@ public:
|
||||
* @brief Retrieves the primary index of the table.
|
||||
* @return The index object.
|
||||
*/
|
||||
inline Index* GetPrimaryIndex() const
|
||||
inline MOT::Index* GetPrimaryIndex() const
|
||||
{
|
||||
return m_primaryIndex;
|
||||
}
|
||||
@ -158,9 +158,9 @@ public:
|
||||
* @param indexName The name of the index to retrieve.
|
||||
* @return The secondary index with indicating whether it has unique keys or not.
|
||||
*/
|
||||
inline Index* GetSecondaryIndex(const string& indexName)
|
||||
inline MOT::Index* GetSecondaryIndex(const string& indexName)
|
||||
{
|
||||
Index* result = nullptr;
|
||||
MOT::Index* result = nullptr;
|
||||
SecondaryIndexMap::iterator itr = m_secondaryIndexes.find(indexName);
|
||||
if (MOT_EXPECT_TRUE(itr != m_secondaryIndexes.end())) {
|
||||
result = itr->second;
|
||||
@ -168,12 +168,12 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Index* GetSecondaryIndex(uint16_t ix) const
|
||||
inline MOT::Index* GetSecondaryIndex(uint16_t ix) const
|
||||
{
|
||||
return (Index*)m_indexes[ix];
|
||||
return (MOT::Index*)m_indexes[ix];
|
||||
}
|
||||
|
||||
inline Index* GetIndex(uint16_t ix) const
|
||||
inline MOT::Index* GetIndex(uint16_t ix) const
|
||||
{
|
||||
return m_indexes[ix];
|
||||
}
|
||||
@ -182,7 +182,7 @@ public:
|
||||
* @brief Sets the primary index for the table.
|
||||
* @param index The index to set.
|
||||
*/
|
||||
void SetPrimaryIndex(Index* index);
|
||||
void SetPrimaryIndex(MOT::Index* index);
|
||||
|
||||
/**
|
||||
* @brief Sets the primary index for the table (replaces previously created fake primary.
|
||||
@ -190,7 +190,7 @@ public:
|
||||
* @param txn The current transaction.
|
||||
* @param tid Current thread id
|
||||
*/
|
||||
bool UpdatePrimaryIndex(Index* index, TxnManager* txn, uint32_t tid);
|
||||
bool UpdatePrimaryIndex(MOT::Index* index, TxnManager* txn, uint32_t tid);
|
||||
|
||||
/**
|
||||
* @brief Adds a secondary index to the table.
|
||||
@ -200,7 +200,7 @@ public:
|
||||
* @param tid The identifier of the requesting process/thread.
|
||||
* @return Boolean value denoting success or failure.
|
||||
*/
|
||||
bool AddSecondaryIndex(const string& indexName, Index* index, TxnManager* txn, uint32_t tid);
|
||||
bool AddSecondaryIndex(const string& indexName, MOT::Index* index, TxnManager* txn, uint32_t tid);
|
||||
|
||||
/**
|
||||
* @brief Index a table using a secondary index.
|
||||
@ -216,14 +216,55 @@ public:
|
||||
* @param txn The txn manager object.
|
||||
* @return RC value denoting the operation's completion status.
|
||||
*/
|
||||
RC RemoveSecondaryIndex(char* name, TxnManager* txn);
|
||||
RC RemoveSecondaryIndex(MOT::Index* index, TxnManager* txn);
|
||||
|
||||
/**
|
||||
* @brief Deletes a primary index.
|
||||
* @brief Remove Index from table meta data.
|
||||
* @param index The index to use.
|
||||
* @return void.
|
||||
*/
|
||||
void RemoveSecondaryIndexFromMetaData(MOT::Index* index) {
|
||||
if (!index->IsPrimaryKey()) {
|
||||
uint16_t rmIx = 0;
|
||||
for (uint16_t i = 1; i < m_numIndexes; i++) {
|
||||
if (m_indexes[i] == index) {
|
||||
rmIx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// prevent removing primary by mistake
|
||||
if (rmIx > 0) {
|
||||
m_numIndexes--;
|
||||
for (uint16_t i = rmIx; i < m_numIndexes; i++) {
|
||||
m_indexes[i] = m_indexes[i + 1];
|
||||
}
|
||||
|
||||
m_secondaryIndexes[index->GetName()] = nullptr;
|
||||
m_indexes[m_numIndexes] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add Index to table meta data.
|
||||
* @param index The index to use.
|
||||
* @return void.
|
||||
*/
|
||||
void AddSecondaryIndexToMetaData(MOT::Index* index) {
|
||||
if (!index->IsPrimaryKey()) {
|
||||
m_secondaryIndexes[index->GetName()] = index;
|
||||
m_indexes[m_numIndexes] = index;
|
||||
++m_numIndexes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes an index.
|
||||
* @param the index to remove.
|
||||
* @return RC value denoting the operation's completion status.
|
||||
*/
|
||||
RC DeletePrimaryIndex(MOT::Index* index);
|
||||
RC DeleteIndex(MOT::Index* index);
|
||||
|
||||
/**
|
||||
* @brief Checks if table contains data.
|
||||
@ -262,13 +303,13 @@ public:
|
||||
* @brief Increases the column usage on an index.
|
||||
* @param index The index to perform on.
|
||||
*/
|
||||
void IncIndexColumnUsage(Index* index);
|
||||
void IncIndexColumnUsage(MOT::Index* index);
|
||||
|
||||
/**
|
||||
* @brief Deccreases the column usage on an index.
|
||||
* @param index The index to perform on.
|
||||
*/
|
||||
void DecIndexColumnUsage(Index* index);
|
||||
void DecIndexColumnUsage(MOT::Index* index);
|
||||
|
||||
/**
|
||||
* @brief Retrieves an iterator to the first row in the primary index.
|
||||
@ -288,7 +329,7 @@ public:
|
||||
* @param result The resulting row (indirected through sItem object).
|
||||
* @return Result code denoting success or failure reason.
|
||||
*/
|
||||
inline RC QuerySecondaryIndex(const Index* index, Key const* const& key, void*& result)
|
||||
inline RC QuerySecondaryIndex(const MOT::Index* index, Key const* const& key, void*& result)
|
||||
{
|
||||
RC rc = RC_OK;
|
||||
|
||||
@ -312,7 +353,7 @@ public:
|
||||
* @param pid The identifier of the requesting process/thread.
|
||||
* @return Result code denoting success or failure reason.
|
||||
*/
|
||||
inline RC QuerySecondaryIndex(const Index* index, Key const* const& key, bool matchKey, IndexIterator*& result,
|
||||
inline RC QuerySecondaryIndex(const MOT::Index* index, Key const* const& key, bool matchKey, IndexIterator*& result,
|
||||
bool forwardDirection, uint32_t pid)
|
||||
{
|
||||
RC rc = RC_OK;
|
||||
@ -356,7 +397,7 @@ public:
|
||||
* @param pid The logical identifier of the requesting thread.
|
||||
* @return Return code denoting success or failure reason.
|
||||
*/
|
||||
inline RC FindRowByIndexId(Index* index, Key const* const& key, Sentinel*& result, const uint32_t& pid)
|
||||
inline RC FindRowByIndexId(MOT::Index* index, Key const* const& key, Sentinel*& result, const uint32_t& pid)
|
||||
{
|
||||
RC rc = RC_ERROR;
|
||||
|
||||
@ -473,7 +514,7 @@ public:
|
||||
* @param index The secondary index.
|
||||
* @return The secondary index key length.
|
||||
*/
|
||||
uint16_t GetLengthSecondaryKey(Index* index) const
|
||||
uint16_t GetLengthSecondaryKey(MOT::Index* index) const
|
||||
{
|
||||
return index->GetKeyLength();
|
||||
}
|
||||
@ -519,7 +560,7 @@ public:
|
||||
* @param tid The logical identifier of the requesting thread.
|
||||
* @return Status of the operation.
|
||||
*/
|
||||
bool CreateSecondaryIndexDataNonTransactional(Index* index, uint32_t tid);
|
||||
bool CreateSecondaryIndexDataNonTransactional(MOT::Index* index, uint32_t tid);
|
||||
|
||||
/**
|
||||
* @brief Inserts a new row into transactional storage.
|
||||
@ -787,7 +828,7 @@ private:
|
||||
// we have only index-organized-tables (IOT) so this is the pointer to the index
|
||||
// representing the table
|
||||
/** @var The primary index holding all rows. */
|
||||
Index* m_primaryIndex;
|
||||
MOT::Index* m_primaryIndex;
|
||||
|
||||
/** @var Number of fields in the table schema. */
|
||||
uint32_t m_fieldCnt;
|
||||
@ -807,7 +848,7 @@ private:
|
||||
Column** m_columns = NULL;
|
||||
|
||||
/** @var Secondary index array. */
|
||||
Index** m_indexes = NULL;
|
||||
MOT::Index** m_indexes = NULL;
|
||||
|
||||
/** @var Current table unique identifier. */
|
||||
uint32_t m_tableId = tableCounter++;
|
||||
@ -817,7 +858,7 @@ private:
|
||||
uint64_t m_tableExId;
|
||||
|
||||
/** @typedef Secondary index map (indexed by index name). */
|
||||
typedef std::map<string, Index*> SecondaryIndexMap;
|
||||
typedef std::map<string, MOT::Index*> SecondaryIndexMap;
|
||||
|
||||
/** @var Secondary index map accessed by name. */
|
||||
SecondaryIndexMap m_secondaryIndexes;
|
||||
@ -880,6 +921,8 @@ public:
|
||||
|
||||
IndexingMethod m_indexingMethod;
|
||||
|
||||
uint64_t m_indexExtId;
|
||||
|
||||
int16_t m_numKeyFields;
|
||||
|
||||
uint32_t m_numTableFields;
|
||||
|
@ -611,7 +611,7 @@ void RecoveryManager::FreeRedoSegment(LogSegment* segment)
|
||||
|
||||
bool RecoveryManager::ApplyRedoLog(uint64_t redoLsn, char* data, size_t len)
|
||||
{
|
||||
if (redoLsn < m_lsn) {
|
||||
if (redoLsn <= m_lsn) {
|
||||
// ignore old redo records which are prior to our checkpoint LSN
|
||||
MOT_LOG_DEBUG("ApplyRedoLog - ignoring old redo record. Checkpoint LSN: %lu, redo LSN: %lu", m_lsn, redoLsn);
|
||||
return true;
|
||||
|
@ -522,6 +522,7 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
|
||||
MOTCurrTxn->DestroyTxnKey(cleanupKeys[j]);
|
||||
}
|
||||
}
|
||||
table->DestroyRow(row);
|
||||
MOTCurrTxn->Rollback();
|
||||
return;
|
||||
}
|
||||
@ -541,7 +542,6 @@ void RecoveryManager::InsertRow(uint64_t tableId, uint64_t exId, char* keyData,
|
||||
status = RC_OK;
|
||||
} else if (status == RC_MEMORY_ALLOCATION_ERROR) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Recovery Manager Insert Row", "failed to insert row");
|
||||
table->DestroyRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ InsItem* TxnManager::GetNextInsertItem(Index* index)
|
||||
return m_accessMgr->GetInsertMgr()->GetInsertItem(index);
|
||||
}
|
||||
|
||||
Key* TxnManager::GetTxnKey(Index* index)
|
||||
Key* TxnManager::GetTxnKey(MOT::Index* index)
|
||||
{
|
||||
int size = index->GetAlignedKeyLength() + sizeof(Key);
|
||||
void* buf = MemSessionAlloc(size);
|
||||
@ -429,7 +429,7 @@ void TxnManager::UndoInserts()
|
||||
for (const auto& ra_pair : OrderedSet) {
|
||||
Access* ac = ra_pair.second;
|
||||
if (ac->m_type == AccessType::INS) {
|
||||
Index* index_ = ac->GetSentinel()->GetIndex();
|
||||
MOT::Index* index_ = ac->GetSentinel()->GetIndex();
|
||||
// Row is local and was not inserted in the commit
|
||||
if (index_->GetIndexOrder() == IndexOrder::INDEX_ORDER_PRIMARY) {
|
||||
// Release local row to the GC!!!!!
|
||||
@ -448,7 +448,7 @@ RC TxnManager::RollbackInsert(Access* ac)
|
||||
Sentinel* outputSen = nullptr;
|
||||
RC rc;
|
||||
Sentinel* sentinel = ac->GetSentinel();
|
||||
Index* index_ = sentinel->GetIndex();
|
||||
MOT::Index* index_ = sentinel->GetIndex();
|
||||
|
||||
MOT_ASSERT(sentinel != nullptr);
|
||||
rc = sentinel->RefCountUpdate(DEC, GetThdId());
|
||||
@ -498,8 +498,8 @@ void TxnManager::RollbackDDLs()
|
||||
|
||||
// rollback DDLs in reverse order (avoid rolling back parent object before rolling back child)
|
||||
for (int i = m_txnDdlAccess->Size() - 1; i >= 0; i--) {
|
||||
Index* index = nullptr;
|
||||
Index** indexes = nullptr;
|
||||
MOT::Index* index = nullptr;
|
||||
MOTIndexArr* indexArr = nullptr;
|
||||
Table* table = nullptr;
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->Get(i);
|
||||
switch (ddl_access->GetDDLAccessType()) {
|
||||
@ -516,23 +516,28 @@ void TxnManager::RollbackDDLs()
|
||||
MOT_LOG_INFO("Rollback of drop table %s", table->GetLongTableName().c_str());
|
||||
break;
|
||||
case DDL_ACCESS_TRUNCATE_TABLE:
|
||||
indexes = (Index**)ddl_access->GetEntry();
|
||||
table = indexes[0]->GetTable();
|
||||
MOT_LOG_INFO("Rollback of truncate table %s", table->GetLongTableName().c_str());
|
||||
table->WrLock();
|
||||
for (int idx = 0; idx < table->GetNumIndexes(); idx++) {
|
||||
index = table->m_indexes[idx];
|
||||
table->m_indexes[idx] = indexes[idx];
|
||||
if (idx == 0)
|
||||
table->m_primaryIndex = indexes[idx];
|
||||
else
|
||||
table->m_secondaryIndexes[indexes[idx]->GetName()] = indexes[idx];
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
index->Truncate(true);
|
||||
delete index;
|
||||
indexArr = (MOTIndexArr*)ddl_access->GetEntry();
|
||||
if (indexArr->GetNumIndexes() > 0) {
|
||||
MOT_ASSERT(indexArr->GetNumIndexes() == table->GetNumIndexes());
|
||||
table = indexArr->GetTable();
|
||||
MOT_LOG_INFO("Rollback of truncate table %s", table->GetLongTableName().c_str());
|
||||
table->WrLock();
|
||||
for (int idx = 0; idx < indexArr->GetNumIndexes(); idx++) {
|
||||
uint16_t oldIx = indexArr->GetIndexIx(idx);
|
||||
MOT::Index* oldIndex = indexArr->GetIndex(idx);
|
||||
index = table->m_indexes[oldIx];
|
||||
table->m_indexes[oldIx] = oldIndex;
|
||||
if (idx == 0)
|
||||
table->m_primaryIndex = oldIndex;
|
||||
else
|
||||
table->m_secondaryIndexes[oldIndex->GetName()] = oldIndex;
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
index->Truncate(true);
|
||||
delete index;
|
||||
}
|
||||
table->Unlock();
|
||||
}
|
||||
table->Unlock();
|
||||
delete[] indexes;
|
||||
delete indexArr;
|
||||
break;
|
||||
case DDL_ACCESS_CREATE_INDEX:
|
||||
index = (Index*)ddl_access->GetEntry();
|
||||
@ -543,10 +548,9 @@ void TxnManager::RollbackDDLs()
|
||||
table->WrLock();
|
||||
if (index->IsPrimaryKey()) {
|
||||
table->SetPrimaryIndex(nullptr);
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
table->DeletePrimaryIndex(index);
|
||||
table->DeleteIndex(index);
|
||||
} else {
|
||||
table->RemoveSecondaryIndex((char*)index->GetName().c_str(), this);
|
||||
table->RemoveSecondaryIndex(index, this);
|
||||
}
|
||||
table->Unlock();
|
||||
break;
|
||||
@ -556,11 +560,13 @@ void TxnManager::RollbackDDLs()
|
||||
MOT_LOG_INFO("Rollback of drop index %s for table %s",
|
||||
index->GetName().c_str(),
|
||||
table->GetLongTableName().c_str());
|
||||
table->WrLock();
|
||||
if (index->IsPrimaryKey()) {
|
||||
table->WrLock();
|
||||
table->SetPrimaryIndex(index);
|
||||
table->Unlock();
|
||||
} else {
|
||||
table->AddSecondaryIndexToMetaData(index);
|
||||
}
|
||||
table->Unlock();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -574,8 +580,8 @@ void TxnManager::WriteDDLChanges()
|
||||
if (m_txnDdlAccess->Size() == 0)
|
||||
return;
|
||||
|
||||
Index* index = nullptr;
|
||||
Index** indexes = nullptr;
|
||||
MOT::Index* index = nullptr;
|
||||
MOTIndexArr* indexArr = nullptr;
|
||||
Table* table = nullptr;
|
||||
for (uint16_t i = 0; i < m_txnDdlAccess->Size(); i++) {
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->Get(i);
|
||||
@ -587,18 +593,20 @@ void TxnManager::WriteDDLChanges()
|
||||
GetTableManager()->DropTable((Table*)ddl_access->GetEntry(), m_sessionContext);
|
||||
break;
|
||||
case DDL_ACCESS_TRUNCATE_TABLE:
|
||||
indexes = (Index**)ddl_access->GetEntry();
|
||||
table = indexes[0]->GetTable();
|
||||
table->WrLock();
|
||||
table->m_rowCount = 0;
|
||||
for (int i = 0; i < table->GetNumIndexes(); i++) {
|
||||
index = indexes[i];
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
index->Truncate(true);
|
||||
delete index;
|
||||
indexArr = (MOTIndexArr*)ddl_access->GetEntry();
|
||||
if (indexArr->GetNumIndexes() > 0) {
|
||||
table = indexArr->GetTable();
|
||||
table->WrLock();
|
||||
table->m_rowCount = 0;
|
||||
for (int i = 0; i < indexArr->GetNumIndexes(); i++) {
|
||||
index = indexArr->GetIndex(i);
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
index->Truncate(true);
|
||||
delete index;
|
||||
}
|
||||
table->Unlock();
|
||||
}
|
||||
table->Unlock();
|
||||
delete[] indexes;
|
||||
delete indexArr;
|
||||
break;
|
||||
case DDL_ACCESS_CREATE_INDEX:
|
||||
index = (Index*)ddl_access->GetEntry();
|
||||
@ -616,11 +624,8 @@ void TxnManager::WriteDDLChanges()
|
||||
table->WrLock();
|
||||
if (index->IsPrimaryKey()) {
|
||||
table->SetPrimaryIndex(nullptr);
|
||||
GcManager::ClearIndexElements(index->GetIndexId());
|
||||
table->DeletePrimaryIndex(index);
|
||||
} else {
|
||||
table->RemoveSecondaryIndex((char*)index->GetName().c_str(), this);
|
||||
}
|
||||
table->DeleteIndex(index);
|
||||
table->Unlock();
|
||||
break;
|
||||
default:
|
||||
@ -886,7 +891,7 @@ RC TxnInsertAction::ExecuteOptimisticInsert(Row* row)
|
||||
while (currentItem != EndCursor()) {
|
||||
isInserted = true;
|
||||
isMappedToCache = false;
|
||||
bool res = reinterpret_cast<Index*>(currentItem->m_index)
|
||||
bool res = reinterpret_cast<MOT::Index*>(currentItem->m_index)
|
||||
->IndexInsert(pIndexInsertResult, currentItem->m_key, m_manager->GetThdId(), rc);
|
||||
if (unlikely(rc == RC_MEMORY_ALLOCATION_ERROR)) {
|
||||
ReportError(rc);
|
||||
@ -953,7 +958,7 @@ end:
|
||||
if (isInserted == true) {
|
||||
if (isMappedToCache == false) {
|
||||
RC rc = pIndexInsertResult->RefCountUpdate(DEC, m_manager->GetThdId());
|
||||
Index* index_ = pIndexInsertResult->GetIndex();
|
||||
MOT::Index* index_ = pIndexInsertResult->GetIndex();
|
||||
if (rc == RC::RC_INDEX_DELETE) {
|
||||
// Memory reclamation need to release the key from the primary sentinel back to the pool
|
||||
MOT_ASSERT(pIndexInsertResult->GetCounter() == 0);
|
||||
@ -1022,6 +1027,8 @@ Table* TxnManager::GetTableByExternalId(uint64_t id)
|
||||
switch (ddl_access->GetDDLAccessType()) {
|
||||
case DDL_ACCESS_CREATE_TABLE:
|
||||
return (Table*)ddl_access->GetEntry();
|
||||
case DDL_ACCESS_TRUNCATE_TABLE:
|
||||
return ((MOTIndexArr*)ddl_access->GetEntry())->GetTable();
|
||||
case DDL_ACCESS_DROP_TABLE:
|
||||
return nullptr;
|
||||
default:
|
||||
@ -1034,19 +1041,7 @@ Table* TxnManager::GetTableByExternalId(uint64_t id)
|
||||
|
||||
Index* TxnManager::GetIndexByExternalId(uint64_t table_id, uint64_t index_id)
|
||||
{
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(index_id);
|
||||
if (ddl_access != nullptr) {
|
||||
switch (ddl_access->GetDDLAccessType()) {
|
||||
case DDL_ACCESS_CREATE_INDEX:
|
||||
return (Index*)ddl_access->GetEntry();
|
||||
case DDL_ACCESS_DROP_INDEX:
|
||||
return nullptr;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Table* table = GetTableManager()->GetTableByExternal(table_id);
|
||||
Table* table = GetTableByExternalId(table_id);
|
||||
if (table == nullptr) {
|
||||
return nullptr;
|
||||
} else {
|
||||
@ -1054,38 +1049,6 @@ Index* TxnManager::GetIndexByExternalId(uint64_t table_id, uint64_t index_id)
|
||||
}
|
||||
}
|
||||
|
||||
Index* TxnManager::GetIndex(uint64_t table_id, uint16_t position)
|
||||
{
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(table_id);
|
||||
Table* table = GetTableByExternalId(table_id);
|
||||
return GetIndex(table, position);
|
||||
}
|
||||
|
||||
Index* TxnManager::GetIndex(Table* table, uint16_t position)
|
||||
{
|
||||
MOT_ASSERT(table != nullptr);
|
||||
Index* index = table->GetIndex(position);
|
||||
MOT_ASSERT(index != nullptr);
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(index->GetExtId());
|
||||
if (ddl_access != nullptr) {
|
||||
switch (ddl_access->GetDDLAccessType()) {
|
||||
case DDL_ACCESS_CREATE_INDEX:
|
||||
return index;
|
||||
case DDL_ACCESS_DROP_INDEX:
|
||||
return nullptr;
|
||||
default:
|
||||
// should print error, the only index operation which are supported
|
||||
// are create and drop
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (index->GetIsCommited())
|
||||
return index;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RC TxnManager::CreateTable(Table* table)
|
||||
{
|
||||
TxnDDLAccess::DDLAccess* ddl_access =
|
||||
@ -1104,15 +1067,11 @@ RC TxnManager::DropTable(Table* table)
|
||||
RC res = RC_OK;
|
||||
|
||||
// we allocate all memory before action takes place, so that if memory allocation fails, we can report error safely
|
||||
TxnDDLAccess::DDLAccess* new_ddl_access = nullptr;
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(table->GetTableExId());
|
||||
if ((ddl_access == nullptr) || (ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE)) {
|
||||
new_ddl_access =
|
||||
new (std::nothrow) TxnDDLAccess::DDLAccess(table->GetTableExId(), DDL_ACCESS_DROP_TABLE, (void*)table);
|
||||
if (new_ddl_access == nullptr) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Drop Table", "Failed to allocate DDL Access object");
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
TxnDDLAccess::DDLAccess* new_ddl_access =
|
||||
new (std::nothrow) TxnDDLAccess::DDLAccess(table->GetTableExId(), DDL_ACCESS_DROP_TABLE, (void*)table);
|
||||
if (new_ddl_access == nullptr) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Drop Table", "Failed to allocate DDL Access object");
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
if (!m_isLightSession) {
|
||||
@ -1132,48 +1091,7 @@ RC TxnManager::DropTable(Table* table)
|
||||
}
|
||||
}
|
||||
|
||||
if (ddl_access != nullptr) {
|
||||
if (ddl_access->GetDDLAccessType() == DDL_ACCESS_CREATE_TABLE) {
|
||||
// this table was created in this transaction, can delete it from the ddl_access
|
||||
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
||||
// check for create and drop index ddls
|
||||
for (uint16_t i = 0; i < table->GetNumIndexes(); i++) {
|
||||
m_txnDdlAccess->EraseByOid(table->GetIndex(i)->GetExtId());
|
||||
}
|
||||
// erase drop fake primary index if exists
|
||||
TxnDDLAccess::DDLAccess* iddl = m_txnDdlAccess->GetByOid(table->GetTableExId() + 1);
|
||||
if (iddl != nullptr) {
|
||||
MOT::Index* ix = (MOT::Index*)iddl->GetEntry();
|
||||
GcManager::ClearIndexElements(ix->GetIndexId());
|
||||
table->DeletePrimaryIndex(ix);
|
||||
}
|
||||
table->DropImpl();
|
||||
RemoveTableFromStat(table);
|
||||
delete table;
|
||||
} else if (ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE) {
|
||||
Index** indexes = (Index**)ddl_access->GetEntry();
|
||||
table->WrLock();
|
||||
for (int i = 0; i < table->GetNumIndexes(); i++) {
|
||||
Index* newIndex = table->m_indexes[i];
|
||||
Index* oldIndex = indexes[i];
|
||||
table->m_indexes[i] = oldIndex;
|
||||
if (i != 0)
|
||||
table->m_secondaryIndexes[oldIndex->GetName()] = oldIndex;
|
||||
else
|
||||
table->m_primaryIndex = oldIndex;
|
||||
// need to check if need to release memory in a different way? GC?
|
||||
// assumption is the we deleted all rows
|
||||
delete newIndex;
|
||||
}
|
||||
table->Unlock();
|
||||
delete[] indexes;
|
||||
m_txnDdlAccess->EraseByOid(table->GetTableExId());
|
||||
m_txnDdlAccess->Add(new_ddl_access);
|
||||
}
|
||||
} else {
|
||||
m_txnDdlAccess->Add(new_ddl_access);
|
||||
}
|
||||
|
||||
m_txnDdlAccess->Add(new_ddl_access);
|
||||
return RC_OK;
|
||||
}
|
||||
|
||||
@ -1182,32 +1100,28 @@ RC TxnManager::TruncateTable(Table* table)
|
||||
RC res = RC_OK;
|
||||
if (m_isLightSession) // really?
|
||||
return res;
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(table->GetTableExId());
|
||||
if (ddl_access != nullptr) {
|
||||
// must be create table or truncate table
|
||||
MOT_ASSERT(ddl_access->GetDDLAccessType() == DDL_ACCESS_CREATE_TABLE ||
|
||||
ddl_access->GetDDLAccessType() == DDL_ACCESS_TRUNCATE_TABLE);
|
||||
// this is a table that we created or truncated before, should remove all the rows
|
||||
// belonging to this table from the access and continue
|
||||
TxnOrderedSet_t& access_row_set = m_accessMgr->GetOrderedRowSet();
|
||||
TxnOrderedSet_t::iterator it = access_row_set.begin();
|
||||
while (it != access_row_set.end()) {
|
||||
Access* ac = it->second;
|
||||
if (ac->GetTxnRow()->GetTable() == table) {
|
||||
if (ac->m_type == INS)
|
||||
RollbackInsert(ac);
|
||||
it = access_row_set.erase(it);
|
||||
// need to perform index clean-up!
|
||||
m_accessMgr->PubReleaseAccess(ac);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
|
||||
TxnOrderedSet_t& access_row_set = m_accessMgr->GetOrderedRowSet();
|
||||
TxnOrderedSet_t::iterator it = access_row_set.begin();
|
||||
while (it != access_row_set.end()) {
|
||||
Access* ac = it->second;
|
||||
if (ac->GetTxnRow()->GetTable() == table) {
|
||||
if (ac->m_type == INS)
|
||||
RollbackInsert(ac);
|
||||
it = access_row_set.erase(it);
|
||||
// need to perform index clean-up!
|
||||
m_accessMgr->PubReleaseAccess(ac);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
} else {
|
||||
Index** indexes = nullptr;
|
||||
indexes = new (std::nothrow) Index*[MAX_NUM_INDEXES];
|
||||
if (indexes == nullptr) {
|
||||
// print error, clould not allocate memory
|
||||
}
|
||||
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(table->GetTableExId());
|
||||
if (ddl_access == nullptr) {
|
||||
MOTIndexArr* indexesArr = nullptr;
|
||||
indexesArr = new (std::nothrow) MOTIndexArr(table);
|
||||
if (indexesArr == nullptr) {
|
||||
// print error, could not allocate memory
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM,
|
||||
"Truncate Table",
|
||||
"Failed to allocate memory for %u index objects",
|
||||
@ -1216,36 +1130,39 @@ RC TxnManager::TruncateTable(Table* table)
|
||||
}
|
||||
// allocate DDL before work and fail immediately if required
|
||||
ddl_access = new (std::nothrow)
|
||||
TxnDDLAccess::DDLAccess(table->GetTableExId(), DDL_ACCESS_TRUNCATE_TABLE, (void*)indexes);
|
||||
TxnDDLAccess::DDLAccess(table->GetTableExId(), DDL_ACCESS_TRUNCATE_TABLE, (void*)indexesArr);
|
||||
if (ddl_access == nullptr) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Truncate Table", "Failed to allocate memory for DDL Access object");
|
||||
delete[] indexes;
|
||||
delete indexesArr;
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
for (int i = 0; i < table->GetNumIndexes(); i++) {
|
||||
Index* index_copy = table->GetIndex(i)->CloneEmpty();
|
||||
for (uint16_t i = 0; i < table->GetNumIndexes(); i++) {
|
||||
MOT::Index* index = table->GetIndex(i);
|
||||
MOT::Index* index_copy = index->CloneEmpty();
|
||||
if (index_copy == nullptr) {
|
||||
// print error, clould not allocate memory for index
|
||||
// print error, could not allocate memory for index
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM,
|
||||
"Truncate Table",
|
||||
"Failed to clone empty index %s",
|
||||
table->GetIndex(i)->GetName().c_str());
|
||||
for (int j = 0; j < i; j++) {
|
||||
index->GetName().c_str());
|
||||
for (uint16_t j = 0; j < indexesArr->GetNumIndexes(); j++) {
|
||||
// cleanup of previous created indexes copy
|
||||
Index* newIndex = table->m_indexes[j];
|
||||
Index* oldIndex = indexes[j];
|
||||
table->m_indexes[j] = oldIndex;
|
||||
if (j != 0) // is secondary
|
||||
MOT::Index* oldIndex = indexesArr->GetIndex(j);
|
||||
uint16_t oldIx = indexesArr->GetIndexIx(j);
|
||||
MOT::Index* newIndex = table->m_indexes[oldIx];
|
||||
table->m_indexes[oldIx] = oldIndex;
|
||||
if (oldIx != 0) // is secondary
|
||||
table->m_secondaryIndexes[oldIndex->GetName()] = oldIndex;
|
||||
else // is primary
|
||||
table->m_primaryIndex = oldIndex;
|
||||
delete newIndex;
|
||||
}
|
||||
delete ddl_access;
|
||||
delete indexesArr;
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
indexes[i] = table->GetIndex(i);
|
||||
indexesArr->Add(i, index);
|
||||
table->m_indexes[i] = index_copy;
|
||||
if (i != 0) // is secondary
|
||||
table->m_secondaryIndexes[index_copy->GetName()] = index_copy;
|
||||
@ -1258,7 +1175,7 @@ RC TxnManager::TruncateTable(Table* table)
|
||||
return res;
|
||||
}
|
||||
|
||||
RC TxnManager::CreateIndex(Table* table, Index* index, bool is_primary)
|
||||
RC TxnManager::CreateIndex(Table* table, MOT::Index* index, bool is_primary)
|
||||
{
|
||||
|
||||
// allocate DDL before work and fail immediately if required
|
||||
@ -1314,42 +1231,35 @@ RC TxnManager::CreateIndex(Table* table, Index* index, bool is_primary)
|
||||
RC TxnManager::DropIndex(MOT::Index* index)
|
||||
{
|
||||
// allocate DDL before work and fail immediately if required
|
||||
TxnDDLAccess::DDLAccess* new_ddl_access = nullptr;
|
||||
TxnDDLAccess::DDLAccess* ddl_access = m_txnDdlAccess->GetByOid(index->GetExtId());
|
||||
if (ddl_access == nullptr) {
|
||||
new_ddl_access =
|
||||
new (std::nothrow) TxnDDLAccess::DDLAccess(index->GetExtId(), DDL_ACCESS_DROP_INDEX, (void*)index);
|
||||
if (new_ddl_access == nullptr) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Drop Index", "Failed to allocate DDL Access object");
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
TxnDDLAccess::DDLAccess* new_ddl_access =
|
||||
new (std::nothrow) TxnDDLAccess::DDLAccess(index->GetExtId(), DDL_ACCESS_DROP_INDEX, (void*)index);
|
||||
if (new_ddl_access == nullptr) {
|
||||
MOT_REPORT_ERROR(MOT_ERROR_OOM, "Drop Index", "Failed to allocate DDL Access object");
|
||||
return RC_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
RC res = RC_OK;
|
||||
Table* table = index->GetTable();
|
||||
|
||||
if (!index->IsPrimaryKey()) {
|
||||
RollbackSecondaryIndexInsert(index);
|
||||
}
|
||||
|
||||
if (ddl_access != nullptr) {
|
||||
// this index was created in this transaction, can delete it from the ddl_access
|
||||
// table->removeSecondaryIndex also performs releases the object
|
||||
m_txnDdlAccess->EraseByOid(index->GetExtId());
|
||||
if (index->IsPrimaryKey()) {
|
||||
res = table->DeletePrimaryIndex(index);
|
||||
} else {
|
||||
res = table->RemoveSecondaryIndex((char*)index->GetName().c_str(), this);
|
||||
}
|
||||
if (res != RC_OK) {
|
||||
// print Error
|
||||
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "Drop Index", "Failed to remove secondary index");
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
m_txnDdlAccess->Add(new_ddl_access);
|
||||
if (!m_isLightSession && !index->IsPrimaryKey()) {
|
||||
TxnOrderedSet_t& access_row_set = m_accessMgr->GetOrderedRowSet();
|
||||
TxnOrderedSet_t::iterator it = access_row_set.begin();
|
||||
while (it != access_row_set.end()) {
|
||||
Access* ac = it->second;
|
||||
if (ac->GetSentinel()->GetIndex() == index) {
|
||||
if (ac->m_type == INS)
|
||||
RollbackInsert(ac);
|
||||
it = access_row_set.erase(it);
|
||||
// need to perform index clean-up!
|
||||
m_accessMgr->PubReleaseAccess(ac);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table->RemoveSecondaryIndexFromMetaData(index);
|
||||
m_txnDdlAccess->Add(new_ddl_access);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -515,8 +515,6 @@ private:
|
||||
public:
|
||||
Table* GetTableByExternalId(uint64_t id);
|
||||
Index* GetIndexByExternalId(uint64_t table_id, uint64_t index_id);
|
||||
Index* GetIndex(uint64_t table_id, uint16_t position);
|
||||
Index* GetIndex(Table* table, uint16_t position);
|
||||
RC CreateTable(Table* table);
|
||||
RC DropTable(Table* table);
|
||||
RC CreateIndex(Table* table, Index* index, bool is_primary);
|
||||
@ -591,7 +589,7 @@ public:
|
||||
bool m_isLightSession;
|
||||
|
||||
/** @var In case of unique violation this will be set to a violating index */
|
||||
Index* m_errIx;
|
||||
MOT::Index* m_errIx;
|
||||
|
||||
/** @var In case of error this will contain the exact error code */
|
||||
RC m_err;
|
||||
|
@ -96,9 +96,14 @@ TxnDDLAccess::DDLAccess* TxnDDLAccess::Get(uint16_t index)
|
||||
|
||||
TxnDDLAccess::DDLAccess* TxnDDLAccess::GetByOid(uint64_t oid)
|
||||
{
|
||||
for (int i = 0; i < m_size; i++)
|
||||
if (m_accessList[i]->GetOid() == oid)
|
||||
if (m_size == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
for (int i = m_size - 1; i >= 0; i--) {
|
||||
if (m_accessList[i]->GetOid() == oid) {
|
||||
return m_accessList[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1170,12 +1170,10 @@ bool MOTAdaptor::SetMatchingExpr(
|
||||
MOTFdwStateSt* state, MatchIndexArr* marr, int16_t colId, KEY_OPER op, Expr* expr, Expr* parent, bool set_local)
|
||||
{
|
||||
bool res = false;
|
||||
MOT::TxnManager* txn = GetSafeTxn();
|
||||
uint16_t numIx = state->m_table->GetNumIndexes();
|
||||
|
||||
for (uint16_t i = 0; i < numIx; i++) {
|
||||
// MOT::Index *ix = state->table->getIndex(i);
|
||||
MOT::Index* ix = txn->GetIndex(state->m_table, i);
|
||||
MOT::Index *ix = state->m_table->GetIndex(i);
|
||||
if (ix != nullptr && ix->IsFieldPresent(colId)) {
|
||||
if (marr->m_idx[i] == nullptr) {
|
||||
marr->m_idx[i] = (MatchIndex*)palloc0(sizeof(MatchIndex));
|
||||
@ -1211,7 +1209,6 @@ inline int32_t MOTAdaptor::AddParam(List** params, Expr* expr)
|
||||
|
||||
MatchIndex* MOTAdaptor::GetBestMatchIndex(MOTFdwStateSt* festate, MatchIndexArr* marr, int numClauses, bool setLocal)
|
||||
{
|
||||
MOT::TxnManager* txn = GetSafeTxn();
|
||||
MatchIndex* best = nullptr;
|
||||
double bestCost = INT_MAX;
|
||||
uint16_t numIx = festate->m_table->GetNumIndexes();
|
||||
@ -1282,7 +1279,7 @@ MatchIndex* MOTAdaptor::GetBestMatchIndex(MOTFdwStateSt* festate, MatchIndexArr*
|
||||
}
|
||||
if (best != nullptr && best->m_ix != nullptr) {
|
||||
for (uint16_t i = 0; i < numIx; i++) {
|
||||
if (best->m_ix == txn->GetIndex(festate->m_table, i)) {
|
||||
if (best->m_ix == festate->m_table->GetIndex(i)) {
|
||||
best->m_ixPosition = i;
|
||||
break;
|
||||
}
|
||||
@ -2030,7 +2027,7 @@ uint64_t MOTAdaptor::GetTableIndexSize(uint64_t tabId, uint64_t ixId)
|
||||
}
|
||||
|
||||
if (ixId > 0) {
|
||||
ix = txn->GetIndexByExternalId(tabId, ixId);
|
||||
ix = tab->GetIndexByExtId(ixId);
|
||||
if (ix == nullptr) {
|
||||
ereport(ERROR,
|
||||
(errmodule(MOD_MM),
|
||||
@ -2893,7 +2890,7 @@ void MatchIndex::Deserialize(ListCell* cell, uint64_t exTableID)
|
||||
m_ixPosition = (int32_t)((Const*)lfirst(cell))->constvalue;
|
||||
MOT::Table* table = txn->GetTableByExternalId(exTableID);
|
||||
if (table != nullptr) {
|
||||
m_ix = txn->GetIndex(table, m_ixPosition);
|
||||
m_ix = table->GetIndex(m_ixPosition);
|
||||
}
|
||||
|
||||
cell = lnext(cell);
|
||||
|
Reference in New Issue
Block a user