From 3b01d5ea22464f74ebb32229d411701d410cc621 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 8 Oct 2019 13:02:52 -0500 Subject: [PATCH] MCOL-3536 use Locale from columnstore.xml when doing ORDER BY --- utils/windowfunction/idborderby.cpp | 13 ++++++------ utils/windowfunction/idborderby.h | 32 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index f6e88bd7e..703008183 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -130,13 +130,12 @@ 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 = l->row1().getStringLength(fSpec.fIndex); + int len2 = l->row2().getStringLength(fSpec.fIndex); + const char* s1 = (const char*)l->row1().getStringPointer(fSpec.fIndex); + const char* s2 = (const char*)l->row2().getStringPointer(fSpec.fIndex); + const std::collate& coll = std::use_facet >(loc); + ret = fSpec.fAsc * coll.compare(s1, s1+len1, s2, s2+len2); } return ret; diff --git a/utils/windowfunction/idborderby.h b/utils/windowfunction/idborderby.h index b11b9c44e..6d0f8574b 100644 --- a/utils/windowfunction/idborderby.h +++ b/utils/windowfunction/idborderby.h @@ -63,6 +63,7 @@ struct IdbSortSpec // TODO There are three ordering specs since 10.2 int fAsc; // ::= ASC | DESC int fNf; // ::= NULLS FIRST | NULLS LAST + std::string fLocale; IdbSortSpec() : fIndex(-1), fAsc(1), fNf(1) {} IdbSortSpec(int i, bool b) : fIndex(i), fAsc(b ? 1 : -1), fNf(fAsc) {} @@ -75,13 +76,42 @@ struct IdbSortSpec class Compare { public: - Compare(const IdbSortSpec& spec) : fSpec(spec) {} + Compare(const IdbSortSpec& spec) : fSpec(spec) + { + // Save off the current Locale in case something goes wrong. + std::string curLocale = setlocale(LC_COLLATE, NULL); + if (spec.fLocale.length() > 0) + { + fLocale = spec.fLocale; + } + else + { + fLocale = curLocale; + } + + try + { + std::locale localloc(fLocale.c_str()); + loc = localloc; + } + catch(...) + { + fLocale = curLocale; + std::locale localloc(fLocale.c_str()); + loc = localloc; + } + if (fLocale.find("ja_JP") != std::string::npos) + JPcodePoint = true; + } virtual ~Compare() {} virtual int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer) = 0; protected: IdbSortSpec fSpec; + std::string fLocale; + std::locale loc; + bool JPcodePoint; // code point ordering (Japanese UTF) flag };