mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 23:23:04 +01:00
Do not reuse arbitrary nodes' impure space in aggregate. Relates to CORE-3255.
This commit is contained in:
parent
aa74283e5d
commit
67f9c9b31d
@ -79,6 +79,15 @@ void AggregatedStream::open(thread_db* tdbb) const
|
|||||||
impure->pending = 0;
|
impure->pending = 0;
|
||||||
VIO_record(tdbb, &request->req_rpb[m_stream], m_format, tdbb->getDefaultPool());
|
VIO_record(tdbb, &request->req_rpb[m_stream], m_format, tdbb->getDefaultPool());
|
||||||
|
|
||||||
|
unsigned impureCount = m_group ? m_group->getCount() : 0;
|
||||||
|
impureCount += m_order ? m_order->getCount() : 0;
|
||||||
|
|
||||||
|
if (!impure->impureValues)
|
||||||
|
{
|
||||||
|
impure->impureValues = FB_NEW(*tdbb->getDefaultPool()) impure_value[impureCount];
|
||||||
|
memset(impure->impureValues, 0, sizeof(impure_value) * impureCount);
|
||||||
|
}
|
||||||
|
|
||||||
m_next->open(tdbb);
|
m_next->open(tdbb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,8 +280,7 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
if (--tdbb->tdbb_quantum < 0)
|
if (--tdbb->tdbb_quantum < 0)
|
||||||
JRD_reschedule(tdbb, 0, true);
|
JRD_reschedule(tdbb, 0, true);
|
||||||
|
|
||||||
impure_value vtemp;
|
Impure* const impure = request->getImpure<Impure>(m_impure);
|
||||||
vtemp.vlu_string = NULL;
|
|
||||||
|
|
||||||
// if we found the last record last time, we're all done
|
// if we found the last record last time, we're all done
|
||||||
|
|
||||||
@ -317,38 +325,43 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned impureOffset = 0;
|
||||||
const NestConst<ValueExprNode>* ptrValue, *endValue;
|
const NestConst<ValueExprNode>* ptrValue, *endValue;
|
||||||
dsc* desc;
|
dsc* desc;
|
||||||
|
|
||||||
if (m_group)
|
if (m_group)
|
||||||
{
|
{
|
||||||
for (ptrValue = m_group->begin(), endValue = m_group->end(); ptrValue != endValue; ++ptrValue)
|
for (ptrValue = m_group->begin(), endValue = m_group->end();
|
||||||
|
ptrValue != endValue;
|
||||||
|
++ptrValue, ++impureOffset)
|
||||||
{
|
{
|
||||||
const ValueExprNode* from = *ptrValue;
|
const ValueExprNode* from = *ptrValue;
|
||||||
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
|
impure_value* target = &impure->impureValues[impureOffset];
|
||||||
|
|
||||||
desc = EVL_expr(tdbb, request, from);
|
desc = EVL_expr(tdbb, request, from);
|
||||||
|
|
||||||
if (request->req_flags & req_null)
|
if (request->req_flags & req_null)
|
||||||
impure->vlu_desc.dsc_address = NULL;
|
target->vlu_desc.dsc_address = NULL;
|
||||||
else
|
else
|
||||||
EVL_make_value(tdbb, desc, impure);
|
EVL_make_value(tdbb, desc, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_order)
|
if (m_order)
|
||||||
{
|
{
|
||||||
for (ptrValue = m_order->begin(), endValue = m_order->end(); ptrValue != endValue; ++ptrValue)
|
for (ptrValue = m_order->begin(), endValue = m_order->end();
|
||||||
|
ptrValue != endValue;
|
||||||
|
++ptrValue, ++impureOffset)
|
||||||
{
|
{
|
||||||
const ValueExprNode* from = *ptrValue;
|
const ValueExprNode* from = *ptrValue;
|
||||||
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
|
impure_value* target = &impure->impureValues[impureOffset];
|
||||||
|
|
||||||
desc = EVL_expr(tdbb, request, from);
|
desc = EVL_expr(tdbb, request, from);
|
||||||
|
|
||||||
if (request->req_flags & req_null)
|
if (request->req_flags & req_null)
|
||||||
impure->vlu_desc.dsc_address = NULL;
|
target->vlu_desc.dsc_address = NULL;
|
||||||
else
|
else
|
||||||
EVL_make_value(tdbb, desc, impure);
|
EVL_make_value(tdbb, desc, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,6 +371,7 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
|
|
||||||
while (state != STATE_EOF_FOUND)
|
while (state != STATE_EOF_FOUND)
|
||||||
{
|
{
|
||||||
|
impureOffset = 0;
|
||||||
state = STATE_PENDING;
|
state = STATE_PENDING;
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
@ -371,22 +385,16 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
{
|
{
|
||||||
for (ptrValue = m_group->begin(), endValue = m_group->end();
|
for (ptrValue = m_group->begin(), endValue = m_group->end();
|
||||||
ptrValue != endValue;
|
ptrValue != endValue;
|
||||||
++ptrValue)
|
++ptrValue, ++impureOffset)
|
||||||
{
|
{
|
||||||
const ValueExprNode* from = *ptrValue;
|
const ValueExprNode* from = *ptrValue;
|
||||||
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
|
impure_value* vtemp = &impure->impureValues[impureOffset];
|
||||||
|
|
||||||
if (impure->vlu_desc.dsc_address)
|
|
||||||
EVL_make_value(tdbb, &impure->vlu_desc, &vtemp);
|
|
||||||
else
|
|
||||||
vtemp.vlu_desc.dsc_address = NULL;
|
|
||||||
|
|
||||||
desc = EVL_expr(tdbb, request, from);
|
desc = EVL_expr(tdbb, request, from);
|
||||||
|
|
||||||
if (request->req_flags & req_null)
|
if (request->req_flags & req_null)
|
||||||
{
|
{
|
||||||
impure->vlu_desc.dsc_address = NULL;
|
if (vtemp->vlu_desc.dsc_address)
|
||||||
if (vtemp.vlu_desc.dsc_address)
|
|
||||||
{
|
{
|
||||||
if (m_order)
|
if (m_order)
|
||||||
state = STATE_GROUPING;
|
state = STATE_GROUPING;
|
||||||
@ -395,8 +403,7 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EVL_make_value(tdbb, desc, impure);
|
if (!vtemp->vlu_desc.dsc_address || MOV_compare(&vtemp->vlu_desc, desc) != 0)
|
||||||
if (!vtemp.vlu_desc.dsc_address || MOV_compare(&vtemp.vlu_desc, desc))
|
|
||||||
{
|
{
|
||||||
if (m_order)
|
if (m_order)
|
||||||
state = STATE_GROUPING;
|
state = STATE_GROUPING;
|
||||||
@ -410,28 +417,21 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
{
|
{
|
||||||
for (ptrValue = m_order->begin(), endValue = m_order->end();
|
for (ptrValue = m_order->begin(), endValue = m_order->end();
|
||||||
ptrValue != endValue;
|
ptrValue != endValue;
|
||||||
++ptrValue)
|
++ptrValue, ++impureOffset)
|
||||||
{
|
{
|
||||||
const ValueExprNode* from = *ptrValue;
|
const ValueExprNode* from = *ptrValue;
|
||||||
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
|
impure_value* vtemp = &impure->impureValues[impureOffset];
|
||||||
|
|
||||||
if (impure->vlu_desc.dsc_address)
|
|
||||||
EVL_make_value(tdbb, &impure->vlu_desc, &vtemp);
|
|
||||||
else
|
|
||||||
vtemp.vlu_desc.dsc_address = NULL;
|
|
||||||
|
|
||||||
desc = EVL_expr(tdbb, request, from);
|
desc = EVL_expr(tdbb, request, from);
|
||||||
|
|
||||||
if (request->req_flags & req_null)
|
if (request->req_flags & req_null)
|
||||||
{
|
{
|
||||||
impure->vlu_desc.dsc_address = NULL;
|
if (vtemp->vlu_desc.dsc_address)
|
||||||
if (vtemp.vlu_desc.dsc_address)
|
|
||||||
goto break_out;
|
goto break_out;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EVL_make_value(tdbb, desc, impure);
|
if (!vtemp->vlu_desc.dsc_address || MOV_compare(&vtemp->vlu_desc, desc) != 0)
|
||||||
if (!vtemp.vlu_desc.dsc_address || MOV_compare(&vtemp.vlu_desc, desc))
|
|
||||||
goto break_out;
|
goto break_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,8 +470,6 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
|
|||||||
|
|
||||||
// Finish up any residual computations and get out
|
// Finish up any residual computations and get out
|
||||||
|
|
||||||
delete vtemp.vlu_string;
|
|
||||||
|
|
||||||
for (const NestConst<ValueExprNode>* source = m_map->sourceList.begin(),
|
for (const NestConst<ValueExprNode>* source = m_map->sourceList.begin(),
|
||||||
*target = m_map->targetList.begin();
|
*target = m_map->targetList.begin();
|
||||||
source != sourceEnd;
|
source != sourceEnd;
|
||||||
|
@ -603,6 +603,7 @@ namespace Jrd
|
|||||||
{
|
{
|
||||||
State state;
|
State state;
|
||||||
FB_UINT64 pending;
|
FB_UINT64 pending;
|
||||||
|
impure_value* impureValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user