mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:00:38 +01:00
Allow computable but non-invariant lists to be used for index lookup
This commit is contained in:
parent
3408f30109
commit
5df6668c7b
@ -1368,10 +1368,9 @@ void InListBoolNode::pass2Boolean(thread_db* tdbb, CompilerScratch* csb, std::fu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nodFlags & FLAG_INVARIANT)
|
if (nodFlags & FLAG_INVARIANT)
|
||||||
{
|
|
||||||
impureOffset = csb->allocImpure<impure_value>();
|
impureOffset = csb->allocImpure<impure_value>();
|
||||||
lookup = FB_NEW_POOL(csb->csb_pool) LookupValueList(csb->csb_pool, list, impureOffset);
|
|
||||||
}
|
lookup = FB_NEW_POOL(csb->csb_pool) LookupValueList(csb->csb_pool, list, impureOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InListBoolNode::execute(thread_db* tdbb, Request* request) const
|
bool InListBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||||
|
@ -206,17 +206,10 @@ LookupValueList::LookupValueList(MemoryPool& pool, ValueListNode* values, ULONG
|
|||||||
|
|
||||||
const SortedValueList* LookupValueList::init(thread_db* tdbb, Request* request) const
|
const SortedValueList* LookupValueList::init(thread_db* tdbb, Request* request) const
|
||||||
{
|
{
|
||||||
const auto impure = request->getImpure<impure_value>(m_impureOffset);
|
auto createList = [&]()
|
||||||
auto sortedList = impure->vlu_misc.vlu_sortedList;
|
|
||||||
|
|
||||||
if (!(impure->vlu_flags & VLU_computed))
|
|
||||||
{
|
{
|
||||||
delete impure->vlu_misc.vlu_sortedList;
|
const auto sortedList = FB_NEW_POOL(*tdbb->getDefaultPool())
|
||||||
impure->vlu_misc.vlu_sortedList = nullptr;
|
SortedValueList(*tdbb->getDefaultPool(), m_values.getCount());
|
||||||
|
|
||||||
sortedList = impure->vlu_misc.vlu_sortedList =
|
|
||||||
FB_NEW_POOL(*tdbb->getDefaultPool())
|
|
||||||
SortedValueList(*tdbb->getDefaultPool(), m_values.getCount());
|
|
||||||
|
|
||||||
sortedList->setSortMode(FB_ARRAY_SORT_MANUAL);
|
sortedList->setSortMode(FB_ARRAY_SORT_MANUAL);
|
||||||
|
|
||||||
@ -228,10 +221,32 @@ const SortedValueList* LookupValueList::init(thread_db* tdbb, Request* request)
|
|||||||
|
|
||||||
sortedList->sort();
|
sortedList->sort();
|
||||||
|
|
||||||
impure->vlu_flags |= VLU_computed;
|
return sortedList;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-zero impure offset means that the list expression is invariant,
|
||||||
|
// so the sorted list can be cached inside the impure area
|
||||||
|
|
||||||
|
if (m_impureOffset)
|
||||||
|
{
|
||||||
|
const auto impure = request->getImpure<impure_value>(m_impureOffset);
|
||||||
|
auto sortedList = impure->vlu_misc.vlu_sortedList;
|
||||||
|
|
||||||
|
if (!(impure->vlu_flags & VLU_computed))
|
||||||
|
{
|
||||||
|
delete impure->vlu_misc.vlu_sortedList;
|
||||||
|
impure->vlu_misc.vlu_sortedList = nullptr;
|
||||||
|
|
||||||
|
sortedList = impure->vlu_misc.vlu_sortedList = createList();
|
||||||
|
impure->vlu_flags |= VLU_computed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedList;
|
// Otherwise, create a temporary list for early evaluation during index lookup
|
||||||
|
|
||||||
|
return createList();
|
||||||
}
|
}
|
||||||
|
|
||||||
TriState LookupValueList::find(thread_db* tdbb, Request* request, const ValueExprNode* value, const dsc* desc) const
|
TriState LookupValueList::find(thread_db* tdbb, Request* request, const ValueExprNode* value, const dsc* desc) const
|
||||||
|
@ -1885,19 +1885,17 @@ bool Retrieval::matchBoolean(IndexScratch* indexScratch,
|
|||||||
if (!((segment->scanType == segmentScanEqual) ||
|
if (!((segment->scanType == segmentScanEqual) ||
|
||||||
(segment->scanType == segmentScanEquivalent)))
|
(segment->scanType == segmentScanEquivalent)))
|
||||||
{
|
{
|
||||||
if (auto lookup = listNode->lookup)
|
fb_assert(listNode->lookup);
|
||||||
|
for (auto& item : *listNode->lookup)
|
||||||
{
|
{
|
||||||
for (auto& item : *lookup)
|
cast = nullptr; // create new cast node for every value
|
||||||
{
|
item = injectCast(csb, item, cast, matchDesc);
|
||||||
cast = nullptr; // create new cast node for every value
|
|
||||||
item = injectCast(csb, item, cast, matchDesc);
|
|
||||||
}
|
|
||||||
segment->lowerValue = segment->upperValue = nullptr;
|
|
||||||
segment->valueList = lookup;
|
|
||||||
segment->scanType = segmentScanList;
|
|
||||||
segment->excludeLower = false;
|
|
||||||
segment->excludeUpper = false;
|
|
||||||
}
|
}
|
||||||
|
segment->lowerValue = segment->upperValue = nullptr;
|
||||||
|
segment->valueList = listNode->lookup;
|
||||||
|
segment->scanType = segmentScanList;
|
||||||
|
segment->excludeLower = false;
|
||||||
|
segment->excludeUpper = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (missingNode)
|
else if (missingNode)
|
||||||
|
Loading…
Reference in New Issue
Block a user