8
0
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:
asfernandes 2011-02-09 00:29:46 +00:00
parent aa74283e5d
commit 67f9c9b31d
2 changed files with 33 additions and 34 deletions

View File

@ -79,6 +79,15 @@ void AggregatedStream::open(thread_db* tdbb) const
impure->pending = 0;
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);
}
@ -271,8 +280,7 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
if (--tdbb->tdbb_quantum < 0)
JRD_reschedule(tdbb, 0, true);
impure_value vtemp;
vtemp.vlu_string = NULL;
Impure* const impure = request->getImpure<Impure>(m_impure);
// 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;
dsc* desc;
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;
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
impure_value* target = &impure->impureValues[impureOffset];
desc = EVL_expr(tdbb, request, from);
if (request->req_flags & req_null)
impure->vlu_desc.dsc_address = NULL;
target->vlu_desc.dsc_address = NULL;
else
EVL_make_value(tdbb, desc, impure);
EVL_make_value(tdbb, desc, target);
}
}
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;
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
impure_value* target = &impure->impureValues[impureOffset];
desc = EVL_expr(tdbb, request, from);
if (request->req_flags & req_null)
impure->vlu_desc.dsc_address = NULL;
target->vlu_desc.dsc_address = NULL;
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)
{
impureOffset = 0;
state = STATE_PENDING;
if (first)
@ -371,22 +385,16 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
{
for (ptrValue = m_group->begin(), endValue = m_group->end();
ptrValue != endValue;
++ptrValue)
++ptrValue, ++impureOffset)
{
const ValueExprNode* from = *ptrValue;
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
if (impure->vlu_desc.dsc_address)
EVL_make_value(tdbb, &impure->vlu_desc, &vtemp);
else
vtemp.vlu_desc.dsc_address = NULL;
impure_value* vtemp = &impure->impureValues[impureOffset];
desc = EVL_expr(tdbb, request, from);
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)
state = STATE_GROUPING;
@ -395,8 +403,7 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
}
else
{
EVL_make_value(tdbb, desc, impure);
if (!vtemp.vlu_desc.dsc_address || MOV_compare(&vtemp.vlu_desc, desc))
if (!vtemp->vlu_desc.dsc_address || MOV_compare(&vtemp->vlu_desc, desc) != 0)
{
if (m_order)
state = STATE_GROUPING;
@ -410,28 +417,21 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
{
for (ptrValue = m_order->begin(), endValue = m_order->end();
ptrValue != endValue;
++ptrValue)
++ptrValue, ++impureOffset)
{
const ValueExprNode* from = *ptrValue;
impure_value* impure = request->getImpure<impure_value>(from->impureOffset);
if (impure->vlu_desc.dsc_address)
EVL_make_value(tdbb, &impure->vlu_desc, &vtemp);
else
vtemp.vlu_desc.dsc_address = NULL;
impure_value* vtemp = &impure->impureValues[impureOffset];
desc = EVL_expr(tdbb, request, from);
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;
}
else
{
EVL_make_value(tdbb, desc, impure);
if (!vtemp.vlu_desc.dsc_address || MOV_compare(&vtemp.vlu_desc, desc))
if (!vtemp->vlu_desc.dsc_address || MOV_compare(&vtemp->vlu_desc, desc) != 0)
goto break_out;
}
}
@ -470,8 +470,6 @@ AggregatedStream::State AggregatedStream::evaluateGroup(thread_db* tdbb, Aggrega
// Finish up any residual computations and get out
delete vtemp.vlu_string;
for (const NestConst<ValueExprNode>* source = m_map->sourceList.begin(),
*target = m_map->targetList.begin();
source != sourceEnd;

View File

@ -603,6 +603,7 @@ namespace Jrd
{
State state;
FB_UINT64 pending;
impure_value* impureValues;
};
public: