diff --git a/src/inc/tutil.h b/src/inc/tutil.h index bdf9df63eeafd73f892be7ab50dddb35ed9989c0..b26ef2b1c828782dd9f3a28da9ed61576024174d 100644 --- a/src/inc/tutil.h +++ b/src/inc/tutil.h @@ -173,6 +173,8 @@ uint32_t MurmurHash3_32(const void *key, int32_t len); bool taosMbsToUcs4(char *mbs, int32_t mbs_len, char *ucs4, int32_t ucs4_max_len); +int tasoUcs4Compare(void* f1_ucs4, void *f2_ucs4, int bytes); + bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs); bool taosValidateEncodec(char *encodec); diff --git a/src/util/src/textbuffer.c b/src/util/src/textbuffer.c index ef5536808137fc5593e097c4396bf0e1281689e6..1811f43be012919eb2077b11fd27b06fe897869d 100644 --- a/src/util/src/textbuffer.c +++ b/src/util/src/textbuffer.c @@ -898,7 +898,7 @@ static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, i }; case TSDB_DATA_TYPE_NCHAR: { int32_t b = bytes / TSDB_NCHAR_SIZE; - int32_t ret = wcsncmp((wchar_t *)f1, (wchar_t *)f2, b); + int32_t ret = tasoUcs4Compare(f1, f2, bytes); if (ret == 0) { return 0; } diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index e0dcb0aa3f22c8eadd4f30c75c9fa6e7bced1727..8af9edc931216a837835491b4e66837fa0d57bb1 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -398,6 +398,46 @@ int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstP return rename(fullPath, *dstPath); } +int tasoUcs4Compare(void* f1_ucs4, void *f2_ucs4, int bytes) { +#if defined WINDOWS + for (int i = 0; i < bytes; ++i) { + int32_t f1 = *(int32_t*)((char*)f1_ucs4 + i * 4); + int32_t f2 = *(int32_t*)((char*)f2_ucs4 + i * 4); + + if ((f1 == 0 && f2 != 0) || (f1 != 0 && f2 == 0)) { + return f1 - f2; + } + else if (f1 == 0 && f2 == 0) { + return 0; + } + + if (f1 != f2) { + return f1 - f2; + } + } + return 0; + +#if 0 + int32_t ucs4_max_len = bytes + 4; + char *f1_mbs = calloc(bytes, 1); + char *f2_mbs = calloc(bytes, 1); + if (!taosUcs4ToMbs(f1_ucs4, ucs4_max_len, f1_mbs)) { + return -1; + } + if (!taosUcs4ToMbs(f2_ucs4, ucs4_max_len, f2_mbs)) { + return -1; + } + int32_t ret = strcmp(f1_mbs, f2_mbs); + free(f1_mbs); + free(f2_mbs); + return ret; +#endif + +#else + return wcsncmp((wchar_t *)f1, (wchar_t *)f2, b); +#endif +} + bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs) { #ifdef USE_LIBICONV iconv_t cd = iconv_open(tsCharset, DEFAULT_UNICODE_ENCODEC);