From b747e9ab9216fe3b449dca12f7fe1082d9bbd02e Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 7 Oct 2019 09:21:09 -0500 Subject: [PATCH] MCOL-3536 use Locale for compare of strings in ORDER BY --- dbcon/joblist/limitedorderby.h | 5 ++--- utils/funcexp/utils_utf8.h | 2 +- utils/rowgroup/rowgroup.h | 12 ++++++++++++ utils/windowfunction/idborderby.cpp | 12 +++++------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/dbcon/joblist/limitedorderby.h b/dbcon/joblist/limitedorderby.h index 3ff266aa3..5b1a02acc 100644 --- a/dbcon/joblist/limitedorderby.h +++ b/dbcon/joblist/limitedorderby.h @@ -54,11 +54,10 @@ public: void finalize(); protected: - uint64_t fStart; - uint64_t fCount; + uint64_t fStart; + uint64_t fCount; }; - } #endif // LIMITED_ORDER_BY_H diff --git a/utils/funcexp/utils_utf8.h b/utils/funcexp/utils_utf8.h index 23d41ce7e..cca738ef0 100644 --- a/utils/funcexp/utils_utf8.h +++ b/utils/funcexp/utils_utf8.h @@ -53,7 +53,7 @@ extern std::locale loc; // Is there a way to construct a global reference to a facet? // const std::collate& coll = std::use_facet >(loc); -//Infinidb version of strlocale BUG 5362 +//Columnstore version of strlocale BUG 5362 //set System Locale "C" by default //return the system Locale currently set in from Columnstore.xml inline diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index 373269e13..c4b419393 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -375,6 +375,7 @@ public: inline std::string getStringField(uint32_t colIndex) const; inline const uint8_t* getStringPointer(uint32_t colIndex) const; inline uint32_t getStringLength(uint32_t colIndex) const; + inline const char* getCharPtrField(uint32_t colIndex, int& len) const; void setStringField(const std::string& val, uint32_t colIndex); inline void setStringField(const uint8_t*, uint32_t len, uint32_t colIndex); @@ -774,6 +775,17 @@ inline std::string Row::getStringField(uint32_t colIndex) const strnlen((char*) &data[offsets[colIndex]], getColumnWidth(colIndex))); } +// Return a char* to the string field with len +inline const char* Row::getCharPtrField(uint32_t colIndex, int& len) const +{ + len = getStringLength(colIndex); + if (inStringTable(colIndex)) + { + return (const char*)strings->getPointer(*((uint64_t*) &data[offsets[colIndex]])); + } + return (char*)&data[offsets[colIndex]]; +} + inline std::string Row::getVarBinaryStringField(uint32_t colIndex) const { if (inStringTable(colIndex)) diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index 8e5a63e1f..e7f8dbaf3 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -130,13 +130,11 @@ int StringCompare::operator()(IdbCompare* l, Row::Pointer r1, Row::Pointer r2) } else { - string v1 = l->row1().getStringField(fSpec.fIndex); - string v2 = l->row2().getStringField(fSpec.fIndex); - - if (v1 > v2) - ret = fSpec.fAsc; - else if (v1 < v2) - ret = -fSpec.fAsc; + int len1, len2; + const char* s1 = l->row1().getCharPtrField(fSpec.fIndex, len1); + const char* s2 = l->row2().getCharPtrField(fSpec.fIndex, len2); + const std::collate& coll = std::use_facet >(loc); + ret = fSpec.fAsc * coll.compare(s1, s1+len1, s2, s2+len2); } return ret;