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 };