From 67f9c9b31de7e18727eac8a1e530183f76bd9141 Mon Sep 17 00:00:00 2001 From: asfernandes Date: Wed, 9 Feb 2011 00:29:46 +0000 Subject: [PATCH] Do not reuse arbitrary nodes' impure space in aggregate. Relates to CORE-3255. --- src/jrd/recsrc/AggregatedStream.cpp | 66 ++++++++++++++--------------- src/jrd/recsrc/RecordSource.h | 1 + 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/jrd/recsrc/AggregatedStream.cpp b/src/jrd/recsrc/AggregatedStream.cpp index ea79813a5c..bcb82f222f 100644 --- a/src/jrd/recsrc/AggregatedStream.cpp +++ b/src/jrd/recsrc/AggregatedStream.cpp @@ -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(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* 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(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(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(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(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* source = m_map->sourceList.begin(), *target = m_map->targetList.begin(); source != sourceEnd; diff --git a/src/jrd/recsrc/RecordSource.h b/src/jrd/recsrc/RecordSource.h index 90d5dffd9c..6666541a26 100644 --- a/src/jrd/recsrc/RecordSource.h +++ b/src/jrd/recsrc/RecordSource.h @@ -603,6 +603,7 @@ namespace Jrd { State state; FB_UINT64 pending; + impure_value* impureValues; }; public: