8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Reworked index root page related code, added some debugging

This commit is contained in:
AlexPeshkoff 2025-01-17 20:29:41 +03:00
parent aaaa7ba427
commit 28bdd0bf99
5 changed files with 145 additions and 66 deletions

View File

@ -531,6 +531,32 @@ Cached::Index* RelationPermanent::lookupIndex(thread_db* tdbb, MetaId id, Object
} }
PageNumber RelationPermanent::getIndexRootPage(thread_db* tdbb)
{
/**************************************
*
* g e t _ r o o t _ p a g e
*
**************************************
*
* Functional description
* Find the root page for a relation.
*
**************************************/
SET_TDBB(tdbb);
RelationPages* relPages = getPages(tdbb);
SLONG page = relPages->rel_index_root;
if (!page)
{
DPM_scan_pages(tdbb);
page = relPages->rel_index_root;
}
return PageNumber(relPages->rel_pg_space_id, page);
}
const char* IndexPermanent::c_name() const const char* IndexPermanent::c_name() const
{ {
// Here we use MetaName feature - pointers in it are DBB-lifetime stable // Here we use MetaName feature - pointers in it are DBB-lifetime stable

View File

@ -872,8 +872,8 @@ public:
rel_file = f; rel_file = f;
} }
void getRelLockKey(thread_db* tdbb, UCHAR* key);
void getRelLockKey(thread_db* tdbb, UCHAR* key); PageNumber getIndexRootPage(thread_db* tdbb);
bool isSystem() const; bool isSystem() const;
bool isTemporary() const; bool isTemporary() const;

View File

