diff --git a/packaging/tools/makeclient.sh b/packaging/tools/makeclient.sh
index 4c3278e41b0c51e86d84c3e200092b4554e6523c..92d3f8a89cf3d985ca9149fdb9d910949285d5d8 100755
--- a/packaging/tools/makeclient.sh
+++ b/packaging/tools/makeclient.sh
@@ -43,9 +43,11 @@ if [ "$osType" != "Darwin" ]; then
if [ "$pagMode" == "lite" ]; then
#strip ${build_dir}/bin/taosd
strip ${build_dir}/bin/taos
- bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
+ bin_files="${build_dir}/bin/taos \
+ ${script_dir}/remove_client.sh"
else
- bin_files="${script_dir}/remove_client.sh \
+ bin_files="${build_dir}/bin/taos \
+ ${script_dir}/remove_client.sh \
${script_dir}/set_core.sh \
${script_dir}/get_client.sh"
#${script_dir}/get_client.sh ${script_dir}/taosd-dump-cfg.gdb"
diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c
index 90379e6f7e5ccb5da12e6007ca0e94cfc859ee53..85c2215a2e71746889403e60ed09279e64574750 100644
--- a/src/client/src/tscLocal.c
+++ b/src/client/src/tscLocal.c
@@ -128,12 +128,13 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
// type length
int32_t bytes = pSchema[i].bytes;
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
- if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
+
+ if (pSchema[i].type == TSDB_DATA_TYPE_BINARY){
bytes -= VARSTR_HEADER_SIZE;
-
- if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
- bytes = bytes / TSDB_NCHAR_SIZE;
- }
+ }
+ else if(pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) {
+ bytes -= VARSTR_HEADER_SIZE;
+ bytes = bytes / TSDB_NCHAR_SIZE;
}
*(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index 063333d9cf72111826309939a818938b18879060..b045c566f1a72b8f0ca970d8e30d1b0e6486be68 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -4519,13 +4519,16 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr,
if (TSDB_FUNC_IS_SCALAR(functionId)) {
code = validateSQLExprItem(pCmd, pParamElem->pNode, pQueryInfo, pList, childrenTypes + i, uid, childrenHeight+i);
if (code != TSDB_CODE_SUCCESS) {
- free(childrenTypes);
+ tfree(childrenTypes);
+ tfree(childrenHeight);
return code;
}
}
if (!TSDB_FUNC_IS_SCALAR(functionId) &&
(pParamElem->pNode->type == SQL_NODE_EXPR || pParamElem->pNode->type == SQL_NODE_SQLFUNCTION)) {
+ tfree(childrenTypes);
+ tfree(childrenHeight);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
@@ -4547,6 +4550,8 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr,
*height = maxChildrenHeight + 1;
if (anyChildAgg && anyChildScalar) {
+ tfree(childrenTypes);
+ tfree(childrenHeight);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
if (anyChildAgg) {
@@ -4558,7 +4563,8 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr,
*type = SQLEXPR_TYPE_AGG;
}
}
- free(childrenTypes);
+ tfree(childrenTypes);
+ tfree(childrenHeight);
//end if param list is not null
} else {
if (TSDB_FUNC_IS_SCALAR(functionId)) {
@@ -6869,7 +6875,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
tscError("json type error, should be string");
return invalidOperationMsg(pMsg, msg25);
}
- if (pItem->pVar.nType > TSDB_MAX_JSON_TAGS_LEN / TSDB_NCHAR_SIZE) {
+ if (pItem->pVar.nLen > TSDB_MAX_JSON_TAGS_LEN / TSDB_NCHAR_SIZE) {
tscError("json tag too long");
return invalidOperationMsg(pMsg, msg14);
}
diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c
index 585865fb23adb9b5c8c6c7f5f1367a4532f12d41..e96e3c16da84b3ffc25b33e3864c4e38dcc3977f 100644
--- a/src/client/src/tscUtil.c
+++ b/src/client/src/tscUtil.c
@@ -774,11 +774,12 @@ static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bo
memcpy(dst, p, varDataTLen(p));
} else if (varDataLen(p) > 0) {
int32_t length = taosUcs4ToMbs(varDataVal(p), varDataLen(p), varDataVal(dst));
- varDataSetLen(dst, length);
-
- if (length == 0) {
+ if (length <= 0) {
tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p);
}
+ if (length >= 0){
+ varDataSetLen(dst, length);
+ }
} else {
varDataSetLen(dst, 0);
}
@@ -809,18 +810,23 @@ static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bo
varDataSetLen(dst, strlen(varDataVal(dst)));
}else if (type == TSDB_DATA_TYPE_JSON) {
int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), varDataVal(dst));
- varDataSetLen(dst, length);
- if (length == 0) {
+
+ if (length <= 0) {
tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p);
}
+ if (length >= 0){
+ varDataSetLen(dst, length);
+ }
}else if (type == TSDB_DATA_TYPE_NCHAR) { // value -> "value"
*(char*)varDataVal(dst) = '\"';
int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), POINTER_SHIFT(varDataVal(dst), CHAR_BYTES));
- *(char*)(POINTER_SHIFT(varDataVal(dst), length + CHAR_BYTES)) = '\"';
- varDataSetLen(dst, length + CHAR_BYTES*2);
- if (length == 0) {
+ if (length <= 0) {
tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p);
}
+ if (length >= 0){
+ varDataSetLen(dst, length + CHAR_BYTES*2);
+ *(char*)(POINTER_SHIFT(varDataVal(dst), length + CHAR_BYTES)) = '\"';
+ }
}else if (type == TSDB_DATA_TYPE_DOUBLE) {
double jsonVd = *(double*)(realData);
sprintf(varDataVal(dst), "%.9lf", jsonVd);
@@ -5515,10 +5521,10 @@ int parseJsontoTagData(char* json, SKVRowBuilder* kvRowBuilder, char* errMsg, in
char *tagVal = calloc(strlen(jsonValue) * TSDB_NCHAR_SIZE + TSDB_NCHAR_SIZE, 1);
*tagVal = jsonType2DbType(0, item->type); // type
char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES);
- if (!taosMbsToUcs4(jsonValue, strlen(jsonValue), varDataVal(tagData),
+ if (strlen(jsonValue) > 0 && !taosMbsToUcs4(jsonValue, strlen(jsonValue), varDataVal(tagData),
(int32_t)(strlen(jsonValue) * TSDB_NCHAR_SIZE), &outLen)) {
- tscError("json string error:%s|%s", strerror(errno), jsonValue);
- retCode = tscSQLSyntaxErrMsg(errMsg, "serizelize json error", NULL);
+ tscError("charset:%s to %s. val:%s, errno:%s, convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, jsonValue, strerror(errno));
+ retCode = tscSQLSyntaxErrMsg(errMsg, "charset convert json error", NULL);
free(tagVal);
goto end;
}
diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c
index 63a19c5c1b74028b8536982b0b2445c06de121b4..db3bec2ddfeee60a90df33cae4c9770bfdb7c46f 100644
--- a/src/common/src/texpr.c
+++ b/src/common/src/texpr.c
@@ -27,6 +27,7 @@
#include "tskiplist.h"
#include "texpr.h"
#include "tarithoperator.h"
+#include "tulog.h"
static int32_t exprValidateMathNode(tExprNode *pExpr);
static int32_t exprValidateStringConcatNode(tExprNode *pExpr);
@@ -1274,6 +1275,11 @@ void castConvert(int16_t inputType, int16_t inputBytes, char *input, int16_t Out
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newColData = calloc(1, outputBytes * TSDB_NCHAR_SIZE + 1);
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), newColData);
+ if (len < 0){
+ uError("castConvert taosUcs4ToMbs error 1");
+ tfree(newColData);
+ return;
+ }
newColData[len] = 0;
*(int64_t *)output = strtoll(newColData, NULL, 10);
tfree(newColData);
@@ -1291,6 +1297,11 @@ void castConvert(int16_t inputType, int16_t inputBytes, char *input, int16_t Out
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newColData = calloc(1, outputBytes * TSDB_NCHAR_SIZE + 1);
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), newColData);
+ if (len < 0){
+ uError("castConvert taosUcs4ToMbs error 2");
+ tfree(newColData);
+ return;
+ }
newColData[len] = 0;
*(int64_t *)output = strtoull(newColData, NULL, 10);
tfree(newColData);
@@ -1332,11 +1343,19 @@ void castConvert(int16_t inputType, int16_t inputBytes, char *input, int16_t Out
if (inputType == TSDB_DATA_TYPE_BOOL) {
char tmp[8] = {0};
int32_t len = sprintf(tmp, "%.*s", ncharSize, *(int8_t*)input ? "true" : "false");
- taosMbsToUcs4(tmp, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ bool ret = taosMbsToUcs4(tmp, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ if(!ret) {
+ uError("castConvert1 taosMbsToUcs4 error");
+ return;
+ }
varDataSetLen(output, len);
} else if (inputType == TSDB_DATA_TYPE_BINARY) {
int32_t len = ncharSize > varDataLen(input) ? varDataLen(input) : ncharSize;
- taosMbsToUcs4(input + VARSTR_HEADER_SIZE, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ bool ret = taosMbsToUcs4(input + VARSTR_HEADER_SIZE, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ if(!ret) {
+ uError("castConvert2 taosMbsToUcs4 error");
+ return;
+ }
varDataSetLen(output, len);
} else if (inputType == TSDB_DATA_TYPE_TIMESTAMP) {
assert(0);
@@ -1348,7 +1367,11 @@ void castConvert(int16_t inputType, int16_t inputBytes, char *input, int16_t Out
char tmp[400] = {0};
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
int32_t len = (int32_t)(ncharSize > strlen(tmp) ? strlen(tmp) : ncharSize);
- taosMbsToUcs4(tmp, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ bool ret = taosMbsToUcs4(tmp, len, varDataVal(output), outputBytes - VARSTR_HEADER_SIZE, &len);
+ if(!ret) {
+ uError("castConvert3 taosMbsToUcs4 error");
+ return;
+ }
varDataSetLen(output, len);
}
break;
diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c
index ee85d2f0086bb2676cb8699ad6bc2acaa33c5fbb..0d00856f9be76ee917d12ff7435142d6d55ccecf 100644
--- a/src/common/src/tvariant.c
+++ b/src/common/src/tvariant.c
@@ -23,6 +23,7 @@
#include "ttype.h"
#include "tutil.h"
#include "tvariant.h"
+#include "tulog.h"
#define SET_EXT_INFO(converted, res, minv, maxv, exti) do { \
if (converted == NULL || exti == NULL || *converted == false) { break; } \
@@ -359,8 +360,12 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
case TSDB_DATA_TYPE_NCHAR: {
dst[0] = '\'';
- taosUcs4ToMbs(pVar->wpz, (twcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1);
- int32_t len = (int32_t)strlen(dst);
+ int32_t len = taosUcs4ToMbs(pVar->wpz, (twcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1);
+ if (len < 0){
+ uError("castConvert1 taosUcs4ToMbs error");
+ return 0 ;
+ }
+ len = (int32_t)strlen(dst);
dst[len] = '\'';
dst[len + 1] = 0;
return len + 1;
@@ -428,11 +433,17 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
pBuf = realloc(pBuf, newSize + 1);
}
- taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, pBuf);
+ int32_t len = taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, pBuf);
+ if (len < 0){
+ uError("castConvert1 taosUcs4ToMbs error");
+ }
free(pVariant->wpz);
pBuf[newSize] = 0;
} else {
- taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, *pDest);
+ int32_t len = taosUcs4ToMbs(pVariant->wpz, (int32_t)newSize, *pDest);
+ if (len < 0){
+ uError("castConvert1 taosUcs4ToMbs error");
+ }
}
} else {
diff --git a/src/connector/C#/src/TDengineDriver/TDengineDriver.cs b/src/connector/C#/src/TDengineDriver/TDengineDriver.cs
index 42bba438522db2a1c238609036e2b5be8b37929f..15e0ca0841c0022439c00fc1b7357b770ccb14f6 100644
--- a/src/connector/C#/src/TDengineDriver/TDengineDriver.cs
+++ b/src/connector/C#/src/TDengineDriver/TDengineDriver.cs
@@ -398,5 +398,8 @@ namespace TDengineDriver
IntPtr stmtErrPrt = StmtErrPtr(stmt);
return Marshal.PtrToStringAnsi(stmtErrPrt);
}
+
+ [DllImport("taos", EntryPoint = "taos_fetch_lengths", CallingConvention = CallingConvention.Cdecl)]
+ static extern public IntPtr FetchLengths(IntPtr taos);
}
}
diff --git a/src/connector/C#/src/test/Cases/Cases.csproj b/src/connector/C#/src/test/Cases/Cases.csproj
index f2ae6938fb4b8c58d9bb657e5fb504814068e92e..57c0dd8f7d363e9da4ae580751cacf706f714883 100644
--- a/src/connector/C#/src/test/Cases/Cases.csproj
+++ b/src/connector/C#/src/test/Cases/Cases.csproj
@@ -9,4 +9,8 @@
net5.0
+
+ true
+ ..\doc\FunctionTest.XML
+
diff --git a/src/connector/C#/src/test/Cases/FetchLength.cs b/src/connector/C#/src/test/Cases/FetchLength.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b5c5c4ecadcd1ff67060a62ac6cfb460e65a530d
--- /dev/null
+++ b/src/connector/C#/src/test/Cases/FetchLength.cs
@@ -0,0 +1,44 @@
+using System;
+using Test.UtilsTools;
+using System.Collections.Generic;
+
+namespace Cases
+{
+
+ public class FetchLengthCase
+ {
+ /// xiaolei
+ /// TestRetrieveBinary
+ /// TD-12103 C# connector fetch_row with binary data retrieving error
+ /// FetchLength.cs
+ /// pass or failed
+ public void TestRetrieveBinary(IntPtr conn)
+ {
+ string sql1 = "create stable stb1 (ts timestamp, name binary(10)) tags(n int);";
+ string sql2 = "insert into tb1 using stb1 tags(1) values(now, 'log');";
+ string sql3 = "insert into tb2 using stb1 tags(2) values(now, 'test');";
+ string sql4 = "insert into tb3 using stb1 tags(3) values(now, 'db02');";
+ string sql5 = "insert into tb4 using stb1 tags(4) values(now, 'db3');";
+
+ string sql6 = "select distinct(name) from stb1;";//
+
+ UtilsTools.ExecuteQuery(conn, sql1);
+ UtilsTools.ExecuteQuery(conn, sql2);
+ UtilsTools.ExecuteQuery(conn, sql3);
+ UtilsTools.ExecuteQuery(conn, sql4);
+ UtilsTools.ExecuteQuery(conn, sql5);
+
+ IntPtr resPtr = IntPtr.Zero;
+ resPtr = UtilsTools.ExecuteQuery(conn, sql6);
+ List> result = UtilsTools.GetResultSet(resPtr);
+
+ List colname = result[0];
+ List data = result[1];
+ UtilsTools.AssertEqual("db3", data[0]);
+ UtilsTools.AssertEqual("log", data[1]);
+ UtilsTools.AssertEqual("db02", data[2]);
+ UtilsTools.AssertEqual("test", data[3]);
+
+ }
+ }
+}
diff --git a/src/connector/C#/src/test/Cases/Program.cs b/src/connector/C#/src/test/Cases/Program.cs
index a1b47f3890134040d3060fdb7b1e8d3beed4b7dd..89f878e994aa35977fc69c5576bca0ec21c41882 100644
--- a/src/connector/C#/src/test/Cases/Program.cs
+++ b/src/connector/C#/src/test/Cases/Program.cs
@@ -1,64 +1,67 @@
-using System;
-using Test.UtilsTools;
-using Cases;
-
-namespace Cases.EntryPoint
-{
- class Program
- {
-
- static void Main(string[] args)
- {
- IntPtr conn = IntPtr.Zero;
- IntPtr stmt = IntPtr.Zero;
- IntPtr res = IntPtr.Zero;
-
- conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0);
- UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
- UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650");
- UtilsTools.ExecuteQuery(conn, "use csharp");
-
- Console.WriteLine("====================StableColumnByColumn===================");
- StableColumnByColumn columnByColumn = new StableColumnByColumn();
- columnByColumn.Test(conn, "stablecolumnbycolumn");
- Console.WriteLine("====================StmtStableQuery===================");
- StmtStableQuery stmtStableQuery = new StmtStableQuery();
- stmtStableQuery.Test(conn, "stablecolumnbycolumn");
-
- Console.WriteLine("====================StableMutipleLine===================");
- StableMutipleLine mutipleLine = new StableMutipleLine();
- mutipleLine.Test(conn, "stablemutipleline");
-
- //================================================================================
-
- Console.WriteLine("====================NtableSingleLine===================");
- NtableSingleLine ntableSingleLine = new NtableSingleLine();
- ntableSingleLine.Test(conn, "stablesingleline");
-
- Console.WriteLine("====================NtableMutipleLine===================");
- NtableMutipleLine ntableMutipleLine = new NtableMutipleLine();
- ntableMutipleLine.Test(conn, "ntablemutipleline");
- Console.WriteLine("====================StmtNtableQuery===================");
- StmtNtableQuery stmtNtableQuery = new StmtNtableQuery();
- stmtNtableQuery.Test(conn, "ntablemutipleline");
-
- Console.WriteLine("====================NtableColumnByColumn===================");
- NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn();
- ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn");
-
- Console.WriteLine("====================fetchfeilds===================");
- FetchFields fetchFields = new FetchFields();
- fetchFields.Test(conn,"fetchfeilds");
-
- Console.WriteLine("===================JsonTagTest====================");
- JsonTagTest jsonTagTest = new JsonTagTest();
- jsonTagTest.Test(conn);
-
- // UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
- UtilsTools.CloseConnection(conn);
- UtilsTools.ExitProgram();
-
-
- }
- }
-}
+using System;
+using Test.UtilsTools;
+using Cases;
+
+namespace Cases.EntryPoint
+{
+ class Program
+ {
+
+ static void Main(string[] args)
+ {
+ IntPtr conn = IntPtr.Zero;
+ IntPtr stmt = IntPtr.Zero;
+ IntPtr res = IntPtr.Zero;
+
+ conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0);
+ UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
+ UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650");
+ UtilsTools.ExecuteQuery(conn, "use csharp");
+
+ Console.WriteLine("====================StableColumnByColumn===================");
+ StableColumnByColumn columnByColumn = new StableColumnByColumn();
+ columnByColumn.Test(conn, "stablecolumnbycolumn");
+ Console.WriteLine("====================StmtStableQuery===================");
+ StmtStableQuery stmtStableQuery = new StmtStableQuery();
+ stmtStableQuery.Test(conn, "stablecolumnbycolumn");
+
+ Console.WriteLine("====================StableMutipleLine===================");
+ StableMutipleLine mutipleLine = new StableMutipleLine();
+ mutipleLine.Test(conn, "stablemutipleline");
+
+ //================================================================================
+
+ Console.WriteLine("====================NtableSingleLine===================");
+ NtableSingleLine ntableSingleLine = new NtableSingleLine();
+ ntableSingleLine.Test(conn, "stablesingleline");
+
+ Console.WriteLine("====================NtableMutipleLine===================");
+ NtableMutipleLine ntableMutipleLine = new NtableMutipleLine();
+ ntableMutipleLine.Test(conn, "ntablemutipleline");
+ Console.WriteLine("====================StmtNtableQuery===================");
+ StmtNtableQuery stmtNtableQuery = new StmtNtableQuery();
+ stmtNtableQuery.Test(conn, "ntablemutipleline");
+
+ Console.WriteLine("====================NtableColumnByColumn===================");
+ NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn();
+ ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn");
+
+ Console.WriteLine("====================fetchfeilds===================");
+ FetchFields fetchFields = new FetchFields();
+ fetchFields.Test(conn, "fetchfeilds");
+
+ Console.WriteLine("===================JsonTagTest====================");
+ JsonTagTest jsonTagTest = new JsonTagTest();
+ jsonTagTest.Test(conn);
+
+ Console.WriteLine("====================fetchLengthCase===================");
+ FetchLengthCase fetchLengthCase = new FetchLengthCase();
+ fetchLengthCase.TestRetrieveBinary(conn);
+
+ UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
+ UtilsTools.CloseConnection(conn);
+ UtilsTools.ExitProgram();
+
+ }
+ }
+}
diff --git a/src/connector/C#/src/test/Cases/Utils.cs b/src/connector/C#/src/test/Cases/Utils.cs
index a549d75b16f76539b0f19d73eab576d0d9d582db..7877601e0adbc38c186bd44456ceb3005d806ff1 100644
--- a/src/connector/C#/src/test/Cases/Utils.cs
+++ b/src/connector/C#/src/test/Cases/Utils.cs
@@ -35,7 +35,6 @@ namespace Test.UtilsTools
else
{
Console.WriteLine(sql.ToString() + " success");
-
}
return res;
}
@@ -83,9 +82,13 @@ namespace Test.UtilsTools
IntPtr rowdata;
StringBuilder builder = new StringBuilder();
+
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
{
queryRows++;
+ IntPtr colLengthPtr = TDengine.FetchLengths(res);
+ int[] colLengthArr = new int[fieldCount];
+ Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount);
for (int fields = 0; fields < fieldCount; ++fields)
{
TDengineMeta meta = metas[fields];
@@ -131,7 +134,7 @@ namespace Test.UtilsTools
builder.Append(v7);
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
- string v8 = Marshal.PtrToStringAnsi(data);
+ string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
builder.Append(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
@@ -139,7 +142,7 @@ namespace Test.UtilsTools
builder.Append(v9);
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
- string v10 = Marshal.PtrToStringAnsi(data);
+ string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
builder.Append(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
@@ -164,6 +167,117 @@ namespace Test.UtilsTools
TDengine.FreeResult(res); Console.WriteLine("");
}
+ public static List> GetResultSet(IntPtr res)
+ {
+ List> result = new List>();
+ List colName = new List();
+ List dataRaw = new List();
+ long queryRows = 0;
+ if (!IsValidResult(res))
+ {
+ ExitProgram();
+ }
+
+ int fieldCount = TDengine.FieldCount(res);
+ List metas = TDengine.FetchFields(res);
+
+ for (int j = 0; j < metas.Count; j++)
+ {
+ TDengineMeta meta = (TDengineMeta)metas[j];
+ colName.Add(meta.name);
+ }
+ result.Add(colName);
+
+ IntPtr rowdata;
+ while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
+ {
+ queryRows++;
+ IntPtr colLengthPtr = TDengine.FetchLengths(res);
+ int[] colLengthArr = new int[fieldCount];
+ Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount);
+
+ for (int fields = 0; fields < fieldCount; ++fields)
+ {
+ TDengineMeta meta = metas[fields];
+ int offset = IntPtr.Size * fields;
+ IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
+
+ if (data == IntPtr.Zero)
+ {
+ dataRaw.Add("NULL");
+ continue;
+ }
+
+ switch ((TDengineDataType)meta.type)
+ {
+ case TDengineDataType.TSDB_DATA_TYPE_BOOL:
+ bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
+ dataRaw.Add(v1.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
+ byte v2 = Marshal.ReadByte(data);
+ dataRaw.Add(v2.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
+ short v3 = Marshal.ReadInt16(data);
+ dataRaw.Add(v3.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_INT:
+ int v4 = Marshal.ReadInt32(data);
+ dataRaw.Add(v4.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
+ long v5 = Marshal.ReadInt64(data);
+ dataRaw.Add(v5.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
+ float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
+ dataRaw.Add(v6.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
+ double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
+ dataRaw.Add(v7.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_BINARY:
+ string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
+ dataRaw.Add(v8);
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
+ long v9 = Marshal.ReadInt64(data);
+ dataRaw.Add(v9.ToString());
+ break;
+ case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
+ string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
+ dataRaw.Add(v10);
+ break;
+ }
+ }
+
+ }
+ result.Add(dataRaw);
+
+ if (TDengine.ErrorNo(res) != 0)
+ {
+ Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
+ }
+ TDengine.FreeResult(res); Console.WriteLine("");
+ return result;
+ }
+
+ public static bool IsValidResult(IntPtr res)
+ {
+ if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
+ {
+ if (res != IntPtr.Zero)
+ {
+ Console.Write("reason: " + TDengine.Error(res));
+ return false;
+ }
+ Console.WriteLine("");
+ return false;
+ }
+ return true;
+ }
public static void CloseConnection(IntPtr conn)
{
if (conn != IntPtr.Zero)
@@ -183,6 +297,18 @@ namespace Test.UtilsTools
List metas = TDengine.FetchFields(res);
return metas;
}
+ public static void AssertEqual(string expectVal, string actualVal)
+ {
+ if (expectVal == actualVal)
+ {
+ Console.WriteLine("{0}=={1} pass", expectVal, actualVal);
+ }
+ else
+ {
+ Console.WriteLine("{0}=={1} failed", expectVal, actualVal);
+ ExitProgram();
+ }
+ }
public static void ExitProgram()
{
TDengine.Cleanup();
diff --git a/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj b/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj
index 97d13e5e9e74abada2efa27d64e57adbe5459023..997a9d6fe072c01ffeb45a32773f8c76a530825c 100644
--- a/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj
+++ b/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj
@@ -2,10 +2,14 @@
net5.0
-
false
+
+ true
+ ..\doc\UnitTest.XML
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
index d8ac10d839651bb476a8688f28917aa356b5b1fe..9f573452b1aacbaaf8593433a0b0c5986ad9d3aa 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
@@ -443,16 +443,29 @@ public class TSDBResultSetRowData {
case 0: {
milliseconds = ts;
fracNanoseconds = (int) (ts * 1_000_000 % 1_000_000_000);
+ fracNanoseconds = fracNanoseconds < 0 ? 1_000_000_000 + fracNanoseconds : fracNanoseconds;
break;
}
case 1: {
milliseconds = ts / 1_000;
fracNanoseconds = (int) (ts * 1_000 % 1_000_000_000);
+ if (fracNanoseconds < 0) {
+ if (milliseconds == 0 ){
+ milliseconds = -1;
+ }
+ fracNanoseconds += 1_000_000_000;
+ }
break;
}
case 2: {
milliseconds = ts / 1_000_000;
fracNanoseconds = (int) (ts % 1_000_000_000);
+ if (fracNanoseconds < 0) {
+ if (milliseconds == 0 ){
+ milliseconds = -1;
+ }
+ fracNanoseconds += 1_000_000_000;
+ }
break;
}
default: {
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
index bfffaa4a129dc7fe19a92c34abbcc886d5e4e22f..4f7f123f5c8b135e757919c8913f1f1bb032d98e 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
@@ -1,23 +1,36 @@
package com.taosdata.jdbc.cases;
+import com.taosdata.jdbc.annotation.CatalogRunner;
+import com.taosdata.jdbc.annotation.Description;
+import com.taosdata.jdbc.annotation.TestTarget;
import com.taosdata.jdbc.utils.TimestampUtil;
import org.junit.*;
+import org.junit.runner.RunWith;
import java.sql.*;
+@RunWith(CatalogRunner.class)
+@TestTarget(alias = "negative value convert to timestamp", author = "huolibo", version = "2.0.37")
public class DatetimeBefore1970Test {
private static final String host = "127.0.0.1";
private Connection conn;
@Test
- public void test() throws SQLException {
+ @Description("millisecond")
+ public void msTest() throws SQLException {
+ conn = createEnvironment("ms");
+ long now = System.currentTimeMillis();
try (Statement stmt = conn.createStatement()) {
// given
+ // before
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 00:00:00.001')");
stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999')");
+ // zero
stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000')");
- stmt.executeUpdate("insert into weather(ts) values('1970-01-01 08:00:00.000')");
- stmt.executeUpdate("insert into weather(ts) values('1970-01-01 07:59:59.999')");
+ //after
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.001')");
+ stmt.executeUpdate("insert into weather(ts) values(" + now + ")");
ResultSet rs = stmt.executeQuery("select * from weather order by ts asc");
ResultSetMetaData metaData = rs.getMetaData();
Assert.assertEquals(2, metaData.getColumnCount());
@@ -26,44 +39,221 @@ public class DatetimeBefore1970Test {
rs.next();
// then
Timestamp ts = rs.getTimestamp("ts");
- Assert.assertEquals("1969-12-31 23:59:59.999", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(-24 * 60 * 60 * 1000 + 1, ts.getTime());
// when
rs.next();
// then
ts = rs.getTimestamp("ts");
- Assert.assertEquals("1970-01-01 00:00:00.000", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(-1, ts.getTime());
// when
rs.next();
// then
ts = rs.getTimestamp("ts");
- Assert.assertEquals("1970-01-01 08:00:00.000", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(0, ts.getTime());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(1, ts.getTime());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(now, ts.getTime());
+ }
+ }
+
+ @Test
+ @Description("microsecond")
+ public void usTest() throws SQLException {
+ conn = createEnvironment("us");
+ long now = System.currentTimeMillis();
+ try (Statement stmt = conn.createStatement()) {
+ // given
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 00:00:00.000001')");
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999999')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000000')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000001')");
+ stmt.executeUpdate("insert into weather(ts) values(" + now + ")");
+ ResultSet rs = stmt.executeQuery("select * from weather order by ts asc");
+ ResultSetMetaData metaData = rs.getMetaData();
+ Assert.assertEquals(2, metaData.getColumnCount());
+
+ // when
+ rs.next();
+ // then
+ Timestamp ts = rs.getTimestamp("ts");
+ Assert.assertEquals(-24 * 60 * 60 * 1000, ts.getTime());
+ Assert.assertEquals(1_000, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(-1, ts.getTime());
+ Assert.assertEquals(999_999_000, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(0, ts.getTime());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(0, ts.getTime());
+ Assert.assertEquals(1_000, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ String s = String.valueOf(now);
+ Assert.assertEquals(Long.parseLong(s.substring(0, s.length() - 3)), ts.getTime());
+ Assert.assertEquals(Long.parseLong(s.substring(s.length() - 6) + "000"), ts.getNanos());
+ }
+ }
+
+ @Test
+ @Description("nanosecond")
+ public void nanoTest() throws SQLException {
+ conn = createEnvironment("ns");
+ long now = System.currentTimeMillis() * 1000_000L + System.nanoTime() % 1000_000L;
+ try (Statement stmt = conn.createStatement()) {
+ // given
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 00:00:00.000000123')");
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999999999')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000000001')");
+ stmt.executeUpdate("insert into weather(ts) values(" + now + ")");
+ ResultSet rs = stmt.executeQuery("select * from weather order by ts asc");
+ ResultSetMetaData metaData = rs.getMetaData();
+ Assert.assertEquals(2, metaData.getColumnCount());
+
+ // when
+ rs.next();
+ // then
+ Timestamp ts = rs.getTimestamp("ts");
+ Assert.assertEquals(-24 * 60 * 60 * 1_000, ts.getTime());
+ Assert.assertEquals(123, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(-1, ts.getTime());
+ Assert.assertEquals(999999999, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(0, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals(1, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ String s = String.valueOf(now);
+ Assert.assertEquals(Long.parseLong(s.substring(0, s.length() - 6)), ts.getTime());
+ Assert.assertEquals(Long.parseLong(s.substring(s.length() - 9)), ts.getNanos());
+ }
+ }
+
+ @Test
+ @Ignore
+ @Description("nanosecond convert timestamp when timezone is asia shanghai")
+ public void asiaShanghaiTest() throws SQLException {
+ conn = createEnvironment("ns");
+ long now = System.currentTimeMillis() * 1000_000L + System.nanoTime() % 1000_000L;
+ try (Statement stmt = conn.createStatement()) {
+ // given
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 00:00:00.000000123')");
+ stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999999999')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000')");
+ stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000000001')");
+ stmt.executeUpdate("insert into weather(ts) values(" + now + ")");
+ ResultSet rs = stmt.executeQuery("select * from weather order by ts asc");
+ ResultSetMetaData metaData = rs.getMetaData();
+ Assert.assertEquals(2, metaData.getColumnCount());
+
+ // when
+ rs.next();
+ // then
+ Timestamp ts = rs.getTimestamp("ts");
+ Assert.assertEquals("1969-12-31 08:00:00.000", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(123, ts.getNanos());
// when
rs.next();
// then
ts = rs.getTimestamp("ts");
Assert.assertEquals("1970-01-01 07:59:59.999", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(999999999, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals("1970-01-01 08:00:00.000", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(0, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ Assert.assertEquals("1970-01-01 08:00:00.000", TimestampUtil.longToDatetime(ts.getTime()));
+ Assert.assertEquals(1, ts.getNanos());
+
+ // when
+ rs.next();
+ // then
+ ts = rs.getTimestamp("ts");
+ String s = String.valueOf(now);
+ Assert.assertEquals(Long.parseLong(s.substring(0, s.length() - 6)), ts.getTime());
+ Assert.assertEquals(Long.parseLong(s.substring(s.length() - 9)), ts.getNanos());
}
}
- @Before
- public void before() throws SQLException {
- conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
+ private Connection createEnvironment(String precision) throws SQLException {
+ String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata&timezone=UTC";
+ String createSql = "create database if not exists test_timestamp keep 36500";
+ if (!isEmpty(precision)) {
+ createSql += " precision '" + precision + "'";
+ }
+ conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists test_timestamp");
- stmt.execute("create database if not exists test_timestamp keep 36500");
+ stmt.execute(createSql);
stmt.execute("use test_timestamp");
stmt.execute("create table weather(ts timestamp,f1 float)");
stmt.close();
+ return conn;
+ }
+
+ private boolean isEmpty(String string) {
+ return null == string || string.trim().equals("");
}
@After
public void after() throws SQLException {
- Statement stmt = conn.createStatement();
- stmt.execute("drop database if exists test_timestamp");
- if (conn != null)
+ if (conn != null) {
+ Statement stmt = conn.createStatement();
+ stmt.execute("drop database if exists test_timestamp");
+ stmt.close();
conn.close();
+ }
}
}
diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h
index 8700cf246a91655c307bbb4c3c2c111d3271fc67..fb70badb862943a0259b2dc94bf52b0a452bd714 100644
--- a/src/inc/taoserror.h
+++ b/src/inc/taoserror.h
@@ -274,7 +274,6 @@ int32_t* taosGetErrno();
#define TSDB_CODE_TDB_IVLD_TAG_VAL TAOS_DEF_ERROR_CODE(0, 0x0615) //"TSDB invalid tag value")
#define TSDB_CODE_TDB_NO_CACHE_LAST_ROW TAOS_DEF_ERROR_CODE(0, 0x0616) //"TSDB no cache last row data")
#define TSDB_CODE_TDB_INCOMPLETE_DFILESET TAOS_DEF_ERROR_CODE(0, 0x0617) //"TSDB incomplete DFileSet")
-#define TSDB_CODE_TDB_NO_JSON_TAG_KEY TAOS_DEF_ERROR_CODE(0, 0x0618) //"TSDB no tag json key")
// query
#define TSDB_CODE_QRY_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0700) //"Invalid handle")
diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c
index 2ba143b147d5924eb07aeb9bb2fd321b5d519573..6346e743081a6594fcc9e8d8001ae18e3f90ac92 100644
--- a/src/query/src/qExecutor.c
+++ b/src/query/src/qExecutor.c
@@ -1942,7 +1942,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr
for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
int16_t type = pSqlExpr->param[j].nType;
int16_t bytes = pSqlExpr->param[j].nLen;
- if (pSqlExpr->functionId == TSDB_FUNC_STDDEV_DST) {
+ if (pSqlExpr->functionId == TSDB_FUNC_STDDEV_DST || pSqlExpr->functionId == TSDB_FUNC_TS_COMP) {
continue;
}
diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c
index cc214b953303e3b10b053bbe0c183eaee520e32a..9d174b0389d74073b5989af5a8fd7c26d5fd80dd 100644
--- a/src/query/src/qExtbuffer.c
+++ b/src/query/src/qExtbuffer.c
@@ -1040,7 +1040,10 @@ void tColModelDisplay(SColumnModel *pModel, void *pData, int32_t numOfRows, int3
break;
case TSDB_DATA_TYPE_NCHAR: {
char buf[4096] = {0};
- taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
+ int32_t len = taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
+ if (len < 0){
+ qError("castConvert1 taosUcs4ToMbs error");
+ }
printf("%s\t", buf);
break;
}
@@ -1092,7 +1095,10 @@ void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, in
break;
case TSDB_DATA_TYPE_NCHAR: {
char buf[128] = {0};
- taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
+ int32_t len = taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
+ if (len < 0){
+ qError("castConvert1 taosUcs4ToMbs error");
+ }
printf("%s\t", buf);
break;
}
diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c
index 05ecda2a51f33c00130bcad0c5aa7139e7429a48..6869017e116ab9fe9dce30fbb028242f0e990a4b 100644
--- a/src/query/src/qFilter.c
+++ b/src/query/src/qFilter.c
@@ -1899,12 +1899,20 @@ int32_t filterInitValFieldData(SFilterInfo *info) {
(unit->compare.optr == TSDB_RELATION_MATCH || unit->compare.optr == TSDB_RELATION_NMATCH)){
char newValData[TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE] = {0};
int32_t len = taosUcs4ToMbs(varDataVal(fi->data), varDataLen(fi->data), varDataVal(newValData));
+ if (len < 0){
+ qError("filterInitValFieldData taosUcs4ToMbs error 1");
+ return TSDB_CODE_FAILED;
+ }
varDataSetLen(newValData, len);
varDataCopy(fi->data, newValData);
}else if(type == TSDB_DATA_TYPE_JSON &&
(unit->compare.optr == TSDB_RELATION_MATCH || unit->compare.optr == TSDB_RELATION_NMATCH)){
char newValData[TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE] = {0};
int32_t len = taosUcs4ToMbs(((tVariant*)(fi->desc))->pz, ((tVariant*)(fi->desc))->nLen, newValData);
+ if (len < 0){
+ qError("filterInitValFieldData taosUcs4ToMbs error 2");
+ return TSDB_CODE_FAILED;
+ }
memcpy(((tVariant*)(fi->desc))->pz, newValData, len);
((tVariant*)(fi->desc))->nLen = len;
}
@@ -3025,6 +3033,11 @@ static void doJsonCompare(SFilterComUnit *cunit, int8_t *result, void* colData){
}else{
char *newColData = calloc(cunit->dataSize * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 1);
int len = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), varDataVal(newColData));
+ if (len < 0){
+ qError("castConvert1 taosUcs4ToMbs error");
+ tfree(newColData);
+ return;
+ }
varDataSetLen(newColData, len);
tVariant* val = cunit->valData;
char newValData[TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE] = {0};
@@ -3113,9 +3126,13 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat
if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_NCHAR && (info->cunits[uidx].optr == TSDB_RELATION_MATCH || info->cunits[uidx].optr == TSDB_RELATION_NMATCH)){
char *newColData = calloc(info->cunits[uidx].dataSize * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 1);
- int len = taosUcs4ToMbs(varDataVal(colData), varDataLen(colData), varDataVal(newColData));
- varDataSetLen(newColData, len);
- (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, newColData, info->cunits[uidx].valData);
+ int32_t len = taosUcs4ToMbs(varDataVal(colData), varDataLen(colData), varDataVal(newColData));
+ if (len < 0){
+ qError("castConvert1 taosUcs4ToMbs error");
+ }else{
+ varDataSetLen(newColData, len);
+ (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, newColData, info->cunits[uidx].valData);
+ }
tfree(newColData);
}else if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){
doJsonCompare(&(info->cunits[uidx]), &(*p)[i], colData);
@@ -3170,9 +3187,13 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *
} else {
if(cunit->dataType == TSDB_DATA_TYPE_NCHAR && (cunit->optr == TSDB_RELATION_MATCH || cunit->optr == TSDB_RELATION_NMATCH)){
char *newColData = calloc(cunit->dataSize * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 1);
- int len = taosUcs4ToMbs(varDataVal(colData), varDataLen(colData), varDataVal(newColData));
- varDataSetLen(newColData, len);
- (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, newColData, cunit->valData);
+ int32_t len = taosUcs4ToMbs(varDataVal(colData), varDataLen(colData), varDataVal(newColData));
+ if (len < 0){
+ qError("castConvert1 taosUcs4ToMbs error");
+ }else{
+ varDataSetLen(newColData, len);
+ (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, newColData, cunit->valData);
+ }
tfree(newColData);
}else if(cunit->dataType == TSDB_DATA_TYPE_JSON){
doJsonCompare(cunit, &(*p)[i], colData);
@@ -3577,7 +3598,11 @@ int32_t filterConverNcharColumns(SFilterInfo* info, int32_t rows, bool *gotNchar
char *src = FILTER_GET_COL_FIELD_DATA(fi, j);
char *dst = FILTER_GET_COL_FIELD_DATA(&nfi, j);
int32_t len = 0;
- taosMbsToUcs4(varDataVal(src), varDataLen(src), varDataVal(dst), bufSize, &len);
+ bool ret = taosMbsToUcs4(varDataVal(src), varDataLen(src), varDataVal(dst), bufSize, &len);
+ if(!ret) {
+ qError("filterConverNcharColumns taosMbsToUcs4 error");
+ return TSDB_CODE_FAILED;
+ }
varDataLen(dst) = len;
}
diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c
index 229d684e8364a4c1aabc5cf1825e45cc698a1de3..a095bff61e05822f6389a51671f98fc5a33e0bbe 100644
--- a/src/tsdb/src/tsdbMeta.c
+++ b/src/tsdb/src/tsdbMeta.c
@@ -1463,6 +1463,7 @@ static void *tsdbDecodeTable(void *buf, STable **pRTable) {
tsdbFreeTable(pTable);
return NULL;
}
+ taosHashSetFreeFp(pTable->jsonKeyMap, taosArrayDestroyForHash);
}else{
pTable->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, colType(pCol), (uint8_t)(colBytes(pCol)), NULL,
SL_ALLOW_DUP_KEY, getTagIndexKey);
diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c
index f3241cd0e0ea4c7929c6d0c82df339a513299c7d..be734ce0cccad6827cba4e2c27d0be478af92af3 100644
--- a/src/tsdb/src/tsdbRead.c
+++ b/src/tsdb/src/tsdbRead.c
@@ -4243,20 +4243,28 @@ char* parseTagDatatoJson(void *p){
}
cJSON_AddItemToObject(json, tagJsonKey, value);
}else if(type == TSDB_DATA_TYPE_NCHAR) {
- char *tagJsonValue = calloc(varDataLen(realData), 1);
- int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), tagJsonValue);
- if (length < 0) {
- tsdbError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
- (char*)val);
+ cJSON* value = NULL;
+ if (varDataLen(realData) > 0){
+ char *tagJsonValue = calloc(varDataLen(realData), 1);
+ int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), tagJsonValue);
+ if (length < 0) {
+ tsdbError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
+ (char*)val);
+ free(tagJsonValue);
+ goto end;
+ }
+ value = cJSON_CreateString(tagJsonValue);
free(tagJsonValue);
- goto end;
- }
- cJSON* value = cJSON_CreateString(tagJsonValue);
- free(tagJsonValue);
- if (value == NULL)
- {
- goto end;
+ if (value == NULL)
+ {
+ goto end;
+ }
+ }else if(varDataLen(realData) == 0){
+ value = cJSON_CreateString("");
+ }else{
+ assert(0);
}
+
cJSON_AddItemToObject(json, tagJsonKey, value);
}else if(type == TSDB_DATA_TYPE_DOUBLE){
double jsonVd = *(double*)(realData);
diff --git a/src/util/src/terror.c b/src/util/src/terror.c
index 3853d2e9c7491db68abf4ca9f7d42edd62da5729..acbee18ec21b02761295de90ef9ff535a97739d1 100644
--- a/src/util/src/terror.c
+++ b/src/util/src/terror.c
@@ -282,7 +282,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, "TSDB messed message")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVLD_TAG_VAL, "TSDB invalid tag value")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_CACHE_LAST_ROW, "TSDB no cache last row data")
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INCOMPLETE_DFILESET, "Incomplete DFileSet")
-TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_JSON_TAG_KEY, "TSDB no tag json key")
// query
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, "Invalid handle")
diff --git a/tests/system-test/2-query/TD-11256.py b/tests/system-test/2-query/TD-11256.py
new file mode 100644
index 0000000000000000000000000000000000000000..f101ad211377310d01ad44504e2e1c60a405e826
--- /dev/null
+++ b/tests/system-test/2-query/TD-11256.py
@@ -0,0 +1,78 @@
+###################################################################
+# Copyright (c) 2020 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import taos
+import time
+
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import *
+
+
+class TDTestCase:
+ def __init__(self):
+ self.err_case = 0
+ self.curret_case = 0
+
+ def caseDescription(self):
+
+ '''
+ case1 : [TD-11256] query the super table in a mixed way of expression + tbanme and using group by tbname
+ '''
+ return
+
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ def create_stb(self):
+ basetime = int(round(time.time() * 1000))
+ tdSql.prepare()
+ tdSql.execute(f"create stable stb1(ts timestamp, c1 int) tags (tag1 int)")
+ for i in range(10):
+ tdSql.execute(f"create table t{i} using stb1 tags({i})")
+ tdSql.execute(f"insert into t{i} values ({basetime}, {i})")
+
+ pass
+
+ def check_td11256(self):
+ # this case expect connect is current after run group by sql
+ tdSql.query("select count(*) from stb1 group by ts")
+ try:
+ tdSql.error("select c1/2, tbname from stb1 group by tbname")
+ tdSql.query("show databases")
+ self.curret_case += 1
+ tdLog.printNoPrefix("the case1: td-11256 run passed")
+ except:
+ self.err_case += 1
+ tdLog.printNoPrefix("the case1: td-11256 run failed")
+ pass
+
+ def run(self):
+ self.create_stb()
+
+ self.check_td11256()
+
+ if self.err_case > 0:
+ tdLog.exit(f"{self.err_case} case for TD-11256 run failed")
+ else:
+ tdLog.success("case for TD-11256 run passed")
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/system-test/4-taosAdapter/TD-12163.py b/tests/system-test/4-taosAdapter/TD-12163.py
new file mode 100644
index 0000000000000000000000000000000000000000..aafc218611c1c51e3d6f82d802c95fd8e2c16cf5
--- /dev/null
+++ b/tests/system-test/4-taosAdapter/TD-12163.py
@@ -0,0 +1,118 @@
+###################################################################
+# Copyright (c) 2020 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from taosdata
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import taos
+import time
+import requests
+
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import *
+
+
+class TDTestCase:
+ def __init__(self):
+ self.err_case = 0
+ self.curret_case = 0
+ self.url = "http://127.0.0.1:6041/rest/sql"
+ self.header = {'Authorization': 'Basic cm9vdDp0YW9zZGF0YQ=='}
+
+ def caseDescription(self):
+
+ '''
+ case1 : [TD-12163] alter table-schema using restful interface
+ '''
+ return
+
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ def check_td12163(self):
+ # basetime = int(round(time.time() * 1000))
+ tdSql.prepare()
+ tdSql.execute(f"create stable stb1(ts timestamp, c1 int) tags (tag1 int)")
+ tdSql.execute(f"create table nt1 (nts timestamp, nc1 int)")
+
+ add_column_stb = "alter table db.stb1 add column c2 float"
+ drop_column_stb = "alter table db.stb1 drop column c2 "
+ add_column_ntb = "alter table db.nt1 add column nc2 float"
+ drop_column_ntb = "alter table db.nt1 drop column nc2 "
+
+ conn_add_stb = requests.post(url=self.url, headers=self.header, data=add_column_stb)
+ resp_code_stb_add = conn_add_stb.status_code
+ resp_add_stb = conn_add_stb.json()
+ try:
+ assert resp_code_stb_add//200 == 1
+ assert resp_add_stb["status"] == "succ"
+ self.curret_case += 1
+ tdLog.printNoPrefix("the case add column to stable successful")
+ except:
+ self.err_case += 1
+ tdLog.printNoPrefix("the case add column to stable failed")
+
+
+ conn_add_ntb = requests.post(url=self.url, headers=self.header, data=add_column_ntb)
+ resp_code_ntb_add = conn_add_ntb.status_code
+ resp_add_ntb = conn_add_ntb.json()
+ try:
+ assert resp_code_ntb_add//200 == 1
+ assert resp_add_ntb["status"] == "succ"
+ self.curret_case += 1
+ tdLog.printNoPrefix("the case add column to normal table successful")
+ except:
+ self.err_case += 1
+ tdLog.printNoPrefix("the case add column to normal table failed")
+
+ conn_drop_stb = requests.post(url=self.url, headers=self.header, data=drop_column_stb)
+ resp_code_stb_drop = conn_drop_stb.status_code
+ resp_drop_stb = conn_drop_stb.json()
+ try:
+ assert resp_code_stb_drop // 200 == 1
+ assert resp_drop_stb["status"] == "succ"
+ self.curret_case += 1
+ tdLog.printNoPrefix("the case drop column to stable successful")
+ except:
+ self.err_case += 1
+ tdLog.printNoPrefix("the case add column to stable failed")
+
+ conn_drop_ntb = requests.post(url=self.url, headers=self.header, data=drop_column_ntb)
+ resp_code_ntb_drop = conn_drop_ntb.status_code
+ resp_drop_ntb = conn_drop_ntb.json()
+ try:
+ assert resp_code_ntb_drop // 200 == 1
+ assert resp_drop_ntb["status"] == "succ"
+ self.curret_case += 1
+ tdLog.printNoPrefix("the case drop column to stable successful")
+ except:
+ self.err_case += 1
+ tdLog.printNoPrefix("the case add column to stable failed")
+
+ pass
+
+ def run(self):
+ self.check_td12163()
+
+ if self.err_case > 0:
+ tdLog.exit(f"{self.err_case} case for TD-12163 run failed")
+ else:
+ tdLog.success("case for TD-12163 run passed")
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/system-test/fulltest-query.sh b/tests/system-test/fulltest-query.sh
index 1db24953488aedeaac3ef8d378f317f09c6c7f71..104781def751ca8df6028dc7afe5dd80a172b4ff 100755
--- a/tests/system-test/fulltest-query.sh
+++ b/tests/system-test/fulltest-query.sh
@@ -1,3 +1,8 @@
+
+python3 ./test.py -f 2-query/ts_hidden_column.py
+python3 ./test.py -f 2-query/union-order.py
+python3 test.py -f 2-query/TD-11256.py
+
python3 ./test.py -f 2-query/TD-11389.py
python3 ./test.py -f 2-query/TD-11945_crash.py
python3 ./test.py -f 2-query/TD-12340-12342.py
diff --git a/tests/system-test/fulltest-taosAdapter.sh b/tests/system-test/fulltest-taosAdapter.sh
index 930236e024f07520cd7a6872cf4101d207a4cedd..f7ca439fd4407438d3ffaf11a6dcd2c839508404 100755
--- a/tests/system-test/fulltest-taosAdapter.sh
+++ b/tests/system-test/fulltest-taosAdapter.sh
@@ -1,2 +1,3 @@
+python3 test.py -f 4-taosAdapter/TD-12163.py
python3 ./test.py -f 4-taosAdapter/taosAdapter_insert.py
python3 ./test.py -f 4-taosAdapter/taosAdapter_query.py
\ No newline at end of file