diff --git a/src/inc/tutil.h b/src/inc/tutil.h index f3576790a93ad7c056aa7073b8ab55cbcc5da217..449e51bc238b802be02d381cee2313bdd4897177 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(const char *encodec); diff --git a/src/util/src/textbuffer.c b/src/util/src/textbuffer.c index 98eca265250c8917c1e38e79e365174a93a1154d..3e71d90147aaa0e4e94992ad6846d7bf5efbbc28 100644 --- a/src/util/src/textbuffer.c +++ b/src/util/src/textbuffer.c @@ -895,8 +895,7 @@ static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, i return (ret < 0) ? -1 : 1; }; 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 cdd017fb564d1f11703b4608cfb85c0865f060c6..4db7adf2074f9b83e52c2f51a84fc72befcabcca 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -401,6 +401,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_ucs4, (wchar_t *)f2_ucs4, bytes / TSDB_NCHAR_SIZE); +#endif +} + bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs) { #ifdef USE_LIBICONV iconv_t cd = iconv_open(tsCharset, DEFAULT_UNICODE_ENCODEC);