@ -219,7 +219,7 @@ static void delete_tree(thread_db*, MetaId, MetaId, PageNumber, PageNumber);
static DSC* eval(thread_db*, const ValueExprNode*, DSC*, bool*); static DSC* eval(thread_db*, const ValueExprNode*, DSC*, bool*);
static ULONG fast_load(thread_db*, IndexCreation&, SelectivityList&); static ULONG fast_load(thread_db*, IndexCreation&, SelectivityList&);
static index_root_page* fetch_root(thread_db*, WIN*, const RelationPermanent*, const RelationPages*); static const index_root_page* fetch_root(thread_db*, WIN*, const RelationPermanent*, const RelationPages*);
static UCHAR* find_node_start_point(btree_page*, temporary_key*, UCHAR*, USHORT*, static UCHAR* find_node_start_point(btree_page*, temporary_key*, UCHAR*, USHORT*,
bool, bool, bool = false, RecordNumber = NO_VALUE); bool, bool, bool = false, RecordNumber = NO_VALUE);
@ -250,6 +250,74 @@ static void update_selectivity(index_root_page*, MetaId, const SelectivityList&)
static void checkForLowerKeySkip(bool&, const bool, const IndexNode&, const temporary_key&, static void checkForLowerKeySkip(bool&, const bool, const IndexNode&, const temporary_key&,
const index_desc&, const IndexRetrieval*); const index_desc&, const IndexRetrieval*);
//#define DEBUG_INDEX_ROOT
namespace {
#ifdef DEBUG_INDEX_ROOT
class Flags
{
public:
static const char* state(const index_root_page::irt_repeat& rpt)
{
if (!rpt.isUsed())
return "Unused";
switch (rpt.getState())
{
case irt_in_progress: return "irt_in_progress";
case irt_commit: return "irt_commit";
case irt_drop: return "irt_drop";
case irt_rollback: return "irt_rollback";
case irt_normal: return "irt_normal";
}
return "** UNKNOWN **";
}
};
void dumpIndexRoot(const char* up, const char* from, thread_db* tdbb, WIN* window, const index_root_page* root)
{
if (root->irt_relation > 127)
{
auto* rel = MetadataCache::lookupRelation(tdbb, root->irt_relation, 0);
printf("\n%sFrom %s page=%" ULONGFORMAT " len=%d rel %s(%d)\n",
up, from, window->win_page.getPageNum(), root->irt_count, rel->c_name(), root->irt_relation);
for (MetaId i = 0; i < root->irt_count; ++i)
{
auto* idp = rel->lookupIndex(tdbb, i, 0);
auto& rpt = root->irt_rpt[i];
printf("Index %d %s root %d tra % " SQUADFORMAT " %s\n", i, idp ? idp->getName().c_str() : "not-found",
rpt.getRoot(), rpt.getTransaction(), Flags::state(rpt));
}
printf("\n");
}
}
#else
void dumpIndexRoot(...) { }
#endif
}
index_root_page* BTR_fetch_root_for_update(const char* from, thread_db* tdbb, WIN* window)
{
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_write, pag_root);
dumpIndexRoot("Upd", from, tdbb, window, root);
return root;
}
const index_root_page* BTR_fetch_root(const char* from, thread_db* tdbb, WIN* window)
{
const index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_read, pag_root);
dumpIndexRoot("", from, tdbb, window, root);
return root;
}
// IndexRetrieval class // IndexRetrieval class
@ -409,7 +477,7 @@ void BTR_all(thread_db* tdbb, Cached::Relation* relation, IndexDescList& idxList
WIN window(relPages->rel_pg_space_id, -1); WIN window(relPages->rel_pg_space_id, -1);
index_root_page* const root = fetch_root(tdbb, &window, relation, relPages); const index_root_page* const root = fetch_root(tdbb, &window, relation, relPages);
if (!root) if (!root)
return; return;
@ -505,9 +573,8 @@ void BTR_create(thread_db* tdbb,
// Index is created. Go back to the index root page and update it to // Index is created. Go back to the index root page and update it to
// point to the index. // point to the index.
RelationPages* const relPages = relation->getPages(tdbb); WIN window(getPermanent(relation)->getIndexRootPage(tdbb));
WIN window(relPages->rel_pg_space_id, relPages->rel_index_root); index_root_page* const root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
index_root_page* const root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_root);
CCH_MARK(tdbb, &window); CCH_MARK(tdbb, &window);
switch(creation.forRollback) switch(creation.forRollback)
@ -592,7 +659,7 @@ static void badState [[noreturn]] (const index_root_page::irt_repeat* irt_desc,
} }
void BTR_mark_index_for_delete(thread_db* tdbb, WIN* window, MetaId id) void BTR_mark_index_for_delete(thread_db* tdbb, Cached::Relation* relation, MetaId id)
{ {
/************************************** /**************************************
* *
@ -608,15 +675,15 @@ void BTR_mark_index_for_delete(thread_db* tdbb, WIN* window, MetaId id)
const Database* dbb = tdbb->getDatabase(); const Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
// Get index descriptor. If index doesn't exist, just leave. WIN window(relation->getIndexRootPage(tdbb));
index_root_page* const root = (index_root_page*) window->win_buffer; index_root_page* const root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
// Get index descriptor. If index doesn't exist, just leave.
if (id < root->irt_count) if (id < root->irt_count)
{ {
index_root_page::irt_repeat* irt_desc = root->irt_rpt + id; index_root_page::irt_repeat* irt_desc = root->irt_rpt + id;
CCH_MARK(tdbb, window); CCH_MARK(tdbb, &window);
const PageNumber next(window->win_page.getPageSpaceID(), irt_desc->getRoot());
jrd_tra* tra = tdbb->getTransaction(); jrd_tra* tra = tdbb->getTransaction();
fb_assert(tra); fb_assert(tra);
@ -660,11 +727,11 @@ void BTR_mark_index_for_delete(thread_db* tdbb, WIN* window, MetaId id)
} }
} }
CCH_RELEASE(tdbb, window); CCH_RELEASE(tdbb, &window);
} }
void BTR_activate_index(thread_db* tdbb, WIN* window, MetaId id) void BTR_activate_index(thread_db* tdbb, Cached::Relation* relation, MetaId id)
{ {
/************************************** /**************************************
* *
@ -680,15 +747,15 @@ void BTR_activate_index(thread_db* tdbb, WIN* window, MetaId id)
const Database* dbb = tdbb->getDatabase(); const Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
// Get index descriptor. If index doesn't exist, just leave. WIN window(relation->getIndexRootPage(tdbb));
index_root_page* const root = (index_root_page*) window->win_buffer; index_root_page* const root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
// Get index descriptor. If index doesn't exist, just leave.
if (id < root->irt_count) if (id < root->irt_count)
{ {
index_root_page::irt_repeat* irt_desc = root->irt_rpt + id; index_root_page::irt_repeat* irt_desc = root->irt_rpt + id;
CCH_MARK(tdbb, window); CCH_MARK(tdbb, &window);
const PageNumber next(window->win_page.getPageSpaceID(), irt_desc->getRoot());
jrd_tra* tra = tdbb->getTransaction(); jrd_tra* tra = tdbb->getTransaction();
fb_assert(tra); fb_assert(tra);
@ -733,11 +800,11 @@ void BTR_activate_index(thread_db* tdbb, WIN* window, MetaId id)
} }
} }
CCH_RELEASE(tdbb, window); CCH_RELEASE(tdbb, &window);
} }
bool BTR_description(thread_db* tdbb, Cached::Relation* relation, index_root_page* root, index_desc* idx, bool BTR_description(thread_db* tdbb, Cached::Relation* relation, const index_root_page* root, index_desc* idx,
MetaId id) MetaId id)
{ {
/************************************** /**************************************
@ -1263,7 +1330,7 @@ btree_page* BTR_find_page(thread_db* tdbb,
fb_assert(window->win_page.getPageSpaceID() == relPages->rel_pg_space_id); fb_assert(window->win_page.getPageSpaceID() == relPages->rel_pg_space_id);
window->win_page = relPages->rel_index_root; window->win_page = relPages->rel_index_root;
index_root_page* rpage = (index_root_page*) CCH_FETCH(tdbb, window, LCK_read, pag_root); const index_root_page* rpage = BTR_fetch_root(FB_FUNCTION, tdbb, window);
if (!BTR_description(tdbb, retrieval->getPermRelation(), rpage, idx, retrieval->irb_index)) if (!BTR_description(tdbb, retrieval->getPermRelation(), rpage, idx, retrieval->irb_index))
{ {
@ -1373,7 +1440,7 @@ void BTR_insert(thread_db* tdbb, WIN* root_window, index_insertion* insertion)
// The top of the index has split. We need to make a new level and // The top of the index has split. We need to make a new level and
// update the index root page. Oh boy. // update the index root page. Oh boy.
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, root_window, LCK_write, pag_root); index_root_page* root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, root_window);
window.win_page = root->irt_rpt[idx->idx_id].getRoot(); window.win_page = root->irt_rpt[idx->idx_id].getRoot();
bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index); bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index);
@ -1849,7 +1916,7 @@ bool BTR_lookup(thread_db* tdbb, Cached::Relation* relation, MetaId id, index_de
SET_TDBB(tdbb); SET_TDBB(tdbb);
WIN window(relPages->rel_pg_space_id, -1); WIN window(relPages->rel_pg_space_id, -1);
index_root_page* const root = fetch_root(tdbb, &window, relation, relPages); const index_root_page* const root = fetch_root(tdbb, &window, relation, relPages);
if (!root) if (!root)
return false; return false;
@ -2142,9 +2209,9 @@ bool BTR_next_index(thread_db* tdbb, Cached::Relation* relation, jrd_tra* transa
else else
id = idx->idx_id + 1; id = idx->idx_id + 1;
index_root_page* root; const index_root_page* root;
if (window->win_bdb) if (window->win_bdb)
root = (index_root_page*) window->win_buffer; root = (const index_root_page*) window->win_buffer;
else else
{ {
RelationPages* const relPages = transaction ? RelationPages* const relPages = transaction ?
@ -2205,8 +2272,8 @@ bool BTR_next_index(thread_db* tdbb, Cached::Relation* relation, jrd_tra* transa
if (rls) if (rls)
CCH_RELEASE(tdbb, window); CCH_RELEASE(tdbb, window);
root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_write, pag_root); auto* root_write = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, window);
index_root_page::irt_repeat* irt_write = root->irt_rpt + id; index_root_page::irt_repeat* irt_write = root_write->irt_rpt + id;
const TraNumber descTrans = irt_write->getTransaction(); const TraNumber descTrans = irt_write->getTransaction();
bool delIndex = false; bool delIndex = false;
@ -2261,7 +2328,7 @@ bool BTR_next_index(thread_db* tdbb, Cached::Relation* relation, jrd_tra* transa
else else
CCH_RELEASE(tdbb, window); CCH_RELEASE(tdbb, window);
root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_read, pag_root); root = BTR_fetch_root(FB_FUNCTION, tdbb, window);
if (delIndex) if (delIndex)
continue; continue;
@ -2323,7 +2390,7 @@ void BTR_remove(thread_db* tdbb, WIN* root_window, index_insertion* insertion)
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
CCH_RELEASE(tdbb, root_window); CCH_RELEASE(tdbb, root_window);
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, root_window, LCK_write, pag_root); index_root_page* root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, root_window);
page = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index); page = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index);
// get the page number of the child, and check to make sure // get the page number of the child, and check to make sure
@ -2400,7 +2467,7 @@ void BTR_reserve_slot(thread_db* tdbb, IndexCreation& creation, IndexCreateLock&
fb_assert((!use_idx_id) || (idx->idx_id <= dbb->dbb_max_idx)); fb_assert((!use_idx_id) || (idx->idx_id <= dbb->dbb_max_idx));
WIN window(relPages->rel_pg_space_id, relPages->rel_index_root); WIN window(relPages->rel_pg_space_id, relPages->rel_index_root);
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_root); index_root_page* root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
CCH_MARK(tdbb, &window); CCH_MARK(tdbb, &window);
// check that we create no more indexes than will fit on a single root page // check that we create no more indexes than will fit on a single root page
@ -2513,7 +2580,7 @@ void BTR_selectivity(thread_db* tdbb, Cached::Relation* relation, MetaId id, Sel
RelationPages* relPages = relation->getPages(tdbb); RelationPages* relPages = relation->getPages(tdbb);
WIN window(relPages->rel_pg_space_id, -1); WIN window(relPages->rel_pg_space_id, -1);
index_root_page* root = fetch_root(tdbb, &window, relation, relPages); const index_root_page* root = fetch_root(tdbb, &window, relation, relPages);
if (!root) if (!root)
return; return;
@ -2690,9 +2757,9 @@ void BTR_selectivity(thread_db* tdbb, Cached::Relation* relation, MetaId id, Sel
// Store the selectivity on the root page // Store the selectivity on the root page
window.win_page = relPages->rel_index_root; window.win_page = relPages->rel_index_root;
window.win_flags = 0; window.win_flags = 0;
root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_root); auto* write_root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
CCH_MARK(tdbb, &window); CCH_MARK(tdbb, &window);
update_selectivity(root, id, selectivity); update_selectivity(write_root, id, selectivity);
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
} }
@ -4621,8 +4688,8 @@ static ULONG fast_load(thread_db* tdbb,
} }
static index_root_page* fetch_root(thread_db* tdbb, WIN* window, const RelationPermanent* relation, static const index_root_page* fetch_root(thread_db* tdbb, WIN* window, const RelationPermanent* relation,
const RelationPages* relPages) const RelationPages* relPages)
{ {
/************************************** /**************************************
* *
@ -4651,7 +4718,7 @@ static index_root_page* fetch_root(thread_db* tdbb, WIN* window, const RelationP
window->win_page = relPages->rel_index_root; window->win_page = relPages->rel_index_root;
} }
return (index_root_page*) CCH_FETCH(tdbb, window, LCK_read, pag_root); return BTR_fetch_root(FB_FUNCTION, tdbb, window);
} }

View File

@ -30,11 +30,11 @@
#include "../jrd/exe.h" #include "../jrd/exe.h"
void BTR_all(Jrd::thread_db*, Jrd::Cached::Relation*, Jrd::IndexDescList&, Jrd::RelationPages*); void BTR_all(Jrd::thread_db*, Jrd::Cached::Relation*, Jrd::IndexDescList&, Jrd::RelationPages*);
void BTR_activate_index(Jrd::thread_db*, Jrd::win*, MetaId); void BTR_activate_index(Jrd::thread_db*, Jrd::Cached::Relation*, MetaId);
void BTR_complement_key(Jrd::temporary_key*); void BTR_complement_key(Jrd::temporary_key*);
void BTR_create(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::SelectivityList&); void BTR_create(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::SelectivityList&);
bool BTR_delete_index(Jrd::thread_db*, Jrd::win*, MetaId); bool BTR_delete_index(Jrd::thread_db*, Jrd::win*, MetaId);
bool BTR_description(Jrd::thread_db*, Jrd::Cached::Relation*, Ods::index_root_page*, Jrd::index_desc*, MetaId); bool BTR_description(Jrd::thread_db*, Jrd::Cached::Relation*, const Ods::index_root_page*, Jrd::index_desc*, MetaId);
bool BTR_check_condition(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*); bool BTR_check_condition(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*);
DSC* BTR_eval_expression(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*, bool&); DSC* BTR_eval_expression(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*, bool&);
void BTR_evaluate(Jrd::thread_db*, const Jrd::IndexRetrieval*, Jrd::RecordBitmap**, Jrd::RecordBitmap*); void BTR_evaluate(Jrd::thread_db*, const Jrd::IndexRetrieval*, Jrd::RecordBitmap**, Jrd::RecordBitmap*);
@ -50,11 +50,13 @@ bool BTR_lookup(Jrd::thread_db*, Jrd::Cached::Relation*, MetaId, Jrd::index_desc
Jrd::idx_e BTR_make_key(Jrd::thread_db*, USHORT, const Jrd::ValueExprNode* const*, const Jrd::index_desc*, Jrd::idx_e BTR_make_key(Jrd::thread_db*, USHORT, const Jrd::ValueExprNode* const*, const Jrd::index_desc*,
Jrd::temporary_key*, USHORT); Jrd::temporary_key*, USHORT);
void BTR_make_null_key(Jrd::thread_db*, const Jrd::index_desc*, Jrd::temporary_key*); void BTR_make_null_key(Jrd::thread_db*, const Jrd::index_desc*, Jrd::temporary_key*);
void BTR_mark_index_for_delete(Jrd::thread_db* tdbb, Jrd::win* window, MetaId id); void BTR_mark_index_for_delete(Jrd::thread_db* tdbb, Jrd::Cached::Relation*, MetaId id);
bool BTR_next_index(Jrd::thread_db*, Jrd::Cached::Relation*, Jrd::jrd_tra*, Jrd::index_desc*, Jrd::win*); bool BTR_next_index(Jrd::thread_db*, Jrd::Cached::Relation*, Jrd::jrd_tra*, Jrd::index_desc*, Jrd::win*);
void BTR_remove(Jrd::thread_db*, Jrd::win*, Jrd::index_insertion*); void BTR_remove(Jrd::thread_db*, Jrd::win*, Jrd::index_insertion*);
void BTR_reserve_slot(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::IndexCreateLock&); void BTR_reserve_slot(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::IndexCreateLock&);
void BTR_selectivity(Jrd::thread_db*, Jrd::Cached::Relation*, MetaId, Jrd::SelectivityList&); void BTR_selectivity(Jrd::thread_db*, Jrd::Cached::Relation*, MetaId, Jrd::SelectivityList&);
bool BTR_types_comparable(const dsc& target, const dsc& source); bool BTR_types_comparable(const dsc& target, const dsc& source);
Ods::index_root_page* BTR_fetch_root_for_update(const char* from, Jrd::thread_db* tdbb, Jrd::win* window);
const Ods::index_root_page* BTR_fetch_root(const char* from, Jrd::thread_db* tdbb, Jrd::win* window);
#endif // JRD_BTR_PROTO_H #endif // JRD_BTR_PROTO_H

View File

@ -149,8 +149,7 @@ void IDX_check_access(thread_db* tdbb, CompilerScratch* csb, Cached::Relation* v
referenced_window.win_page = get_root_page(tdbb, getPermanent(referenced_relation)); referenced_window.win_page = get_root_page(tdbb, getPermanent(referenced_relation));
referenced_window.win_flags = 0; referenced_window.win_flags = 0;
index_root_page* referenced_root = auto* referenced_root = BTR_fetch_root(FB_FUNCTION, tdbb, &referenced_window);
(index_root_page*) CCH_FETCH(tdbb, &referenced_window, LCK_read, pag_root);
index_desc referenced_idx; index_desc referenced_idx;
if (!BTR_description(tdbb, getPermanent(referenced_relation), referenced_root, if (!BTR_description(tdbb, getPermanent(referenced_relation), referenced_root,
&referenced_idx, index_id)) &referenced_idx, index_id))
@ -205,7 +204,7 @@ bool IDX_check_master_types(thread_db* tdbb, index_desc& idx, Cached::Relation*
// get the index root page for the partner relation // get the index root page for the partner relation
WIN window(get_root_page(tdbb, partner_relation)); WIN window(get_root_page(tdbb, partner_relation));
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_root); auto* root = BTR_fetch_root(FB_FUNCTION, tdbb, &window);
// get the description of the partner index // get the description of the partner index
const bool ok = BTR_description(tdbb, partner_relation, root, &partner_idx, idx.idx_primary_index); const bool ok = BTR_description(tdbb, partner_relation, root, &partner_idx, idx.idx_primary_index);
@ -980,10 +979,7 @@ void IDX_create_index(thread_db* tdbb,
void IDX_activate_index(thread_db* tdbb, Cached::Relation* relation, MetaId id) void IDX_activate_index(thread_db* tdbb, Cached::Relation* relation, MetaId id)
{ {
WIN window(get_root_page(tdbb, relation)); BTR_activate_index(tdbb, relation, id);
CCH_FETCH(tdbb, &window, LCK_write, pag_root);
BTR_activate_index(tdbb, &window, id);
} }
@ -1003,12 +999,10 @@ void IDX_delete_index(thread_db* tdbb, Cached::Relation* relation, MetaId id)
signal_index_deletion(tdbb, relation, id); signal_index_deletion(tdbb, relation, id);
WIN window(get_root_page(tdbb, relation)); BTR_mark_index_for_delete(tdbb, relation, id);
CCH_FETCH(tdbb, &window, LCK_write, pag_root);
BTR_mark_index_for_delete(tdbb, &window, id);
/* ?????????????????? /* ??????????????????
if ((getPermanent(relation)->rel_flags & REL_temp_conn) && (relation->getPages(tdbb)->rel_instance_id != 0) && if ((relation->rel_flags & REL_temp_conn) && (relation->getPages(tdbb)->rel_instance_id != 0) &&
tree_exists) tree_exists)
{ {
IndexPermanent* idx_lock = relation->getIndexLock(tdbb, id); IndexPermanent* idx_lock = relation->getIndexLock(tdbb, id);
@ -1037,14 +1031,14 @@ void IDX_delete_indices(thread_db* tdbb, RelationPermanent* relation, RelationPa
fb_assert(relPages->rel_index_root); fb_assert(relPages->rel_index_root);
WIN window(relPages->rel_pg_space_id, relPages->rel_index_root); WIN window(relPages->rel_pg_space_id, relPages->rel_index_root);
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_root); index_root_page* root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
// const bool is_temp = (relation->rel_flags & REL_temp_conn) && (relPages->rel_instance_id != 0); // const bool is_temp = (relation->rel_flags & REL_temp_conn) && (relPages->rel_instance_id != 0);
for (USHORT i = 0; i < root->irt_count; i++) for (USHORT i = 0; i < root->irt_count; i++)
{ {
const bool tree_exists = BTR_delete_index(tdbb, &window, i); const bool tree_exists = BTR_delete_index(tdbb, &window, i);
root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_root); root = BTR_fetch_root_for_update(FB_FUNCTION, tdbb, &window);
/* !!!!!!!!!!!!!! /* !!!!!!!!!!!!!!
if (is_temp && tree_exists) if (is_temp && tree_exists)
{ {
@ -1126,7 +1120,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
WIN window(get_root_page(tdbb, getPermanent(rpb->rpb_relation))); WIN window(get_root_page(tdbb, getPermanent(rpb->rpb_relation)));
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_root); auto* root = BTR_fetch_root(FB_FUNCTION, tdbb, &window);
for (USHORT i = 0; i < root->irt_count; i++) for (USHORT i = 0; i < root->irt_count; i++)
{ {
@ -1206,7 +1200,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
// Get rid of index node // Get rid of index node
BTR_remove(tdbb, &window, &insertion); BTR_remove(tdbb, &window, &insertion);
root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_root); root = BTR_fetch_root(FB_FUNCTION, tdbb, &window);
if (stack1.hasMore(1)) if (stack1.hasMore(1))
BTR_description(tdbb, getPermanent(rpb->rpb_relation), root, &idx, i); BTR_description(tdbb, getPermanent(rpb->rpb_relation), root, &idx, i);
@ -1796,7 +1790,7 @@ static idx_e check_partner_index(thread_db* tdbb,
// get the index root page for the partner relation // get the index root page for the partner relation
WIN window(get_root_page(tdbb, getPermanent(partner_relation))); WIN window(get_root_page(tdbb, getPermanent(partner_relation)));
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_root); auto* root = BTR_fetch_root(FB_FUNCTION, tdbb, &window);
// get the description of the partner index // get the description of the partner index
@ -1943,17 +1937,7 @@ static PageNumber get_root_page(thread_db* tdbb, Cached::Relation* relation)
* Find the root page for a relation. * Find the root page for a relation.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); return relation->getIndexRootPage(tdbb);
RelationPages* relPages = relation->getPages(tdbb);
SLONG page = relPages->rel_index_root;
if (!page)
{
DPM_scan_pages(tdbb);
page = relPages->rel_index_root;
}
return PageNumber(relPages->rel_pg_space_id, page);
} }