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:
parent
ee936d80fd
commit
767a819321
@ -283,20 +283,38 @@ bool OPT_expression_equal(thread_db* tdbb, OptimizerBlk* opt,
|
|||||||
{
|
{
|
||||||
fb_assert(idx->idx_flags & idx_expressn);
|
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;
|
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);
|
result = OPT_expression_equal2(tdbb, opt, idx->idx_expression, node, stream);
|
||||||
}
|
}
|
||||||
tdbb->setRequest(expr_req->req_caller);
|
catch (const Firebird::Exception&)
|
||||||
expr_req->req_caller = NULL;
|
{
|
||||||
expr_req->req_flags &= ~req_in_use;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -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
|
// case of reentrance due to recursion or multi-threading
|
||||||
// 28 Nov 2005 hvlad
|
// 28 Nov 2005 hvlad
|
||||||
// When using EXE_find_request i hope all is ok here
|
// 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);
|
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
|
// 10 Feb 2005 hvlad
|
||||||
// When this code called from IDX_create_index
|
// When this code called from IDX_create_index
|
||||||
// tdbb->getRequest() is set to our idx->idx_expression_request
|
// tdbb->getRequest() is set to our idx->idx_expression_request
|
||||||
// by PCMET_expression_index. Therefore no need to attach\detach
|
// by PCMET_expression_index. Therefore no need to attach\detach
|
||||||
// idx_expression_request to the same transaction twice
|
// 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);
|
TRA_attach_request(tdbb->getTransaction(), expr_request);
|
||||||
|
tdbb->setRequest(expr_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(expr_request->req_transaction);
|
fb_assert(expr_request->req_transaction);
|
||||||
|
|
||||||
tdbb->setRequest(expr_request);
|
expr_request->req_rpb[0].rpb_record = record;
|
||||||
tdbb->getRequest()->req_rpb[0].rpb_record = record;
|
expr_request->req_flags &= ~req_null;
|
||||||
tdbb->getRequest()->req_flags &= ~req_null;
|
|
||||||
|
|
||||||
DSC* result = 0;
|
DSC* result = NULL;
|
||||||
try {
|
|
||||||
Jrd::ContextPoolHolder context(tdbb, tdbb->getRequest()->req_pool);
|
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)))
|
if (!(result = EVL_expr(tdbb, idx->idx_expression)))
|
||||||
result = &idx->idx_expression_desc;
|
result = &idx->idx_expression_desc;
|
||||||
|
|
||||||
|
notNull = !(expr_request->req_flags & req_null);
|
||||||
}
|
}
|
||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
{
|
{
|
||||||
if (!already_attached) {
|
if (!already_attached)
|
||||||
|
{
|
||||||
TRA_detach_request(expr_request);
|
TRA_detach_request(expr_request);
|
||||||
|
tdbb->setRequest(org_request);
|
||||||
}
|
}
|
||||||
tdbb->setRequest(expr_request->req_caller);
|
|
||||||
expr_request->req_caller = NULL;
|
expr_request->req_caller = NULL;
|
||||||
expr_request->req_flags &= ~req_in_use;
|
expr_request->req_flags &= ~req_in_use;
|
||||||
|
expr_request->req_timestamp.invalidate();
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
notNull = !(tdbb->getRequest()->req_flags & req_null);
|
|
||||||
|
|
||||||
if (!already_attached) {
|
if (!already_attached)
|
||||||
|
{
|
||||||
TRA_detach_request(expr_request);
|
TRA_detach_request(expr_request);
|
||||||
|
tdbb->setRequest(org_request);
|
||||||
}
|
}
|
||||||
tdbb->setRequest(expr_request->req_caller);
|
|
||||||
expr_request->req_caller = NULL;
|
expr_request->req_caller = NULL;
|
||||||
expr_request->req_flags &= ~req_in_use;
|
expr_request->req_flags &= ~req_in_use;
|
||||||
|
expr_request->req_timestamp.invalidate();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user