mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:43:03 +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)
|
||||
{
|
||||
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
|
||||
|
@ -206,17 +206,10 @@ LookupValueList::LookupValueList(MemoryPool& pool, ValueListNode* values, ULONG
|
||||
|
||||
const SortedValueList* LookupValueList::init(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
const auto impure = request->getImpure<impure_value>(m_impureOffset);
|
||||
auto sortedList = impure->vlu_misc.vlu_sortedList;
|
||||
|
||||
if (!(impure->vlu_flags & VLU_computed))
|
||||
auto createList = [&]()
|
||||
{
|
||||
delete impure->vlu_misc.vlu_sortedList;
|
||||
impure->vlu_misc.vlu_sortedList = nullptr;
|
||||
|
||||
sortedList = impure->vlu_misc.vlu_sortedList =
|
||||
FB_NEW_POOL(*tdbb->getDefaultPool())
|
||||
SortedValueList(*tdbb->getDefaultPool(), m_values.getCount());
|
||||
const auto sortedList = FB_NEW_POOL(*tdbb->getDefaultPool())
|
||||
SortedValueList(*tdbb->getDefaultPool(), m_values.getCount());
|
||||
|
||||
sortedList->setSortMode(FB_ARRAY_SORT_MANUAL);
|
||||
|
||||
@ -228,10 +221,32 @@ const SortedValueList* LookupValueList::init(thread_db* tdbb, Request* request)
|
||||
|
||||
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
|
||||
|
@ -1885,19 +1885,17 @@ bool Retrieval::matchBoolean(IndexScratch* indexScratch,
|
||||
if (!((segment->scanType == segmentScanEqual) ||
|
||||
(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);
|
||||
}
|
||||
segment->lowerValue = segment->upperValue = nullptr;
|
||||
segment->valueList = lookup;
|
||||
segment->scanType = segmentScanList;
|
||||
segment->excludeLower = false;
|
||||
segment->excludeUpper = false;
|
||||
cast = nullptr; // create new cast node for every value
|
||||
item = injectCast(csb, item, cast, matchDesc);
|
||||
}
|
||||
segment->lowerValue = segment->upperValue = nullptr;
|
||||
segment->valueList = listNode->lookup;
|
||||
segment->scanType = segmentScanList;
|
||||
segment->excludeLower = false;
|
||||
segment->excludeUpper = false;
|
||||
}
|
||||
}
|
||||
else if (missingNode)
|
||||
|
Loading…
Reference in New Issue
Block a user