8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 20:03:02 +01:00

This should fix CORE-2833: Changing data that affects an expression index that contains references to null date fields fails.

This commit is contained in:
dimitr 2010-02-26 07:53:52 +00:00
parent ee936d80fd
commit 767a819321
2 changed files with 57 additions and 24 deletions

View File

@ -283,20 +283,38 @@ bool OPT_expression_equal(thread_db* tdbb, OptimizerBlk* opt,
{
fb_assert(idx->idx_flags & idx_expressn);
jrd_req* expr_req = EXE_find_request(tdbb, idx->idx_expression_request, false);
jrd_req* org_request = tdbb->getRequest();
jrd_req* expr_request = EXE_find_request(tdbb, idx->idx_expression_request, false);
fb_assert(expr_request->req_caller == NULL);
expr_request->req_caller = org_request;
tdbb->setRequest(expr_request);
fb_assert(expr_req->req_caller == NULL);
expr_req->req_caller = tdbb->getRequest();
tdbb->setRequest(expr_req);
bool result = false;
try
{
Jrd::ContextPoolHolder context(tdbb, tdbb->getRequest()->req_pool);
Jrd::ContextPoolHolder context(tdbb, expr_request->req_pool);
expr_request->req_timestamp = expr_request->req_caller ?
expr_request->req_caller->req_timestamp : Firebird::TimeStamp::getCurrentTimeStamp();
result = OPT_expression_equal2(tdbb, opt, idx->idx_expression, node, stream);
}
tdbb->setRequest(expr_req->req_caller);
expr_req->req_caller = NULL;
expr_req->req_flags &= ~req_in_use;
catch (const Firebird::Exception&)
{
tdbb->setRequest(org_request);
expr_request->req_caller = NULL;
expr_request->req_flags &= ~req_in_use;
expr_request->req_timestamp.invalidate();
throw;
}
tdbb->setRequest(org_request);
expr_request->req_caller = NULL;
expr_request->req_flags &= ~req_in_use;
expr_request->req_timestamp.invalidate();
return result;
}

View File

@ -490,53 +490,68 @@ DSC* BTR_eval_expression(thread_db* tdbb, index_desc* idx, Record* record, bool&
// case of reentrance due to recursion or multi-threading
// 28 Nov 2005 hvlad
// When using EXE_find_request i hope all is ok here
jrd_req* org_request = tdbb->getRequest();
jrd_req* expr_request = EXE_find_request(tdbb, idx->idx_expression_request, false);
fb_assert(expr_request->req_caller == NULL);
expr_request->req_caller = tdbb->getRequest();
// 10 Feb 2005 hvlad
// When this code called from IDX_create_index
// tdbb->getRequest() is set to our idx->idx_expression_request
// by PCMET_expression_index. Therefore no need to attach\detach
// idx_expression_request to the same transaction twice
const bool already_attached = (expr_request->req_caller == expr_request);
const bool already_attached = (org_request == expr_request);
if (!already_attached) {
fb_assert(expr_request->req_caller == NULL);
expr_request->req_caller = already_attached ? org_request->req_caller : org_request;
if (!already_attached)
{
TRA_attach_request(tdbb->getTransaction(), expr_request);
tdbb->setRequest(expr_request);
}
fb_assert(expr_request->req_transaction);
tdbb->setRequest(expr_request);
tdbb->getRequest()->req_rpb[0].rpb_record = record;
tdbb->getRequest()->req_flags &= ~req_null;
expr_request->req_rpb[0].rpb_record = record;
expr_request->req_flags &= ~req_null;
DSC* result = 0;
try {
Jrd::ContextPoolHolder context(tdbb, tdbb->getRequest()->req_pool);
DSC* result = NULL;
try
{
Jrd::ContextPoolHolder context(tdbb, expr_request->req_pool);
expr_request->req_timestamp = expr_request->req_caller ?
expr_request->req_caller->req_timestamp : Firebird::TimeStamp::getCurrentTimeStamp();
if (!(result = EVL_expr(tdbb, idx->idx_expression)))
result = &idx->idx_expression_desc;
notNull = !(expr_request->req_flags & req_null);
}
catch (const Firebird::Exception&)
{
if (!already_attached) {
if (!already_attached)
{
TRA_detach_request(expr_request);
tdbb->setRequest(org_request);
}
tdbb->setRequest(expr_request->req_caller);
expr_request->req_caller = NULL;
expr_request->req_flags &= ~req_in_use;
expr_request->req_timestamp.invalidate();
throw;
}
notNull = !(tdbb->getRequest()->req_flags & req_null);
if (!already_attached) {
if (!already_attached)
{
TRA_detach_request(expr_request);
tdbb->setRequest(org_request);
}
tdbb->setRequest(expr_request->req_caller);
expr_request->req_caller = NULL;
expr_request->req_flags &= ~req_in_use;
expr_request->req_timestamp.invalidate();
return result;
}