diff --git a/src/gausskernel/storage/mot/core/src/storage/index/index.cpp b/src/gausskernel/storage/mot/core/src/storage/index/index.cpp index 8d276cdeb71990f7c84c3f0d8c47310dc8eafdfb..96d16d4efaed041b55464678df77d754b7a166f8 100644 --- a/src/gausskernel/storage/mot/core/src/storage/index/index.cpp +++ b/src/gausskernel/storage/mot/core/src/storage/index/index.cpp @@ -31,7 +31,7 @@ namespace MOT { IMPLEMENT_CLASS_LOGGER(Index, Storage); -std::atomic Index::m_indexCounter(0); +std::atomic 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 diff --git a/src/gausskernel/storage/mot/core/src/storage/index/index.h b/src/gausskernel/storage/mot/core/src/storage/index/index.h index db7f3336aa13fd93192572e0013228e82b947f46..8d2316d6578a64c16f65cdeb2374b31dba1af824 100644 --- a/src/gausskernel/storage/mot/core/src/storage/index/index.h +++ b/src/gausskernel/storage/mot/core/src/storage/index/index.h @@ -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 */ diff --git a/src/gausskernel/storage/mot/core/src/storage/table.cpp b/src/gausskernel/storage/mot/core/src/storage/table.cpp index f84d0a5dc1a2ac50ffc02123e01ebf36649115ae..2b0e76107105b54cbb6454880367c208e1d38db7 100644 --- a/src/gausskernel/storage/mot/core/src/storage/table.cpp +++ b/src/gausskernel/storage/mot/core/src/storage/table.cpp @@ -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::SerializeSize(index->m_keyLength) + SerializablePOD::SerializeSize(index->m_indexOrder) + SerializablePOD::SerializeSize(index->m_indexingMethod) + + SerializablePOD::SerializeSize(index->m_indexExtId) + SerializablePOD::SerializeSize(index->GetUnique()) + SerializablePOD::SerializeSize(index->m_numKeyFields) + SerializablePOD::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::Serialize(dataOut, keyLength); dataOut = SerializablePOD::Serialize(dataOut, index->m_indexOrder); dataOut = SerializablePOD::Serialize(dataOut, index->m_indexingMethod); + dataOut = SerializablePOD::Serialize(dataOut, index->m_indexExtId); dataOut = SerializablePOD::Serialize(dataOut, index->GetUnique()); dataOut = SerializablePOD::Serialize(dataOut, index->m_numKeyFields); dataOut = SerializablePOD::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::Deserialize(dataIn, meta.m_keyLength); dataIn = SerializablePOD::Deserialize(dataIn, meta.m_indexOrder); dataIn = SerializablePOD::Deserialize(dataIn, meta.m_indexingMethod); + dataIn = SerializablePOD::Deserialize(dataIn, meta.m_indexExtId); dataIn = SerializablePOD::Deserialize(dataIn, meta.m_unique); dataIn = SerializablePOD::Deserialize(dataIn, meta.m_numKeyFields); dataIn = SerializablePOD::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()); diff --git a/src/gausskernel/storage/mot/core/src/storage/table.h b/src/gausskernel/storage/mot/core/src/storage/table.h index 036b3508840f9c2e62a453ea8e08a1b894e6411d..eb68e8679a0a78cb9a6c1294433805c01a40136a 100644 --- a/src/gausskernel/storage/mot/core/src/storage/table.h +++ b/src/gausskernel/storage/mot/core/src/storage/table.h @@ -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 SecondaryIndexMap; + typedef std::map 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; diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp index 56fb03677e998673e8e8b94ee79ccfbaaeec200e..38e6ff80ffd94faa2ebf20f1efcab7dca67b4489 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_ops.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_ops.cpp index c3be70a63b566a0e1c44ec26e5ad30437d7d32ad..4d40976ccacbc810222bd4a42076ec764bc8625e 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_ops.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_ops.cpp @@ -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); } } diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp index 64fe08692a892e6be7c0c2865916d33608cb7ed4..d7831dabe303a2a652e94471dd161a5660d32c2f 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp @@ -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(currentItem->m_index) + bool res = reinterpret_cast(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; + 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++; + } } - } else { - m_txnDdlAccess->Add(new_ddl_access); } + table->RemoveSecondaryIndexFromMetaData(index); + m_txnDdlAccess->Add(new_ddl_access); return res; } diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn.h b/src/gausskernel/storage/mot/core/src/system/transaction/txn.h index eddec1d76a51a0897194f0d9e73e4c98cdeb53ec..fb42dafb0aaa0d38306a0e481c86045bd1124b1e 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn.h +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn.h @@ -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; diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn_ddl_access.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn_ddl_access.cpp index 1c445060b21a0095aa0860d923fd520ec6683b7e..b870b3e2c2a33324d353b950c822562095535658 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn_ddl_access.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn_ddl_access.cpp @@ -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; } diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp index 6bd0c843855fdcb712ecd79f90d50bc59d75b673..6a873b1bb37b8a8e63ce52a93109a6a7ff79a487 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp @@ -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);