diff --git a/documentation20/webdocs/markdowndocs/faq-ch.md b/documentation20/webdocs/markdowndocs/faq-ch.md index 757b6d9929b68a90e7bc558b553233f24b09ba17..42f9761c95f8d10af48af6b669dee00723c6e238 100644 --- a/documentation20/webdocs/markdowndocs/faq-ch.md +++ b/documentation20/webdocs/markdowndocs/faq-ch.md @@ -101,7 +101,20 @@ Connection = DriverManager.getConnection(url, properties); 2.0.4 ``` -## 14. 怎么报告问题? +## 14. taos connect failed, reason: invalid timestamp + +常见原因是服务器和客户端时间没有校准,可以通过和时间服务器同步的方式(Linux 下使用 ntpdate 命令,Windows 在系统时间设置中选择自动同步)校准。 + + + +## 15. 表名显示不全 + +由于 taos shell 在终端中显示宽度有限,有可能比较长的表名显示不全,如果按照显示的不全的表名进行相关操作会发生 Table does not exist 错误。解决方法可以是通过修改 taos.cfg 文件中的设置项 maxBinaryDisplayWidth, 或者直接输入命令 set max_binary_display_width 100。或者在命令结尾使用 \G 参数来调整结果的显示方式。 + + + +## 16. 怎么报告问题? + 如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包: 1. /var/log/taos 2. /etc/taos diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg index ff4beea6e20a09ef5a670ab2c33e9a6e248ffcff..8a68d02dfd232e557d0877e738aa8aa33a02467f 100644 --- a/packaging/cfg/taos.cfg +++ b/packaging/cfg/taos.cfg @@ -251,7 +251,7 @@ # cqDebugFlag 131 # enable/disable recording the SQL in taos client -# tscEnableRecordSql 0 +# enableRecordSql 0 # generate core file when service crash # enableCoreFile 1 @@ -264,3 +264,6 @@ # enable/disable stream (continuous query) # stream 1 + +# only 50% CPU resources will be used in query processing +# halfCoresForQuery 0 diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c index 56b7f052f75e60214c46d18a2cbe80fcba6cb9ae..594a4c39b55071aeb5f3010a435717fb321abe38 100644 --- a/src/client/src/tscFunctionImpl.c +++ b/src/client/src/tscFunctionImpl.c @@ -4540,11 +4540,11 @@ static void sumrate_finalizer(SQLFunctionCtx *pCtx) { * */ int32_t functionCompatList[] = { - // count, sum, avg, min, max, stddev, percentile, apercentile, first, last - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - // last_row, top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_z + // count, sum, avg, min, max, stddev, percentile, apercentile, first, last + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_z 4, -1, -1, 1, 1, 1, 1, 1, 1, -1, - // tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, interp rate irate + // tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, interp rate irate 1, 1, 1, 1, -1, 1, 1, 5, 1, 1, // sum_rate, sum_irate, avg_rate, avg_irate 1, 1, 1, 1, diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 6de8195d736e33dd0920590731221e0baf7b7d71..18e5b6f0744a06e5d28f2ce5cfa3df1244a0dc89 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -630,11 +630,17 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3 return TSDB_CODE_SUCCESS; } -static void tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) { +static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) { pBlocks->tid = pTableMeta->id.tid; pBlocks->uid = pTableMeta->id.uid; pBlocks->sversion = pTableMeta->sversion; - pBlocks->numOfRows += numOfRows; + + if (pBlocks->numOfRows + numOfRows >= INT16_MAX) { + return TSDB_CODE_TSC_INVALID_SQL; + } else { + pBlocks->numOfRows += numOfRows; + return TSDB_CODE_SUCCESS; + } } // data block is disordered, sort it in ascending order @@ -722,7 +728,11 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableList, char **st } SSubmitBlk *pBlocks = (SSubmitBlk *)(dataBuf->pData); - tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); + code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); + if (code != TSDB_CODE_SUCCESS) { + tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", *str); + return code; + } dataBuf->vgId = pTableMeta->vgroupInfo.vgId; dataBuf->numOfTables = 1; @@ -1384,7 +1394,10 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta; SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData); - tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); + code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows); + if (code != TSDB_CODE_SUCCESS) { + return tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", NULL); + } if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) { return code; diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index acc5acd786bfe00036e539a104da04af1485a263..18fc79c4748f84d4ec073e4bc678e3a067afb025 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -39,6 +39,7 @@ void tscInitConnCb(void *param, TAOS_RES *result, int code) { tscSlowQueryConnInitialized = true; tscSaveSlowQueryFp(sql, NULL); } + taos_free_result(result); } void tscAddIntoSqlList(SSqlObj *pSql) { @@ -69,6 +70,7 @@ void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) { } else { tscDebug("success to save slow query, code:%d", code); } + taos_free_result(result); } void tscSaveSlowQueryFp(void *handle, void *tmrId) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 1e6f931fe39a18c7b0abbe13737038b500dd4f0a..91b00e0109b0551b3bde52e326966ff396921019 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2835,6 +2835,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) { if (functionCompatList[functionId] != factor) { return false; + } else { + if (factor == -1) { // two functions with the same -1 flag + return false; + } } if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) { diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index 91eabda78b8082355e9b48b0cf52c5495304710b..6aea03d2141f3f512c0df042c5984f4a408fcb52 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -144,7 +144,7 @@ void taos_init_imp(void) { int64_t refreshTime = 10; // 10 seconds by default if (tscMetaCache == NULL) { tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta"); - tscObjRef = taosOpenRef(4096, tscFreeRegisteredSqlObj); + tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj); } tscRefId = taosOpenRef(200, tscCloseTscObj); diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 7ba7260af22be7e817e673d2f92756f661ef5703..851ca57ba9be376ab8cef06567ec8c6f1206a8e4 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -56,6 +56,7 @@ extern char tsTempDir[]; //query buffer management extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing +extern int32_t tsHalfCoresForQuery; // only 50% will be used in query processing // client extern int32_t tsTableMetaKeepTimer; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index dd4b738949419e6d3f92ef3c27d6e18601a44840..a912cdfd7f531a6d863323056b1d9f78857a9284 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -107,6 +107,9 @@ int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance // positive value (in MB) int32_t tsQueryBufferSize = -1; +// only 50% cpu will be used in query processing in dnode +int32_t tsHalfCoresForQuery = 0; + // db parameters int32_t tsCacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE; int32_t tsBlocksPerVnode = TSDB_DEFAULT_TOTAL_BLOCKS; @@ -884,6 +887,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_BYTE; taosInitConfigOption(cfg); + cfg.option = "halfCoresForQuery"; + cfg.ptr = &tsHalfCoresForQuery; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; + cfg.minValue = 0; + cfg.maxValue = 1; + cfg.ptrLength = 1; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + // locale & charset cfg.option = "timezone"; cfg.ptr = tsTimezone; @@ -1290,7 +1303,7 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); - cfg.option = "tscEnableRecordSql"; + cfg.option = "enableRecordSql"; cfg.ptr = &tsTscEnableRecordSql; cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; diff --git a/src/connector/python/linux/python2/setup.py b/src/connector/python/linux/python2/setup.py index b3daa98bdce79adc479ac4c529bb2d2f4fe36696..92a931b504fd76d12c1a4094a04fed4f859c0a3e 100644 --- a/src/connector/python/linux/python2/setup.py +++ b/src/connector/python/linux/python2/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.2", + version="2.0.3", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/linux/python2/taos/__init__.py b/src/connector/python/linux/python2/taos/__init__.py index 4894488bc8d4e594c11a8be61fbea278ca2588fa..62e0536b6fca63a0aca0b6be3673104c27c631c6 100644 --- a/src/connector/python/linux/python2/taos/__init__.py +++ b/src/connector/python/linux/python2/taos/__init__.py @@ -3,7 +3,7 @@ from .connection import TDengineConnection from .cursor import TDengineCursor # Globals -apilevel = '2.0' +apilevel = '2.0.3' threadsafety = 0 paramstyle = 'pyformat' diff --git a/src/connector/python/linux/python2/taos/cinterface.py b/src/connector/python/linux/python2/taos/cinterface.py index 6f0435722ffba7a3cf6e2fb22591b1d037397156..2b1b29ee31af56499d626fc56d4950e2e25f9978 100644 --- a/src/connector/python/linux/python2/taos/cinterface.py +++ b/src/connector/python/linux/python2/taos/cinterface.py @@ -81,6 +81,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) if num_of_rows > 0: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] else: @@ -106,6 +107,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) res=[] if num_of_rows > 0: for i in range(abs(num_of_rows)): diff --git a/src/connector/python/linux/python2/taos/cursor.py b/src/connector/python/linux/python2/taos/cursor.py index eee5e3948894b710217038f6e52db24a96212d60..82a01be67118813f9c83c3c3870d91535e13c526 100644 --- a/src/connector/python/linux/python2/taos/cursor.py +++ b/src/connector/python/linux/python2/taos/cursor.py @@ -26,7 +26,7 @@ class TDengineCursor(object): """ def __init__(self, connection=None): - self._description = None + self._description = [] self._rowcount = -1 self._connection = None self._result = None @@ -234,7 +234,7 @@ class TDengineCursor(object): def _reset_result(self): """Reset the result to unused version. """ - self._description = None + self._description = [] self._rowcount = -1 if self._result is not None: CTaosInterface.freeResult(self._result) diff --git a/src/connector/python/linux/python3/setup.py b/src/connector/python/linux/python3/setup.py index f49ebe2b6d188bf8c25623fbdde4c610a6b66231..655a12ad135e4eae575061e6069724a12a2a6996 100644 --- a/src/connector/python/linux/python3/setup.py +++ b/src/connector/python/linux/python3/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.2", + version="2.0.3", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/linux/python3/taos/__init__.py b/src/connector/python/linux/python3/taos/__init__.py index 4894488bc8d4e594c11a8be61fbea278ca2588fa..8cf095ea68dda55a071403734d39e9198a71d8a1 100644 --- a/src/connector/python/linux/python3/taos/__init__.py +++ b/src/connector/python/linux/python3/taos/__init__.py @@ -3,7 +3,7 @@ from .connection import TDengineConnection from .cursor import TDengineCursor # Globals -apilevel = '2.0' +apilevel = '2.0.3' threadsafety = 0 paramstyle = 'pyformat' @@ -21,4 +21,4 @@ def connect(*args, **kwargs): @rtype: TDengineConnector """ - return TDengineConnection(*args, **kwargs) \ No newline at end of file + return TDengineConnection(*args, **kwargs) diff --git a/src/connector/python/linux/python3/taos/cinterface.py b/src/connector/python/linux/python3/taos/cinterface.py index bbf5a0c7146f1fbc22befe50691df460ca8191c2..fdebe349fe9597260f231adb52022a2ecc9e1063 100644 --- a/src/connector/python/linux/python3/taos/cinterface.py +++ b/src/connector/python/linux/python3/taos/cinterface.py @@ -81,6 +81,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) if num_of_rows > 0: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] else: @@ -106,6 +107,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) res=[] if num_of_rows > 0: for i in range(abs(num_of_rows)): diff --git a/src/connector/python/linux/python3/taos/cursor.py b/src/connector/python/linux/python3/taos/cursor.py index d8184668c8a13daafad86a17906d2077afe62b5a..0ce20f0edaabe5cf0d2bb6efa3e031f51779f03d 100644 --- a/src/connector/python/linux/python3/taos/cursor.py +++ b/src/connector/python/linux/python3/taos/cursor.py @@ -27,7 +27,7 @@ class TDengineCursor(object): """ def __init__(self, connection=None): - self._description = None + self._description = [] self._rowcount = -1 self._connection = None self._result = None @@ -242,7 +242,7 @@ class TDengineCursor(object): def _reset_result(self): """Reset the result to unused version. """ - self._description = None + self._description = [] self._rowcount = -1 if self._result is not None: CTaosInterface.freeResult(self._result) diff --git a/src/connector/python/windows/python2/setup.py b/src/connector/python/windows/python2/setup.py index 34cb7a04d701395cedc60ef13e541ad0c8303ec5..5ddbe83011daa9d408e22dbeda7172466329921e 100644 --- a/src/connector/python/windows/python2/setup.py +++ b/src/connector/python/windows/python2/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.2", + version="2.0.3", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/windows/python2/taos/__init__.py b/src/connector/python/windows/python2/taos/__init__.py index 4894488bc8d4e594c11a8be61fbea278ca2588fa..62e0536b6fca63a0aca0b6be3673104c27c631c6 100644 --- a/src/connector/python/windows/python2/taos/__init__.py +++ b/src/connector/python/windows/python2/taos/__init__.py @@ -3,7 +3,7 @@ from .connection import TDengineConnection from .cursor import TDengineCursor # Globals -apilevel = '2.0' +apilevel = '2.0.3' threadsafety = 0 paramstyle = 'pyformat' diff --git a/src/connector/python/windows/python2/taos/cinterface.py b/src/connector/python/windows/python2/taos/cinterface.py index d4bf1a0350680c407dd6b957ea3f59c0c3c9612f..14f4f49be8ae719da16dbed7e79631db7ef9689e 100644 --- a/src/connector/python/windows/python2/taos/cinterface.py +++ b/src/connector/python/windows/python2/taos/cinterface.py @@ -81,6 +81,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) if num_of_rows > 0: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] else: @@ -106,6 +107,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) res=[] if num_of_rows > 0: for i in range(abs(num_of_rows)): diff --git a/src/connector/python/windows/python2/taos/cursor.py b/src/connector/python/windows/python2/taos/cursor.py index 71651afee1c2232ea6dc7a402e15a27ff9a6d72d..f6fde2619b0a727c74904c2338c813b97a2e602c 100644 --- a/src/connector/python/windows/python2/taos/cursor.py +++ b/src/connector/python/windows/python2/taos/cursor.py @@ -27,7 +27,7 @@ class TDengineCursor(object): """ def __init__(self, connection=None): - self._description = None + self._description = [] self._rowcount = -1 self._connection = None self._result = None @@ -193,7 +193,7 @@ class TDengineCursor(object): def _reset_result(self): """Reset the result to unused version. """ - self._description = None + self._description = [] self._rowcount = -1 if self._result is not None: CTaosInterface.freeResult(self._result) diff --git a/src/connector/python/windows/python3/setup.py b/src/connector/python/windows/python3/setup.py index c09644d3301b3a488b9bfdb7b60ffbaf6dba320e..ffed304c855fda28287735d0daab27e17b0e976e 100644 --- a/src/connector/python/windows/python3/setup.py +++ b/src/connector/python/windows/python3/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.2", + version="2.0.3", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/windows/python3/taos/__init__.py b/src/connector/python/windows/python3/taos/__init__.py index 2fec471a1adb29f08cd0d6539e8f9682bf6bc768..c6dd929a6a5110300ecd2e1042d48a5ad6a4bf46 100644 --- a/src/connector/python/windows/python3/taos/__init__.py +++ b/src/connector/python/windows/python3/taos/__init__.py @@ -3,7 +3,7 @@ from .connection import TDengineConnection from .cursor import TDengineCursor # Globals -apilevel = '2.0' +apilevel = '2.0.3' threadsafety = 0 paramstyle = 'pyformat' diff --git a/src/connector/python/windows/python3/taos/cinterface.py b/src/connector/python/windows/python3/taos/cinterface.py index fb1b65fc15f2f1c0f07745bb2aecf7b928a7c555..42b820ca80feda4a269e5e80f288bd1f5e87adcd 100644 --- a/src/connector/python/windows/python3/taos/cinterface.py +++ b/src/connector/python/windows/python3/taos/cinterface.py @@ -81,6 +81,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) if num_of_rows > 0: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] else: @@ -108,6 +109,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ + assert(nbytes is not None) res=[] if num_of_rows > 0: for i in range(abs(num_of_rows)): diff --git a/src/connector/python/windows/python3/taos/cursor.py b/src/connector/python/windows/python3/taos/cursor.py index b813bba35756065b2082d39391de3367cf9865fb..db66b99d3bfe5935a3e5b04c3692453092bcf24e 100644 --- a/src/connector/python/windows/python3/taos/cursor.py +++ b/src/connector/python/windows/python3/taos/cursor.py @@ -28,7 +28,7 @@ class TDengineCursor(object): """ def __init__(self, connection=None): - self._description = None + self._description = [] self._rowcount = -1 self._connection = None self._result = None @@ -194,7 +194,7 @@ class TDengineCursor(object): def _reset_result(self): """Reset the result to unused version. """ - self._description = None + self._description = [] self._rowcount = -1 if self._result is not None: CTaosInterface.freeResult(self._result) diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 0c07149e8e0b20e91123d9491ab25acfff75f5d4..bcce7c50a81032b330e878adb21bc6dc017598c3 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -1372,8 +1372,12 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat } if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - pResultRow->key = malloc(varDataTLen(pData)); - varDataCopy(pResultRow->key, pData); + if (pResultRow->key == NULL) { + pResultRow->key = malloc(varDataTLen(pData)); + varDataCopy(pResultRow->key, pData); + } else { + assert(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0); + } } else { pResultRow->win.skey = v; pResultRow->win.ekey = v; diff --git a/src/query/src/qParserImpl.c b/src/query/src/qParserImpl.c index 5cd9d3c77a5211fa1c0058978799447f38867180..7d71d9f7f15ad88d0bc1565047ae7686320d2832 100644 --- a/src/query/src/qParserImpl.c +++ b/src/query/src/qParserImpl.c @@ -405,14 +405,29 @@ void tSQLSetColumnType(TAOS_FIELD *pField, SStrToken *type) { if (type->type == 0) { pField->bytes = 0; } else { - pField->bytes = (int16_t)(-(int32_t)type->type * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); + int32_t bytes = -(int32_t)(type->type); + if (bytes > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { + // we have to postpone reporting the error because it cannot be done here + // as pField->bytes is int16_t, use 'TSDB_MAX_NCHAR_LEN + 1' to avoid overflow + bytes = TSDB_MAX_NCHAR_LEN + 1; + } else { + bytes = bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE; + } + pField->bytes = (int16_t)bytes; } } else if (i == TSDB_DATA_TYPE_BINARY) { /* for binary, the TOKENTYPE is the length of binary */ if (type->type == 0) { pField->bytes = 0; } else { - pField->bytes = (int16_t) (-(int32_t) type->type + VARSTR_HEADER_SIZE); + int32_t bytes = -(int32_t)(type->type); + if (bytes > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) { + // refer comment for NCHAR above + bytes = TSDB_MAX_BINARY_LEN + 1; + } else { + bytes += VARSTR_HEADER_SIZE; + } + pField->bytes = (int16_t)bytes; } } break; diff --git a/src/tsdb/src/tsdbMemTable.c b/src/tsdb/src/tsdbMemTable.c index 4c51608b5df6a151fed04defe8fc41c047e3e76e..999e2deb413eb13cc7119ee9042a260366c5f9a3 100644 --- a/src/tsdb/src/tsdbMemTable.c +++ b/src/tsdb/src/tsdbMemTable.c @@ -786,9 +786,9 @@ static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pT if (tsdbGetTableSchemaImpl(pTable, false, false, pBlock->sversion) == NULL) { tsdbError("vgId:%d invalid submit schema version %d to table %s tid %d from client", REPO_ID(pRepo), pBlock->sversion, TABLE_CHAR_NAME(pTable), TABLE_TID(pTable)); + terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; + return -1; } - terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; - return -1; } return 0; diff --git a/src/util/src/tconfig.c b/src/util/src/tconfig.c index e89dea5a244acb5823c49d4b7c9aefb4c254db4c..173de294cf333e20b9649a5634905421786a1b30 100644 --- a/src/util/src/tconfig.c +++ b/src/util/src/tconfig.c @@ -19,9 +19,7 @@ #include "taoserror.h" #include "tconfig.h" #include "tglobal.h" -#include "tkey.h" #include "tulog.h" -#include "tsocket.h" #include "tsystem.h" #include "tutil.h" diff --git a/src/util/src/tref.c b/src/util/src/tref.c index 4c1a87c96070534e25149357b766a8539e362680..1f83abcb847147da1d9ad0d17d26081176df0c93 100644 --- a/src/util/src/tref.c +++ b/src/util/src/tref.c @@ -329,7 +329,7 @@ void *taosIterateRef(int rsetId, int64_t rid) { pNode->count++; // acquire it newP = pNode->p; taosUnlockList(pSet->lockedBy+hash); - uTrace("rsetId:%d p:%p rid:%" PRId64 " is returned", rsetId, newP, rid); + uTrace("rsetId:%d p:%p rid:%" PRId64 " is returned", rsetId, newP, rid); } else { uTrace("rsetId:%d the list is over", rsetId); } @@ -423,24 +423,25 @@ static int taosDecRefCount(int rsetId, int64_t rid, int remove) { if (pNode->next) { pNode->next->prev = pNode->prev; } - - (*pSet->fp)(pNode->p); - - uTrace("rsetId:%d p:%p rid:%" PRId64 " is removed, count:%d, free mem: %p", rsetId, pNode->p, rid, pSet->count, pNode); - free(pNode); released = 1; } else { - uTrace("rsetId:%d p:%p rid:%" PRId64 " is released, count:%d", rsetId, pNode->p, rid, pNode->count); + uTrace("rsetId:%d p:%p rid:%" PRId64 " is released", rsetId, pNode->p, rid); } } else { - uTrace("rsetId:%d rid:%" PRId64 " is not there, failed to release/remove", rsetId, rid); + uTrace("rsetId:%d rid:%" PRId64 " is not there, failed to release/remove", rsetId, rid); terrno = TSDB_CODE_REF_NOT_EXIST; code = -1; } taosUnlockList(pSet->lockedBy+hash); - if (released) taosDecRsetCount(pSet); + if (released) { + uTrace("rsetId:%d p:%p rid:%" PRId64 " is removed, count:%d, free mem: %p", rsetId, pNode->p, rid, pSet->count, pNode); + (*pSet->fp)(pNode->p); + free(pNode); + + taosDecRsetCount(pSet); + } return code; } diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 5ef79cfbf01fb49ebbfd4603b8a9163b3ae9bc32..ed6d29505f04df25f48ffe1692d2914816001b75 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -275,41 +275,40 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { vDebug("vgId:%d, QInfo:%p, dnode continues to exec query", pVnode->vgId, *qhandle); + // In the retrieve blocking model, only 50% CPU will be used in query processing + if (tsHalfCoresForQuery) { + qTableQuery(*qhandle); // do execute query + qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, false); + } else { + bool freehandle = false; + bool buildRes = qTableQuery(*qhandle); // do execute query -#if _NON_BLOCKING_RETRIEVE - bool freehandle = false; - bool buildRes = qTableQuery(*qhandle); // do execute query - - // build query rsp, the retrieve request has reached here already - if (buildRes) { - // update the connection info according to the retrieve connection - pRead->rpcHandle = qGetResultRetrieveMsg(*qhandle); - assert(pRead->rpcHandle != NULL); - - vDebug("vgId:%d, QInfo:%p, start to build retrieval rsp after query paused, %p", pVnode->vgId, *qhandle, - pRead->rpcHandle); + // build query rsp, the retrieve request has reached here already + if (buildRes) { + // update the connection info according to the retrieve connection + pRead->rpcHandle = qGetResultRetrieveMsg(*qhandle); + assert(pRead->rpcHandle != NULL); - // set the real rsp error code - pRead->code = vnodeDumpQueryResult(&pRead->rspRet, pVnode, qhandle, &freehandle, pRead->rpcHandle); + vDebug("vgId:%d, QInfo:%p, start to build retrieval rsp after query paused, %p", pVnode->vgId, *qhandle, + pRead->rpcHandle); - // NOTE: set return code to be TSDB_CODE_QRY_HAS_RSP to notify dnode to return msg to client - code = TSDB_CODE_QRY_HAS_RSP; - } else { - void* h1 = qGetResultRetrieveMsg(*qhandle); - assert(h1 == NULL); + // set the real rsp error code + pRead->code = vnodeDumpQueryResult(&pRead->rspRet, pVnode, qhandle, &freehandle, pRead->rpcHandle); - freehandle = qQueryCompleted(*qhandle); - } + // NOTE: set return code to be TSDB_CODE_QRY_HAS_RSP to notify dnode to return msg to client + code = TSDB_CODE_QRY_HAS_RSP; + } else { + void *h1 = qGetResultRetrieveMsg(*qhandle); + assert(h1 == NULL); + freehandle = qQueryCompleted(*qhandle); + } - // NOTE: if the qhandle is not put into vread queue or query is completed, free the qhandle. - // If the building of result is not required, simply free it. Otherwise, mandatorily free the qhandle - if (freehandle || (!buildRes)) { - qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle); + // NOTE: if the qhandle is not put into vread queue or query is completed, free the qhandle. + // If the building of result is not required, simply free it. Otherwise, mandatorily free the qhandle + if (freehandle || (!buildRes)) { + qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle); + } } -#else - qTableQuery(*qhandle); // do execute query - qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, false); -#endif } return code; @@ -375,14 +374,16 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { freeHandle = true; } else { // result is not ready, return immediately assert(buildRes == true); -#if _NON_BLOCKING_RETRIEVE - if (!buildRes) { - assert(pRead->rpcHandle != NULL); - qReleaseQInfo(pVnode->qMgmt, (void **)&handle, false); - return TSDB_CODE_QRY_NOT_READY; + // Only effects in the non-blocking model + if (!tsHalfCoresForQuery) { + if (!buildRes) { + assert(pRead->rpcHandle != NULL); + + qReleaseQInfo(pVnode->qMgmt, (void **)&handle, false); + return TSDB_CODE_QRY_NOT_READY; + } } -#endif // ahandle is the sqlObj pointer code = vnodeDumpQueryResult(pRet, pVnode, handle, &freeHandle, pRead->rpcHandle); diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 042fd826e8c81653d719b9b444df1bd8ee5af3cb..448a0413e00643304410b7c44e462b70303f9f5f 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -159,7 +159,8 @@ python3 ./test.py -f query/bug1471.py python3 ./test.py -f query/bug1874.py python3 ./test.py -f query/bug1875.py python3 ./test.py -f query/bug1876.py -python3 ./test.py -f query/bug2218.py +python3 ./test.py -f query/bug2218.py +python3 ./test.py -f query/sliding.py #stream python3 ./test.py -f stream/metric_1.py diff --git a/tests/pytest/query/queryInterval.py b/tests/pytest/query/queryInterval.py index 98b8c9fbef819caebe34fce96bec66da99176131..871c076c0813f0ccd340d33bff992401e522df4a 100644 --- a/tests/pytest/query/queryInterval.py +++ b/tests/pytest/query/queryInterval.py @@ -16,6 +16,7 @@ import taos from util.log import tdLog from util.cases import tdCases from util.sql import tdSql +from util.dnodes import tdDnodes class TDTestCase: @@ -72,6 +73,19 @@ class TDTestCase: tdSql.checkData(6, 0, "2020-09-16 00:00:00") tdSql.checkData(6, 1, 222.0) + # test case for https://jira.taosdata.com:18080/browse/TD-2298 + tdSql.execute("create database test keep 36500") + tdSql.execute("use test") + tdSql.execute("create table t (ts timestamp, voltage int)") + for i in range(10000): + tdSql.execute("insert into t values(%d, 0)" % (1000000 + i * 6000)) + + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select last(*) from t interval(1s)") + tdSql.checkRows(10000) + + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__)