8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 21:23:04 +01:00

Ensure pages are properly released after exception raised during partial index condition check, see #7998

This commit is contained in:
Dmitry Yemanov 2024-02-09 14:56:58 +03:00
parent f4e725f3af
commit c40fe4e181
5 changed files with 82 additions and 36 deletions

View File

@ -422,6 +422,30 @@ bool IndexCondition::evaluate(Record* record) const
return result;
}
TriState IndexCondition::check(Record* record, idx_e* errCode)
{
TriState result;
try
{
result = evaluate(record);
if (errCode)
*errCode = idx_e_ok;
}
catch (const Exception& ex)
{
if (errCode)
{
*errCode = idx_e_conversion;
ex.stuffException(m_tdbb->tdbb_status_vector);
}
}
return result;
}
// IndexExpression class
IndexExpression::IndexExpression(thread_db* tdbb, index_desc* idx)
@ -1014,12 +1038,6 @@ bool BTR_description(thread_db* tdbb, jrd_rel* relation, index_root_page* root,
}
bool BTR_check_condition(thread_db* tdbb, index_desc* idx, Record* record)
{
return IndexCondition(tdbb, idx).evaluate(record);
}
dsc* BTR_eval_expression(thread_db* tdbb, index_desc* idx, Record* record)
{
return IndexExpression(tdbb, idx).evaluate(record);

View File

@ -343,12 +343,14 @@ public:
~IndexCondition();
bool evaluate(Record* record) const;
Firebird::TriState check(Record* record, idx_e* errCode = nullptr);
private:
thread_db* const m_tdbb;
BoolExprNode* m_condition = nullptr;
Request* m_request = nullptr;
bool evaluate(Record* record) const;
};
class IndexExpression

View File

@ -34,7 +34,6 @@ void BTR_complement_key(Jrd::temporary_key*);
void BTR_create(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::SelectivityList&);
bool BTR_delete_index(Jrd::thread_db*, Jrd::win*, USHORT);
bool BTR_description(Jrd::thread_db*, Jrd::jrd_rel*, Ods::index_root_page*, Jrd::index_desc*, USHORT);
bool BTR_check_condition(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*);
dsc* BTR_eval_expression(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*);
void BTR_evaluate(Jrd::thread_db*, const Jrd::IndexRetrieval*, Jrd::RecordBitmap**, Jrd::RecordBitmap*);
UCHAR* BTR_find_leaf(Ods::btree_page*, Jrd::temporary_key*, UCHAR*, USHORT*, bool, int);

View File

@ -628,11 +628,17 @@ bool IndexCreateTask::handler(WorkItem& _item)
while (!m_stop && stack.hasData())
{
Record* record = stack.pop();
idx_e result = idx_e_ok;
if (!condition.evaluate(record))
const auto checkResult = condition.check(record, &result);
if (result == idx_e_ok)
{
fb_assert(checkResult.isAssigned());
if (!checkResult.asBool())
continue;
auto result = key.compose(record);
result = key.compose(record);
if (result == idx_e_ok)
{
@ -656,6 +662,7 @@ bool IndexCreateTask::handler(WorkItem& _item)
partner_relation, partner_index_id);
}
}
}
if (result != idx_e_ok)
{
@ -1167,7 +1174,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
{
Record* const rec1 = stack1.object();
if (!condition.evaluate(rec1))
if (!condition.check(rec1).asBool())
continue;
if (const auto result = key1.compose(rec1))
@ -1275,11 +1282,21 @@ void IDX_modify(thread_db* tdbb,
while (BTR_next_index(tdbb, org_rpb->rpb_relation, transaction, &idx, &window))
{
if (!BTR_check_condition(tdbb, &idx, new_rpb->rpb_record))
continue;
IndexErrorContext context(new_rpb->rpb_relation, &idx);
idx_e error_code;
idx_e error_code = idx_e_ok;
IndexCondition condition(tdbb, &idx);
const auto checkResult = condition.check(new_rpb->rpb_record, &error_code);
if (error_code)
{
CCH_RELEASE(tdbb, &window);
context.raise(tdbb, error_code, new_rpb->rpb_record);
}
fb_assert(checkResult.isAssigned());
if (!checkResult.asBool())
continue;
AutoIndexExpression expression;
IndexKey newKey(tdbb, new_rpb->rpb_relation, &idx, expression), orgKey(newKey);
@ -1504,11 +1521,21 @@ void IDX_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
while (BTR_next_index(tdbb, rpb->rpb_relation, transaction, &idx, &window))
{
if (!BTR_check_condition(tdbb, &idx, rpb->rpb_record))
continue;
IndexErrorContext context(rpb->rpb_relation, &idx);
idx_e error_code;
idx_e error_code = idx_e_ok;
IndexCondition condition(tdbb, &idx);
const auto checkResult = condition.check(rpb->rpb_record, &error_code);
if (error_code)
{
CCH_RELEASE(tdbb, &window);
context.raise(tdbb, error_code, rpb->rpb_record);
}
fb_assert(checkResult.isAssigned());
if (!checkResult.asBool())
continue;
AutoIndexExpression expression;
IndexKey key(tdbb, rpb->rpb_relation, &idx, expression);

View File

@ -1903,7 +1903,7 @@ Validation::RTN Validation::walk_data_page(jrd_rel* relation, ULONG page_number,
if (!getInfo.m_condition)
getInfo.m_condition = FB_NEW_POOL(*pool) IndexCondition(vdr_tdbb, &getInfo.m_desc);
if (getInfo.m_condition->evaluate(rpb.rpb_record))
if (getInfo.m_condition->check(rpb.rpb_record).asBool())
RBM_SET(pool, &getInfo.m_recs, recno);
}
}