diff --git a/src/jrd/Package.epp b/src/jrd/Package.epp index 405c22f416e..9fd0bb3b376 100644 --- a/src/jrd/Package.epp +++ b/src/jrd/Package.epp @@ -172,12 +172,12 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request) { { ReadLockGuard guard(m_makeValueLock, FB_FUNCTION); - if (m_value.vlu_desc.dsc_dtype != dtype_unknown) + if (m_value.vlu_desc.dsc_address != nullptr) return &m_value.vlu_desc; } WriteLockGuard guard(m_makeValueLock, FB_FUNCTION); - if (m_value.vlu_desc.dsc_dtype != dtype_unknown) // Extra check in case of two callers waiting + if (m_value.vlu_desc.dsc_address != nullptr) // Extra check in case of two callers waiting return &m_value.vlu_desc; Attachment* attachment = tdbb->getAttachment(); @@ -196,6 +196,8 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request) MET_parse_blob(tdbb, &name.schema, nullptr, &constantBid, &csb, nullptr, false, false); fb_assert(csb->csb_node != nullptr); + csb->csb_node->pass1(tdbb, csb); + csb->csb_node->pass2(tdbb, csb); if (request == nullptr) { @@ -216,7 +218,27 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request) executeCsbNode(tdbb, csb); } else + { + // A csb->csb_node will use impureArea from the incoming request + // but it contains other data + // Backup the current data and restore it later + + // Reusing a small chunk is faster instead of makeing a new request + // And using existing space for a temporally value is better instead of adding this to request->impureArea + // and carrying it for whole request live + + const auto nodeImpureSize = csb->csb_impure; + if (request->impureArea.getCount() < nodeImpureSize) + request->impureArea.grow(nodeImpureSize - request->impureArea.getCount()); + + const Array backup(request->impureArea.begin(), nodeImpureSize); + + fb_assert(tdbb->getRequest() == request); executeCsbNode(tdbb, csb); + + // Restore + memcpy(request->impureArea.begin(), backup.begin(), nodeImpureSize); + } } catch (const Exception& ex) { diff --git a/src/jrd/Package.h b/src/jrd/Package.h index 182b2823ce5..1a4697e95a0 100644 --- a/src/jrd/Package.h +++ b/src/jrd/Package.h @@ -73,6 +73,7 @@ class ConstantValue final : public Firebird::PermanentStorage delete m_value.vlu_string; m_value = {}; m_value.vlu_desc = typeDesc; + m_value.vlu_desc.dsc_address = nullptr; // Make sure to call makeValue } void updateValue(const bid blobId)