From 0fc68ab8eac79fa1521659a6c67c635ae7cc678c Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 15 Mar 2017 14:42:30 +0300 Subject: [PATCH] Avoid loosing decimal float precision, scale and/or sign info when sorting --- src/common/DecFloat.cpp | 18 +++++++++++------- src/jrd/opt.cpp | 3 ++- src/jrd/recsrc/SortedStream.cpp | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/common/DecFloat.cpp b/src/common/DecFloat.cpp index c3ee05870b..5a5ea1acd6 100644 --- a/src/common/DecFloat.cpp +++ b/src/common/DecFloat.cpp @@ -140,11 +140,17 @@ void make(unsigned int* key, unsigned dig = digits(pMax, coeff, exp); // exponent bias and sign - exp += (bias + 2); if (!dig) - exp = 1; - if (sign) - exp = -exp; + { + exp = 0; + sign = 0; + } + else + { + exp += (bias + 2); + if (sign) + exp = -exp; + } *key++ = exp; // convert to SLONG @@ -171,9 +177,7 @@ void grab(unsigned int* key, sign = DECFLOAT_Sign; exp = -exp; } - if (exp == 1) - exp = 0; - else + if (exp != 0) exp -= (bias + 2); // convert from SLONG diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index e298bad4a1..b37f8e5571 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -2453,7 +2453,8 @@ SortedStream* OPT_gen_sort(thread_db* tdbb, CompilerScratch* csb, const StreamLi fieldNode->getDesc(tdbb, csb, desc); // International type text has a computed key - if (IS_INTL_DATA(desc)) + // Different decimal float values sometimes have same keys + if (IS_INTL_DATA(desc) || desc->isDecFloat()) break; --items; diff --git a/src/jrd/recsrc/SortedStream.cpp b/src/jrd/recsrc/SortedStream.cpp index 9cc24c7e8c..8a518daf63 100644 --- a/src/jrd/recsrc/SortedStream.cpp +++ b/src/jrd/recsrc/SortedStream.cpp @@ -339,7 +339,7 @@ void SortedStream::mapData(thread_db* tdbb, jrd_req* request, UCHAR* data) const // a sort key, there is a later nod_field in the item // list that contains the data to send back - if (IS_INTL_DATA(&item->desc) && + if ((IS_INTL_DATA(&item->desc) || item->desc.isDecFloat()) && (ULONG)(IPTR) item->desc.dsc_address < m_map->keyLength) { continue;