diff --git a/Jenkinsfile b/Jenkinsfile index 491e70742825fb9d655ca76321085a133c4aea63..d8803cd1a993250055c9aa3f2e0b457ab4d0f170 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -476,6 +476,9 @@ pipeline { ''' sh ''' + cd ${WKC}/src/connector/nodejs + npm install + npm run test cd ${WKC}/tests/examples/nodejs npm install td2.0-connector > /dev/null 2>&1 node nodejsChecker.js host=localhost @@ -486,6 +489,15 @@ pipeline { ''' catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { sh ''' + cd ${WKC}/src/connector/C# + dotnet test + dotnet run --project src/test/Cases/Cases.csproj + + cd ${WKC}/tests/examples/C# + dotnet run --project C#checker/C#checker.csproj + dotnet run --project TDengineTest/TDengineTest.csproj + dotnet run --project schemaless/schemaless.csproj + cd ${WKC}/tests/examples/C#/taosdemo dotnet build -c Release tree | true diff --git a/documentation20/cn/02.getting-started/02.taosdemo/docs.md b/documentation20/cn/02.getting-started/02.taosdemo/docs.md index 98e9ef79eb2a179109d4f7fef51573a9c9a4807d..c01c2efb514c22883bbc9a8bd07a974ba37d3019 100644 --- a/documentation20/cn/02.getting-started/02.taosdemo/docs.md +++ b/documentation20/cn/02.getting-started/02.taosdemo/docs.md @@ -364,7 +364,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 } ``` 以下为 JSON 文件中和查询相关的特有参数含义: - +``` "query_times": 每种查询类型的查询次数 "query_mode": 查询数据接口,"taosc":调用TDengine的c接口;“resetful”:使用restfule接口。可选项。缺省是“taosc”。 "specified_table_query": { 指定表的查询 @@ -379,7 +379,7 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 "threads": 并发执行sqls的线程数,可选项,缺省是1。每个线程负责一部分子表,执行所有的sqls。 "sql": "select count(*) from xxxx"。查询超级表内所有子表的查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。 "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 - +``` 以下为一个典型订阅 JSON 示例文件内容: ``` @@ -422,13 +422,13 @@ taosdemo 不仅仅可以进行数据写入,也可以执行查询和订阅功 } ``` 以下为订阅功能相关的特有参数含义: - +``` "interval": 执行订阅的间隔,单位是秒。可选项,缺省是0。 "restart": 订阅重启。"yes":如果订阅已经存在,重新开始,"no": 继续之前的订阅。(请注意执行用户需要对 dataDir 目录有读写权限) "keepProgress": 保留订阅信息进度。yes表示保留订阅信息,no表示不保留。该值为yes,restart为no时,才能继续之前的订阅。 "resubAfterConsume": 配合 keepProgress 使用,在订阅消费了相应次数后调用 unsubscribe 取消订阅并再次订阅。 "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 - +``` 结语 -- TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台。TDengine 由于数据库内核中创新的数据存储和查询引擎设计,展现出远超同类产品的高效性能。并且由于支持 SQL 语法和多种编程语言的连接器(目前支持 Java, Python, Go, C#, NodeJS, Rust 等),易用性极强,学习成本为零。为了便于运维需求,我们还提供数据迁移和监控功能等相关生态工具软件。 @@ -440,6 +440,7 @@ TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维 附录 - 完整 taosdemo 参数介绍 -- taosdemo支持两种配置参数的模式,一种是命令行参数,一种是使用 JSON 格式的配置文件。 + 一、命令行参数 -f:指定taosdemo所需参数的meta文件。当使用该参数时,其他所有命令行参数都失效。可选项,缺省是NULL。目前仅支持不含 BOM(byte-order mark)的标准 UTF-8 编码文件。 @@ -508,8 +509,9 @@ taosdemo支持两种配置参数的模式,一种是命令行参数,一种是 二、JSON 格式的配置文件中所有参数说明 taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个taosdemo实例不能同时支持三种功能,一个 taosdemo 实例只能支持其中的一种功能,通过配置文件来指定进行哪种功能的测试。 -1、插入功能测试的 JSON 配置文件 +1、插入功能测试的 JSON 配置文件 +``` { "filetype": "insert", "cfgdir": "/etc/taos", @@ -571,6 +573,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta }] }] } +``` "filetype": 本taosdemo实例进行哪种功能测试。"insert"表示数据插入功能。必选项。 @@ -600,7 +603,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta "databases": [{ -"dbinfo": { ​ "name": 数据库名称。必选项。 +"dbinfo": {"name": 数据库名称。必选项。 "drop": 如果数据库已经存在,”yes“:删除后重建;”no“:不删除,直接使用。可选项,缺省是”no“。drop = yes 会使其他子表创建相关条目无效。 @@ -695,8 +698,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta "count":该类型的连续列个数,可选项,缺省是1。 }] -2、查询功能测试的 JSON 配置文件 +2、查询功能测试的 JSON 配置文件 +``` { "filetype": "query", "cfgdir": "/etc/taos", @@ -734,7 +738,7 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta ] } } -​ +``` "filetype": 本taosdemo实例进行哪种功能测试。"query"表示数据查询功能。必选项。 @@ -784,8 +788,9 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 查询结果显示:如果查询线程结束一次查询距开始执行时间超过30秒打印一次查询次数、用时和QPS。所有查询结束时,汇总打印总的查询次数和QPS。 -3、订阅功能测试的 JSON 配置文件 +3、订阅功能测试的 JSON 配置文件 +``` { "filetype":"subscribe", "cfgdir": "/etc/taos", @@ -822,7 +827,8 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta "result": "./subscribe_res1.txt" }] } - } +} +``` "filetype": 本taosdemo实例进行哪种功能测试。"subscribe"表示数据查询功能。必选项。** @@ -878,4 +884,4 @@ taosdemo支持3种功能的测试,包括插入、查询、订阅。但一个ta "sql": " select count(*) from xxxx "。查询语句,其中表名必须写成 “xxxx”,实例会自动替换成子表名。 -​ "result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 +"result": 查询结果写入的文件名。可选项,缺省是空,表示查询结果不写入文件。 注意:每条sql语句后的保存结果的文件不能重名,且生成结果文件时,文件名会附加线程号。 diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 9203c2cc9e24a8aaa424bb9e2ee64bd23310cc99..7806de6093b422b40938b701d85c1512b32945ec 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -208,6 +208,8 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine 返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。 + **提示:** 同一进程可以根据不同的host/port 连接多个taosd 集群 + - `char *taos_get_server_info(TAOS *taos)` 获取服务端版本信息。 diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index 8ce6732efec4da35683913e8f73082f98f88f89d..7b7b2262d470f5226eef780a9971894a65663579 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -223,7 +223,6 @@ taosd -C | 105 | compressColData | | **S** | bytes | 客户端与服务器之间进行消息通讯过程中,对服务器端查询结果进行列压缩的阈值。 | 0: 对所有查询结果均进行压缩 >0: 查询结果中任意列大小超过该值的消息才进行压缩 -1: 不压缩 | -1 | 2.3.0.0 版本新增。 | | 106 | tsdbMetaCompactRatio | | **C** | | tsdb meta文件中冗余数据超过多少阈值,开启meta文件的压缩功能 | 0:不开启,[1-100]:冗余数据比例 | 0 | | | 107 | rpcForceTcp | | **SC**| | 强制使用TCP传输 | 0: 不开启 1: 开启 | 0 | 在网络比较差的环境中,建议开启。2.0版本新增。| -| 107 | rpcForceTcp | | **SC** | | 强制使用TCP传输。 | 0: 不开启 1: 开启 | 0 | 在网络比较差的环境中,建议开启。2.0 版本新增。 | **注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。(详细的端口情况请参见 [TDengine 2.0 端口说明](https://www.taosdata.com/cn/documentation/faq#port)) diff --git a/documentation20/en/02.getting-started/02.taosdemo/docs.md b/documentation20/en/02.getting-started/02.taosdemo/docs.md index 750983c85e8ebcd896587df98af83ce20b23ac28..c872d2971ef3cce250592df0534af5369c4682dd 100644 --- a/documentation20/en/02.getting-started/02.taosdemo/docs.md +++ b/documentation20/en/02.getting-started/02.taosdemo/docs.md @@ -374,7 +374,7 @@ The following is the content of a typical query JSON example file. } ``` The following parameters are specific to the query in the JSON file. - +``` "query_times": the number of queries per query type "query_mode": query data interface, "tosc": call TDengine's c interface; "resetful": use restfule interface. Options are available. Default is "taosc". "specified_table_query": { query for the specified table @@ -389,7 +389,7 @@ The following parameters are specific to the query in the JSON file. "threads": the number of threads to execute sqls concurrently, optional, default is 1. Each thread is responsible for a part of sub-tables and executes all sqls. "sql": "select count(*) from xxxx". Query statement for all sub-tables in the super table, where the table name must be written as "xxxx" and the instance will be replaced with the sub-table name automatically. "result": the name of the file to which the query result is written. Optional, the default is null, which means the query results are not written to a file. - +``` The following is a typical subscription JSON example file content. ``` @@ -432,13 +432,13 @@ The following is a typical subscription JSON example file content. } ``` The following are the meanings of the parameters specific to the subscription function. - +``` "interval": interval for executing subscriptions, in seconds. Optional, default is 0. "restart": subscription restart." yes": restart the subscription if it already exists, "no": continue the previous subscription. (Please note that the executing user needs to have read/write access to the dataDir directory) "keepProgress": keep the progress of the subscription information. yes means keep the subscription information, no means don't keep it. The value is yes and restart is no to continue the previous subscriptions. "resubAfterConsume": Used in conjunction with keepProgress to call unsubscribe after the subscription has been consumed the appropriate number of times and to subscribe again. "result": the name of the file to which the query result is written. Optional, default is null, means the query result will not be written to the file. Note: The file to save the result after each sql statement cannot be renamed, and the file name will be appended with the thread number when generating the result file. - +``` Conclusion -- TDengine is a big data platform designed and optimized for IoT, Telematics, Industrial Internet, DevOps, etc. TDengine shows a high performance that far exceeds similar products due to the innovative data storage and query engine design in the database kernel. And withSQL syntax support and connectors for multiple programming languages (currently Java, Python, Go, C#, NodeJS, Rust, etc. are supported), it is extremely easy to use and has zero learning cost. To facilitate the operation and maintenance needs, we also provide data migration and monitoring functions and other related ecological tools and software. diff --git a/documentation20/en/08.connector/docs.md b/documentation20/en/08.connector/docs.md index 2a67c65c16ea11873e65c87fb6d059ac82dfc9ec..b3b4dedabbbc55f554541710c4e0d8abd8e5c892 100644 --- a/documentation20/en/08.connector/docs.md +++ b/documentation20/en/08.connector/docs.md @@ -200,6 +200,8 @@ Create a database connection and initialize the connection context. The paramete * port: Port number A null return value indicates a failure. The application needs to save the returned parameters for subsequent API calls. +Note: The same process can connect to multiple taosd processes based on ip/port + - `char *taos_get_server_info(TAOS *taos)` diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index b1130e1b86eb1ed24b11f3aa3ca1c38f4d5fdf12..10cfe8bcc5053fa9fe44982268d9e8843d071ce6 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -115,8 +115,9 @@ typedef struct SParsedDataColInfo { int16_t numOfCols; int16_t numOfBound; uint16_t flen; // TODO: get from STSchema - uint16_t allNullLen; // TODO: get from STSchema + uint16_t allNullLen; // TODO: get from STSchema(base on SDataRow) uint16_t extendedVarLen; + uint16_t boundNullLen; // bound column len with all NULL value(without VarDataOffsetT/SColIdx part) int32_t * boundedColumns; // bound column idx according to schema SBoundColumn * cols; SBoundIdxInfo *colIdxInfo; @@ -132,7 +133,7 @@ typedef struct { typedef struct { uint8_t memRowType; // default is 0, that is SDataRow uint8_t compareStat; // 0 no need, 1 need compare - TDRowTLenT kvRowInitLen; + int32_t rowSize; SMemRowInfo *rowInfo; } SMemRowBuilder; @@ -150,8 +151,7 @@ typedef struct { int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec); -int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint32_t nCols, uint32_t nBoundCols, - int32_t allNullLen); +int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, SParsedDataColInfo *pColInfo); void destroyMemRowBuilder(SMemRowBuilder *pBuilder); /** @@ -533,16 +533,6 @@ static FORCE_INLINE int32_t getExtendedRowSize(STableDataBlocks *pBlock) { return pBlock->rowSize + TD_MEM_ROW_DATA_HEAD_SIZE + pBlock->boundColumnInfo.extendedVarLen; } -static FORCE_INLINE void checkAndConvertMemRow(SMemRow row, int32_t dataLen, int32_t kvLen) { - if (isDataRow(row)) { - if (kvLen < (dataLen * KVRatioConvert)) { - memRowSetConvert(row); - } - } else if (kvLen > dataLen) { - memRowSetConvert(row); - } -} - static FORCE_INLINE void initSMemRow(SMemRow row, uint8_t memRowType, STableDataBlocks *pBlock, int16_t nBoundCols) { memRowSetType(row, memRowType); if (isDataRowT(memRowType)) { @@ -642,8 +632,7 @@ static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE; static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE; static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pToken, SMemRow row, char *msg, char **str, - bool primaryKey, int16_t timePrec, int32_t toffset, int16_t colId, - int32_t *dataLen, int32_t *kvLen, uint8_t compareStat) { + bool primaryKey, int16_t timePrec, int32_t toffset, int16_t colId) { int64_t iv; int32_t ret; char * endptr = NULL; @@ -655,26 +644,22 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok switch (pSchema->type) { case TSDB_DATA_TYPE_BOOL: { // bool if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) { if (strncmp(pToken->z, "true", pToken->n) == 0) { - tscAppendMemRowColValEx(row, &TRUE_VALUE, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &TRUE_VALUE, true, colId, pSchema->type, toffset); } else if (strncmp(pToken->z, "false", pToken->n) == 0) { - tscAppendMemRowColValEx(row, &FALSE_VALUE, true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, &FALSE_VALUE, true, colId, pSchema->type, toffset); } else { return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z); } } else if (pToken->type == TK_INTEGER) { iv = strtoll(pToken->z, NULL, 10); - tscAppendMemRowColValEx(row, ((iv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset, - dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, ((iv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset); } else if (pToken->type == TK_FLOAT) { double dv = strtod(pToken->z, NULL); - tscAppendMemRowColValEx(row, ((dv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset, - dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, ((dv == 0) ? &FALSE_VALUE : &TRUE_VALUE), true, colId, pSchema->type, toffset); } else { return tscInvalidOperationMsg(msg, "invalid bool data", pToken->z); } @@ -684,8 +669,7 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok case TSDB_DATA_TYPE_TINYINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { @@ -695,15 +679,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } uint8_t tmpVal = (uint8_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_UTINYINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { @@ -713,15 +696,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } uint8_t tmpVal = (uint8_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_SMALLINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { @@ -731,15 +713,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } int16_t tmpVal = (int16_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_USMALLINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { @@ -749,15 +730,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } uint16_t tmpVal = (uint16_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_INT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { @@ -767,15 +747,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } int32_t tmpVal = (int32_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_UINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { @@ -785,15 +764,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } uint32_t tmpVal = (uint32_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_BIGINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true); if (ret != TSDB_CODE_SUCCESS) { @@ -802,14 +780,13 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok return tscInvalidOperationMsg(msg, "bigint data overflow", pToken->z); } - tscAppendMemRowColValEx(row, &iv, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &iv, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_UBIGINT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false); if (ret != TSDB_CODE_SUCCESS) { @@ -819,14 +796,13 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } uint64_t tmpVal = (uint64_t)iv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_FLOAT: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { double dv; if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) { @@ -839,14 +815,13 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok } float tmpVal = (float)dv; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_DOUBLE: if (isNullStr(pToken)) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { double dv; if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) { @@ -857,15 +832,14 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok return tscInvalidOperationMsg(msg, "illegal double data", pToken->z); } - tscAppendMemRowColValEx(row, &dv, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &dv, true, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_BINARY: // binary data cannot be null-terminated char string, otherwise the last char of the string is lost if (pToken->type == TK_NULL) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { // too long values will return invalid sql, not be truncated automatically if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { // todo refactor return tscInvalidOperationMsg(msg, "string data overflow", pToken->z); @@ -873,14 +847,13 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok // STR_WITH_SIZE_TO_VARSTR(payload, pToken->z, pToken->n); char *rowEnd = memRowEnd(row); STR_WITH_SIZE_TO_VARSTR(rowEnd, pToken->z, pToken->n); - tscAppendMemRowColValEx(row, rowEnd, false, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, rowEnd, false, colId, pSchema->type, toffset); } break; case TSDB_DATA_TYPE_NCHAR: if (pToken->type == TK_NULL) { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } else { // if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long' int32_t output = 0; @@ -892,7 +865,7 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok return tscInvalidOperationMsg(msg, buf, pToken->z); } varDataSetLen(rowEnd, output); - tscAppendMemRowColValEx(row, rowEnd, false, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, rowEnd, false, colId, pSchema->type, toffset); } break; @@ -901,17 +874,16 @@ static FORCE_INLINE int32_t tsParseOneColumnKV(SSchema *pSchema, SStrToken *pTok if (primaryKey) { // When building SKVRow primaryKey, we should not skip even with NULL value. int64_t tmpVal = 0; - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } else { - tscAppendMemRowColValEx(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset, dataLen, kvLen, - compareStat); + tdAppendMemRowColVal(row, getNullValue(pSchema->type), true, colId, pSchema->type, toffset); } } else { int64_t tmpVal; if (tsParseTime(pToken, &tmpVal, str, msg, timePrec) != TSDB_CODE_SUCCESS) { return tscInvalidOperationMsg(msg, "invalid timestamp", pToken->z); } - tscAppendMemRowColValEx(row, &tmpVal, true, colId, pSchema->type, toffset, dataLen, kvLen, compareStat); + tdAppendMemRowColVal(row, &tmpVal, true, colId, pSchema->type, toffset); } break; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 3c6c79ad40454a19eb373e7c2f3dce3e773e48db..05b8b031d99c2b0f4e54e9fc3392a20a9e1bcfcc 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -41,9 +41,8 @@ enum { static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t *numOfRows); static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDataColInfo *pColInfo, SSchema *pSchema, char *str, char **end); -int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint32_t nCols, uint32_t nBoundCols, - int32_t allNullLen) { - ASSERT(nRows >= 0 && nCols > 0 && (nBoundCols <= nCols)); +int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, SParsedDataColInfo *pColInfo) { + ASSERT(nRows >= 0 && pColInfo->numOfCols > 0 && (pColInfo->numOfBound <= pColInfo->numOfCols)); if (nRows > 0) { // already init(bind multiple rows by single column) if (pBuilder->compareStat == ROW_COMPARE_NEED && (pBuilder->rowInfo != NULL)) { @@ -51,41 +50,12 @@ int initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint3 } } - // default compareStat is ROW_COMPARE_NO_NEED - if (nBoundCols == 0) { // file input - pBuilder->memRowType = SMEM_ROW_DATA; - return TSDB_CODE_SUCCESS; + uint32_t dataLen = TD_MEM_ROW_DATA_HEAD_SIZE + pColInfo->allNullLen; + uint32_t kvLen = TD_MEM_ROW_KV_HEAD_SIZE + pColInfo->numOfBound * sizeof(SColIdx) + pColInfo->boundNullLen; + if (isUtilizeKVRow(kvLen, dataLen)) { + pBuilder->memRowType = SMEM_ROW_KV; } else { - float boundRatio = ((float)nBoundCols / (float)nCols); - - if (boundRatio < KVRatioKV) { - pBuilder->memRowType = SMEM_ROW_KV; - return TSDB_CODE_SUCCESS; - } else if (boundRatio > KVRatioData) { - pBuilder->memRowType = SMEM_ROW_DATA; - return TSDB_CODE_SUCCESS; - } - pBuilder->compareStat = ROW_COMPARE_NEED; - - if (boundRatio < KVRatioPredict) { - pBuilder->memRowType = SMEM_ROW_KV; - } else { - pBuilder->memRowType = SMEM_ROW_DATA; - } - } - - pBuilder->kvRowInitLen = TD_MEM_ROW_KV_HEAD_SIZE + nBoundCols * sizeof(SColIdx); - - if (nRows > 0) { - pBuilder->rowInfo = tcalloc(nRows, sizeof(SMemRowInfo)); - if (pBuilder->rowInfo == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - - for (int i = 0; i < nRows; ++i) { - (pBuilder->rowInfo + i)->dataLen = TD_MEM_ROW_DATA_HEAD_SIZE + allNullLen; - (pBuilder->rowInfo + i)->kvLen = pBuilder->kvRowInitLen; - } + pBuilder->memRowType = SMEM_ROW_DATA; } return TSDB_CODE_SUCCESS; @@ -468,8 +438,6 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i STableMeta * pTableMeta = pDataBlocks->pTableMeta; SSchema * schema = tscGetTableSchema(pTableMeta); SMemRowBuilder * pBuilder = &pDataBlocks->rowBuilder; - int32_t dataLen = spd->allNullLen + TD_MEM_ROW_DATA_HEAD_SIZE; - int32_t kvLen = pBuilder->kvRowInitLen; bool isParseBindParam = false; initSMemRow(row, pBuilder->memRowType, pDataBlocks, spd->numOfBound); @@ -546,8 +514,8 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i int16_t colId = -1; tscGetMemRowAppendInfo(schema, pBuilder->memRowType, spd, i, &toffset, &colId); - int32_t ret = tsParseOneColumnKV(pSchema, &sToken, row, pInsertParam->msg, str, isPrimaryKey, timePrec, toffset, - colId, &dataLen, &kvLen, pBuilder->compareStat); + int32_t ret = + tsParseOneColumnKV(pSchema, &sToken, row, pInsertParam->msg, str, isPrimaryKey, timePrec, toffset, colId); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -562,13 +530,8 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i } if (!isParseBindParam) { - // 2. check and set convert flag - if (pBuilder->compareStat == ROW_COMPARE_NEED) { - checkAndConvertMemRow(row, dataLen, kvLen); - } - - // 3. set the null value for the columns that do not assign values - if ((spd->numOfBound < spd->numOfCols) && isDataRow(row) && !isNeedConvertRow(row)) { + // set the null value for the columns that do not assign values + if ((spd->numOfBound < spd->numOfCols) && isDataRow(row)) { SDataRow dataRow = memRowDataBody(row); for (int32_t i = 0; i < spd->numOfCols; ++i) { if (spd->cols[i].valStat == VAL_STAT_NONE) { @@ -578,7 +541,7 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i } } - *len = getExtendedRowSize(pDataBlocks); + *len = pBuilder->rowSize; return TSDB_CODE_SUCCESS; } @@ -631,11 +594,11 @@ int32_t tsParseValues(char **str, STableDataBlocks *pDataBlock, int maxRows, SIn int32_t extendedRowSize = getExtendedRowSize(pDataBlock); - if (TSDB_CODE_SUCCESS != - (code = initMemRowBuilder(&pDataBlock->rowBuilder, 0, tinfo.numOfColumns, pDataBlock->boundColumnInfo.numOfBound, - pDataBlock->boundColumnInfo.allNullLen))) { + if (TSDB_CODE_SUCCESS != (code = initMemRowBuilder(&pDataBlock->rowBuilder, 0, &pDataBlock->boundColumnInfo))) { return code; } + pDataBlock->rowBuilder.rowSize = extendedRowSize; + while (1) { index = 0; sToken = tStrGetToken(*str, &index, false); @@ -714,6 +677,7 @@ void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32 pColInfo->boundedColumns[i] = i; } pColInfo->allNullLen += pColInfo->flen; + pColInfo->boundNullLen = pColInfo->allNullLen; // default set allNullLen pColInfo->extendedVarLen = (uint16_t)(nVar * sizeof(VarDataOffsetT)); } @@ -1254,6 +1218,7 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat int32_t nCols = pColInfo->numOfCols; pColInfo->numOfBound = 0; + pColInfo->boundNullLen = 0; memset(pColInfo->boundedColumns, 0, sizeof(int32_t) * nCols); for (int32_t i = 0; i < nCols; ++i) { pColInfo->cols[i].valStat = VAL_STAT_NONE; @@ -1311,6 +1276,17 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat pColInfo->cols[t].valStat = VAL_STAT_HAS; pColInfo->boundedColumns[pColInfo->numOfBound] = t; ++pColInfo->numOfBound; + switch (pSchema[t].type) { + case TSDB_DATA_TYPE_BINARY: + pColInfo->boundNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES); + break; + case TSDB_DATA_TYPE_NCHAR: + pColInfo->boundNullLen += (VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE); + break; + default: + pColInfo->boundNullLen += TYPE_BYTES[pSchema[t].type]; + break; + } findColumnIndex = true; if (isOrdered && (lastColIdx > t)) { isOrdered = false; @@ -1334,6 +1310,17 @@ static int32_t parseBoundColumns(SInsertStatementParam *pInsertParam, SParsedDat pColInfo->cols[t].valStat = VAL_STAT_HAS; pColInfo->boundedColumns[pColInfo->numOfBound] = t; ++pColInfo->numOfBound; + switch (pSchema[t].type) { + case TSDB_DATA_TYPE_BINARY: + pColInfo->boundNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES); + break; + case TSDB_DATA_TYPE_NCHAR: + pColInfo->boundNullLen += (VARSTR_HEADER_SIZE + TSDB_NCHAR_SIZE); + break; + default: + pColInfo->boundNullLen += TYPE_BYTES[pSchema[t].type]; + break; + } findColumnIndex = true; if (isOrdered && (lastColIdx > t)) { isOrdered = false; @@ -1784,13 +1771,18 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow goto _error; } - tscAllocateMemIfNeed(pTableDataBlock, getExtendedRowSize(pTableDataBlock), &maxRows); + int32_t extendedRowSize = getExtendedRowSize(pTableDataBlock); + tscAllocateMemIfNeed(pTableDataBlock, extendedRowSize, &maxRows); tokenBuf = calloc(1, TSDB_MAX_BYTES_PER_ROW); if (tokenBuf == NULL) { code = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } + // insert from .csv means full and ordered columns, thus use SDataRow all the time + ASSERT(SMEM_ROW_DATA == pTableDataBlock->rowBuilder.memRowType); + pTableDataBlock->rowBuilder.rowSize = extendedRowSize; + while ((readLen = tgetline(&line, &n, fp)) != -1) { if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) { line[--readLen] = 0; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 2f800339b792191685057a7e54077677156bbe01..1828cda348d0140cce35a648e3e86d05d61c7442 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -100,7 +100,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem, bool outerQuery); -static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); +static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql, bool joinQuery); static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema); @@ -472,7 +472,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { } createInfo->name.z[createInfo->name.n] = 0; - // funcname's naming rule is same to column + // funcname's naming rule is same to column if (validateColumnName(createInfo->name.z) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -5036,11 +5036,13 @@ int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) { static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, - int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, tSqlExpr** tsExpr) { + int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, + tSqlExpr** tsExpr, bool joinQuery) { const char* msg1 = "table query cannot use tags filter"; const char* msg2 = "illegal column name"; const char* msg4 = "too many join tables"; const char* msg5 = "not support ordinary column join"; + const char* msg6 = "illegal condition expression"; tSqlExpr* pLeft = (*pExpr)->pLeft; tSqlExpr* pRight = (*pExpr)->pRight; @@ -5157,7 +5159,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } else { rexpr = *pExpr; } - + ret = setNormalExprToCond(tsExpr, rexpr, parentOptr); if (type) { *type |= TSQL_EXPR_TS; @@ -5189,7 +5191,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql *pExpr = NULL; if (type) { *type |= TSQL_EXPR_JOIN; - } + } } else { // do nothing // ret = setExprToCond(pCmd, &pCondExpr->pTagCond, @@ -5202,7 +5204,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql handleNeOptr(&rexpr, *pExpr); *pExpr = rexpr; } - + if (type) { *type |= TSQL_EXPR_TAG; } @@ -5211,9 +5213,13 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql if (type) { *type |= TSQL_EXPR_COLUMN; } - - if (pRight->tokenId == TK_ID) { // other column cannot be served as the join column - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); + + if (pRight->tokenId == TK_ID) { + if (joinQuery) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); // other column cannot be served as the join column + } else { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); + } } tSqlExpr *rexpr = NULL; @@ -5231,7 +5237,8 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql } int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, - int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, tSqlExpr** tsExpr) { + int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, + tSqlExpr** tsExpr, bool joinQuery) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -5263,12 +5270,12 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr int32_t rightTbIdx = 0; if (!tSqlExprIsParentOfLeaf(*pExpr)) { - ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, type ? &leftType : NULL, &leftTbIdx, (*pExpr)->tokenId, &columnLeft, &tsLeft); + ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, type ? &leftType : NULL, &leftTbIdx, (*pExpr)->tokenId, &columnLeft, &tsLeft, joinQuery); if (ret != TSDB_CODE_SUCCESS) { goto err_ret; } - ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, type ? &rightType : NULL, &rightTbIdx, (*pExpr)->tokenId, &columnRight, &tsRight); + ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, pCondExpr, type ? &rightType : NULL, &rightTbIdx, (*pExpr)->tokenId, &columnRight, &tsRight, joinQuery); if (ret != TSDB_CODE_SUCCESS) { goto err_ret; } @@ -5323,7 +5330,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr goto err_ret; } - ret = handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, tbIdx, parentOptr, columnExpr, tsExpr); + ret = handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, tbIdx, parentOptr, columnExpr, tsExpr, joinQuery); if (ret) { goto err_ret; } @@ -5863,12 +5870,11 @@ _ret: -int32_t -validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { +int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql, bool joinQuery) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } - + const char* msg1 = "invalid expression"; // const char* msg2 = "invalid filter expression"; @@ -5892,7 +5898,7 @@ validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { } #endif - if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, etype, &tbIdx, (*pExpr)->tokenId, &condExpr.pColumnCond, &condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) { + if ((ret = getQueryCondExpr(&pSql->cmd, pQueryInfo, pExpr, &condExpr, etype, &tbIdx, (*pExpr)->tokenId, &condExpr.pColumnCond, &condExpr.pTimewindow, joinQuery)) != TSDB_CODE_SUCCESS) { goto PARSE_WHERE_EXIT; } @@ -8742,7 +8748,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { if (tscValidateName(pName, true, &dbIncluded1) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - + SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); @@ -8759,7 +8765,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { char buf[TSDB_TABLE_FNAME_LEN]; SStrToken sTblToken; sTblToken.z = buf; - + int32_t code = validateTableName(srcToken.z, srcToken.n, &sTblToken, &dbIncluded2); if (code != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -8779,8 +8785,10 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return TSDB_CODE_TSC_INVALID_OPERATION; } + int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); + if (pSqlNode->pWhere != NULL) { // query condition in stream computing - if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -9721,11 +9729,13 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); + int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); + // parse the group by clause in the first place if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - + if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, false, timeWindowQuery, true) != TSDB_CODE_SUCCESS) { @@ -9757,7 +9767,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf SExprInfo* pExpr = tscExprGet(pQueryInfo, i); int32_t f = pExpr->base.functionId; - if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE || + if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE || f == TSDB_FUNC_RATE || f == TSDB_FUNC_DIFF) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); } @@ -9766,7 +9776,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf // validate the query filter condition info if (pSqlNode->pWhere != NULL) { - if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } } else { @@ -9811,7 +9821,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf } // parse the having clause in the first place - int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -9863,6 +9872,8 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); + int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); + // parse the group by clause in the first place if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -9870,7 +9881,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf pQueryInfo->onlyHasTagCond = true; // set where info if (pSqlNode->pWhere != NULL) { - if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql, joinQuery) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -9881,7 +9892,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf } } - int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); int32_t timeWindowQuery = (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); @@ -9891,7 +9901,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf } if (isSTable && tscQueryTags(pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) { - return TSDB_CODE_TSC_INVALID_OPERATION; + return TSDB_CODE_TSC_INVALID_OPERATION; } // parse the window_state diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 527185468f4032e50475f7f040642a33c5037ac6..e2263f696a885e885091e86c6b1210bc817996c2 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -2066,18 +2066,11 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SI } } else { for (int32_t i = 0; i < numOfRows; ++i) { - char* payload = (blkKeyTuple + i)->payloadAddr; - if (isNeedConvertRow(payload)) { - convertSMemRow(pDataBlock, payload, pTableDataBlock); - TDRowTLenT rowTLen = memRowTLen(pDataBlock); - pDataBlock = POINTER_SHIFT(pDataBlock, rowTLen); - pBlock->dataLen += rowTLen; - } else { - TDRowTLenT rowTLen = memRowTLen(payload); - memcpy(pDataBlock, payload, rowTLen); - pDataBlock = POINTER_SHIFT(pDataBlock, rowTLen); - pBlock->dataLen += rowTLen; - } + char* payload = (blkKeyTuple + i)->payloadAddr; + TDRowTLenT rowTLen = memRowTLen(payload); + memcpy(pDataBlock, payload, rowTLen); + pDataBlock = POINTER_SHIFT(pDataBlock, rowTLen); + pBlock->dataLen += rowTLen; } } diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index c9359d821d1adb8571bf14cb8c413b41a99a9b42..cb001becd45271989586b0d45d4f91c36bbba5aa 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -614,22 +614,17 @@ typedef void *SMemRow; #define SMEM_ROW_DATA 0x0U // SDataRow #define SMEM_ROW_KV 0x01U // SKVRow -#define SMEM_ROW_CONVERT 0x80U // SMemRow convert flag -#define KVRatioKV (0.2f) // all bool -#define KVRatioPredict (0.4f) -#define KVRatioData (0.75f) // all bigint #define KVRatioConvert (0.9f) #define memRowType(r) ((*(uint8_t *)(r)) & 0x01) #define memRowSetType(r, t) ((*(uint8_t *)(r)) = (t)) // set the total byte in case of dirty memory -#define memRowSetConvert(r) ((*(uint8_t *)(r)) = (((*(uint8_t *)(r)) & 0x7F) | SMEM_ROW_CONVERT)) // highest bit #define isDataRowT(t) (SMEM_ROW_DATA == (((uint8_t)(t)) & 0x01)) #define isDataRow(r) (SMEM_ROW_DATA == memRowType(r)) #define isKvRowT(t) (SMEM_ROW_KV == (((uint8_t)(t)) & 0x01)) #define isKvRow(r) (SMEM_ROW_KV == memRowType(r)) -#define isNeedConvertRow(r) (((*(uint8_t *)(r)) & 0x80) == SMEM_ROW_CONVERT) +#define isUtilizeKVRow(k, d) ((k) < ((d)*KVRatioConvert)) #define memRowDataBody(r) POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE) // section after flag #define memRowKvBody(r) \ diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 49ca1e31c5f4fc21beeed169b431f21e8985a642..cde5eab48783351d4bd8c00be9008d52b5bf6561 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -42,6 +42,7 @@ extern int8_t tsArbOnline; extern int64_t tsArbOnlineTimestamp; extern int32_t tsDnodeId; extern int64_t tsDnodeStartTime; +extern int8_t tsDnodeNopLoop; // common extern int tsRpcTimer; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index b4bc38d53e517da33a7e71fe6b6b189c3d64d613..8627a3153cdac2b06cd3cf15dddefad32c39c58d 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -47,6 +47,7 @@ int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME; char tsEmail[TSDB_FQDN_LEN] = {0}; int32_t tsDnodeId = 0; int64_t tsDnodeStartTime = 0; +int8_t tsDnodeNopLoop = 0; // common int32_t tsRpcTimer = 300; @@ -622,6 +623,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + cfg.option = "dnodeNopLoop"; + cfg.ptr = &tsDnodeNopLoop; + cfg.valType = TAOS_CFG_VTYPE_INT8; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; + cfg.minValue = 0; + cfg.maxValue = 1; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + cfg.option = "balance"; cfg.ptr = &tsEnableBalance; cfg.valType = TAOS_CFG_VTYPE_INT8; diff --git a/src/connector/C#/src/test/Cases/Utils.cs b/src/connector/C#/src/test/Cases/Utils.cs index 26414c91f9e6b65f58b0405786ced54fa4b61bcd..1c2ab137930384c0a85ae2103ff6be0893d7733b 100644 --- a/src/connector/C#/src/test/Cases/Utils.cs +++ b/src/connector/C#/src/test/Cases/Utils.cs @@ -3,6 +3,7 @@ using TDengineDriver; using System.Runtime.InteropServices; using System.Text; using System.Collections.Generic; + namespace Test.UtilsTools { public class UtilsTools @@ -163,4 +164,4 @@ namespace Test.UtilsTools System.Environment.Exit(0); } } -} \ No newline at end of file +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatementWrapper.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatementWrapper.java deleted file mode 100644 index 0b46226d1113b82d9333204427eaad074d3572cb..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatementWrapper.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.taosdata.jdbc; - -import java.sql.*; - -public class AbstractStatementWrapper extends AbstractStatement{ - protected Statement statement; - - public AbstractStatementWrapper(Statement statement) { - this.statement = statement; - } - - @Override - public ResultSet executeQuery(String sql) throws SQLException { - return statement.executeQuery(sql); - } - - @Override - public int executeUpdate(String sql) throws SQLException { - return statement.executeUpdate(sql); - } - - @Override - public void close() throws SQLException { - statement.close(); - } - - @Override - public boolean execute(String sql) throws SQLException { - return statement.execute(sql); - } - - @Override - public ResultSet getResultSet() throws SQLException { - return statement.getResultSet(); - } - - @Override - public int getUpdateCount() throws SQLException { - return statement.getUpdateCount(); - } - - @Override - public Connection getConnection() throws SQLException { - return statement.getConnection(); - } - - @Override - public boolean isClosed() throws SQLException { - return statement.isClosed(); - } -} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessStatement.java deleted file mode 100644 index d1184abc2722d81e8688a024d08e26200d104ce8..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessStatement.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.taosdata.jdbc; - -import com.taosdata.jdbc.enums.SchemalessProtocolType; -import com.taosdata.jdbc.enums.SchemalessTimestampType; -import com.taosdata.jdbc.rs.RestfulConnection; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * this class is an extension of {@link Statement}. e.g.: - * Statement statement = conn.createStatement(); - * SchemalessStatement schemalessStatement = new SchemalessStatement(statement); - * schemalessStatement.execute(sql); - * schemalessStatement.insert(lines, SchemalessProtocolType, SchemalessTimestampType); - */ -public class SchemalessStatement extends AbstractStatementWrapper { - public SchemalessStatement(Statement statement) { - super(statement); - } - - /** - * batch insert schemaless lines - * - * @param lines schemaless lines - * @param protocolType schemaless type {@link SchemalessProtocolType} - * @param timestampType Time precision {@link SchemalessTimestampType} - * @throws SQLException execute insert exception - */ - public void insert(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException { - Connection connection = this.getConnection(); - if (connection instanceof TSDBConnection) { - TSDBConnection tsdbConnection = (TSDBConnection) connection; - tsdbConnection.getConnector().insertLines(lines, protocolType, timestampType); - } else if (connection instanceof RestfulConnection) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD, "restful connection is not supported currently"); - } else { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown connection:" + connection.getMetaData().getURL()); - } - } - - /** - * only one insert - * - * @param line schemaless line - * @param protocolType schemaless type {@link SchemalessProtocolType} - * @param timestampType Time precision {@link SchemalessTimestampType} - * @throws SQLException execute insert exception - */ - public void insert(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException { - insert(new String[]{line}, protocolType, timestampType); - } -} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessWriter.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessWriter.java new file mode 100644 index 0000000000000000000000000000000000000000..d8cb5795f05e0fad785fc0c4ffcdaea7be411be6 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/SchemalessWriter.java @@ -0,0 +1,67 @@ +package com.taosdata.jdbc; + +import com.taosdata.jdbc.enums.SchemalessProtocolType; +import com.taosdata.jdbc.enums.SchemalessTimestampType; +import com.taosdata.jdbc.rs.RestfulConnection; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; + +/** + * This class is for schemaless lines(line/telnet/json) write to tdengine. + * e.g.: + * SchemalessWriter writer = new SchemalessWriter(connection); + * writer.write(lines, SchemalessProtocolType, SchemalessTimestampType); + */ +public class SchemalessWriter { + protected Connection connection; + + public SchemalessWriter(Connection connection) { + this.connection = connection; + } + + /** + * batch schemaless lines write to db + * + * @param lines schemaless lines + * @param protocolType schemaless type {@link SchemalessProtocolType} + * @param timestampType Time precision {@link SchemalessTimestampType} + * @throws SQLException execute exception + */ + public void write(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException { + if (connection instanceof TSDBConnection) { + TSDBConnection tsdbConnection = (TSDBConnection) connection; + tsdbConnection.getConnector().insertLines(lines, protocolType, timestampType); + } else if (connection instanceof RestfulConnection) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD, "restful connection is not supported currently"); + } else { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown connection:" + connection.getMetaData().getURL()); + } + } + + /** + * only one line writes to db + * + * @param line schemaless line + * @param protocolType schemaless type {@link SchemalessProtocolType} + * @param timestampType Time precision {@link SchemalessTimestampType} + * @throws SQLException execute exception + */ + public void write(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException { + write(new String[]{line}, protocolType, timestampType); + } + + /** + * batch schemaless lines write to db with list + * + * @param lines schemaless list + * @param protocolType schemaless type {@link SchemalessProtocolType} + * @param timestampType Time precision {@link SchemalessTimestampType} + * @throws SQLException execute exception + */ + public void write(List lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException { + String[] strings = lines.toArray(new String[0]); + write(strings, protocolType, timestampType); + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SchemalessInsertTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SchemalessInsertTest.java index b24271615ccf50d459e41687a51ba37394cbce4d..a090dd10e3564d498ab807909f97aefb3b2f3466 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SchemalessInsertTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SchemalessInsertTest.java @@ -10,6 +10,8 @@ import org.junit.Before; import org.junit.Test; import java.sql.*; +import java.util.ArrayList; +import java.util.List; public class SchemalessInsertTest { private final String dbname = "test_schemaless_insert"; @@ -27,10 +29,8 @@ public class SchemalessInsertTest { "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000", "st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000"}; // when - try (Statement statement = conn.createStatement(); - SchemalessStatement schemalessStatement = new SchemalessStatement(statement)) { - schemalessStatement.insert(lines, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS); - } + SchemalessWriter writer = new SchemalessWriter(conn); + writer.write(lines, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS); // then Statement statement = conn.createStatement(); @@ -62,10 +62,9 @@ public class SchemalessInsertTest { }; // when - try (Statement statement = conn.createStatement(); - SchemalessStatement schemalessStatement = new SchemalessStatement(statement)) { - schemalessStatement.insert(lines, SchemalessProtocolType.TELNET, SchemalessTimestampType.NOT_CONFIGURED); - } + + SchemalessWriter writer = new SchemalessWriter(conn); + writer.write(lines, SchemalessProtocolType.TELNET, SchemalessTimestampType.NOT_CONFIGURED); // then Statement statement = conn.createStatement(); @@ -114,10 +113,8 @@ public class SchemalessInsertTest { "]"; // when - try (Statement statement = conn.createStatement(); - SchemalessStatement schemalessStatement = new SchemalessStatement(statement)) { - schemalessStatement.insert(json, SchemalessProtocolType.JSON, SchemalessTimestampType.NOT_CONFIGURED); - } + SchemalessWriter writer = new SchemalessWriter(conn); + writer.write(json, SchemalessProtocolType.JSON, SchemalessTimestampType.NOT_CONFIGURED); // then Statement statement = conn.createStatement(); @@ -135,6 +132,33 @@ public class SchemalessInsertTest { statement.close(); } + @Test + public void telnetListInsert() throws SQLException { + // given + List list = new ArrayList<>(); + list.add("stb0_0 1626006833 4 host=host0 interface=eth0"); + list.add("stb0_1 1626006833 4 host=host0 interface=eth0"); + list.add("stb0_2 1626006833 4 host=host0 interface=eth0 id=\"special_name\""); + // when + + SchemalessWriter writer = new SchemalessWriter(conn); + writer.write(list, SchemalessProtocolType.TELNET, SchemalessTimestampType.NOT_CONFIGURED); + + // then + Statement statement = conn.createStatement(); + ResultSet rs = statement.executeQuery("show tables"); + Assert.assertNotNull(rs); + ResultSetMetaData metaData = rs.getMetaData(); + Assert.assertTrue(metaData.getColumnCount() > 0); + int rowCnt = 0; + while (rs.next()) { + rowCnt++; + } + Assert.assertEquals(list.size(), rowCnt); + rs.close(); + statement.close(); + } + @Before public void before() { String host = "127.0.0.1"; diff --git a/src/connector/nodejs/test/testNanoseconds.js b/src/connector/nodejs/test/testNanoseconds.js index 85a7600b01f2c908f22e621488f22678083149ea..c3089aab3eaa4621b36297a70f2698dd08ed5988 100644 --- a/src/connector/nodejs/test/testNanoseconds.js +++ b/src/connector/nodejs/test/testNanoseconds.js @@ -3,7 +3,6 @@ var conn = taos.connect(); var c1 = conn.cursor(); let stime = new Date(); let interval = 1000; - function convertDateToTS(date) { let tsArr = date.toISOString().split("T") return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length - 1) + "\""; diff --git a/src/connector/nodejs/test/testUnsignedType.js b/src/connector/nodejs/test/testUnsignedType.js index 82413afebad0b75116fe3ea46e50716843d87c84..14b102972a898c582e0011698bfd7b3cd771bc42 100644 --- a/src/connector/nodejs/test/testUnsignedType.js +++ b/src/connector/nodejs/test/testUnsignedType.js @@ -1,14 +1,13 @@ const taos = require('../tdengine'); var conn = taos.connect({ host: "127.0.0.1", user: "root", password: "taosdata", config: "/etc/taos", port: 10 }); var c1 = conn.cursor(); -executeUpdate("create database nodedb;"); +executeUpdate("create database if not exists nodedb;"); executeUpdate("use nodedb;"); -executeUpdate("create table unsigntest(ts timestamp,ut tinyint unsigned,us smallint unsigned,ui int unsigned,ub bigint unsigned,bi bigint);"); +executeUpdate("create table if not exists unsigntest(ts timestamp,ut tinyint unsigned,us smallint unsigned,ui int unsigned,ub bigint unsigned,bi bigint);"); executeUpdate("insert into unsigntest values (now, 254,65534,4294967294,18446744073709551614,9223372036854775807);"); executeUpdate("insert into unsigntest values (now, 0,0,0,0,-9223372036854775807);"); executeQuery("select * from unsigntest;"); -executeUpdate("drop database nodedb;"); - +executeUpdate("drop database if exists nodedb;"); function executeUpdate(sql) { console.log(sql); diff --git a/src/dnode/src/dnodeSystem.c b/src/dnode/src/dnodeSystem.c index e4d1d102e0319706c723f2659b843791654b96a7..d41a2c6a8ae442f09b20c1dc55d06d5d5273cd88 100644 --- a/src/dnode/src/dnodeSystem.c +++ b/src/dnode/src/dnodeSystem.c @@ -19,6 +19,7 @@ #include "tconfig.h" #include "dnodeMain.h" +bool dnodeExit = false; static tsem_t exitSem; static void siguser1Handler(int32_t signum, void *sigInfo, void *context); static void siguser2Handler(int32_t signum, void *sigInfo, void *context); @@ -182,6 +183,8 @@ static void sigintHandler(int32_t signum, void *sigInfo, void *context) { syslog(LOG_INFO, "Shut down signal is %d", signum); syslog(LOG_INFO, "Shutting down TDengine service..."); + dnodeExit = true; + // inform main thread to exit tsem_post(&exitSem); #ifdef WINDOWS diff --git a/src/dnode/src/dnodeVnodes.c b/src/dnode/src/dnodeVnodes.c index 93d218581cfb7d1738fa5ba3f3afd8c8f0d70dd7..981c150f1c8a523ae78749560545dd985af73eac 100644 --- a/src/dnode/src/dnodeVnodes.c +++ b/src/dnode/src/dnodeVnodes.c @@ -30,6 +30,7 @@ typedef struct { int32_t * vnodeList; } SOpenVnodeThread; +extern bool dnodeExit; extern void * tsDnodeTmr; static void * tsStatusTimer = NULL; static uint32_t tsRebootTime = 0; @@ -222,6 +223,22 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) { if (clusterId[0] != '\0') { dnodeSetDropped(); dError("exit zombie dropped dnode"); + + // warning: only for k8s! + while (tsDnodeNopLoop) { + if (dnodeExit) { + dInfo("Break loop"); + return; + } + + dInfo("Nop loop"); +#ifdef WINDOWS + Sleep(100); +#else + usleep(100000); +#endif + } + exit(EXIT_FAILURE); } } diff --git a/tests/develop-test/1-insert/0-sql/batchInsert.py b/tests/develop-test/1-insert/0-sql/batchInsert.py new file mode 100644 index 0000000000000000000000000000000000000000..22b1b5250b844648541b90361ec36cbf4da6c94f --- /dev/null +++ b/tests/develop-test/1-insert/0-sql/batchInsert.py @@ -0,0 +1,234 @@ +################################################################### +# Copyright (c) 2016 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 sys +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def caseDescription(self): + ''' + case1: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp in ascending order + case2: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp in descending order + case3: [TS-854] normal table batch insert with binding same table, different number of columns and timestamp out of order + case4: [TS-854] normal table batch insert with binding same table, different number of columns and same timestamp + + case5: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp in ascending order + case6: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp in descending order + case7: [TS-854] normal table batch insert with binding different tables, different number of columns and timestamp out of order + case8: [TS-854] normal table batch insert with binding different tables, different number of columns and same timestamp + + case9: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp in ascending order + case10: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp in descending order + case11: [TS-854] sub table batch insert with binding same table, different number of columns and timestamp out of order + case12: [TS-854] sub table batch insert with binding same table, different number of columns and same timestamp + + case13: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp in ascending order + case14: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp in descending order + case15: [TS-854] sub table batch insert with binding different tables, different number of columns and timestamp out of order + case16: [TS-854] sub table batch insert with binding different tables, different number of columns and same timestamp + + case17: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp in ascending order + case18: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp in descending order + case19: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and timestamp out of order + case20: [TS-854] sub table batch insert with binding same table, different number of columns, different number of tags and same timestamp + + case21: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp in ascending order + case22: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp in descending order + case23: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and timestamp out of order + case24: [TS-854] sub table batch insert with binding different tables, different number of columns, different number of tags and same timestamp + ''' + return + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + self.ts = 1607817000000 + + def run(self): + tdSql.prepare() + + tdSql.execute("create table tb1(ts timestamp, c1 double, c2 double, c3 double, c4 double)") + + args = [(self.ts + 1000, self.ts + 3000, self.ts + 5000, self.ts + 7000), + (self.ts + 8000, self.ts + 6000, self.ts + 4000, self.ts + 2000), + (self.ts - 1000 , self.ts - 5000, self.ts - 3000, self.ts - 8000), + (self.ts, self.ts, self.ts, self.ts)] + + # case 1, 2, 3, 4 + tdLog.info("test case for case 1, 2, 3, 4") + sql = "insert into tb1(ts, c1) values(%d, 0.0) tb1(ts, c1) values(%d, 0.0) tb1(ts, c1) values(%d, 0.0) tb1(ts, c1, c2, c3, c4) values(%d, 0.0, 0.0, 0.0, 0.0)" + i = 1 + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + + if i == 4: + rows = rows + 1 + else: + rows = rows + 4 + + tdSql.query("select * from tb1") + tdSql.checkRows(rows) + i = i + 1 + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from tb1") + tdSql.checkRows(rows) + + # case 5, 6, 7, 8 + tdSql.execute("create table tb2(ts timestamp, c1 int, c2 int, c3 int, c4 int)") + tdSql.execute("create table tb3(ts timestamp, c1 double, c2 double, c3 double, c4 double)") + tdLog.info("test case for case 5, 6, 7, 8") + sql = "insert into tb2(ts, c1) values(%d, 0) tb2(ts, c1, c2, c3, c4) values(%d, 0, 0, 0, 0) tb3(ts, c2) values(%d, 0.0) tb3(ts, c1, c2, c3, c4) values(%d, 0.0, 0.0, 0.0, 0.0)" + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + tdSql.query("select * from tb2") + if i == 8: + rows = rows + 1 + else: + rows = rows + 2 + tdSql.query("select * from tb2") + tdSql.checkRows(rows) + tdSql.query("select * from tb3") + tdSql.checkRows(rows) + i = i + 1 + + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from tb2") + tdSql.checkRows(rows) + tdSql.query("select * from tb3") + tdSql.checkRows(rows) + + # case 9, 10, 11, 12 + tdSql.execute("create table stb(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 nchar(20))") + tdLog.info("test case for case 9, 10, 11, 12") + sql = "insert into t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1) using stb tags('tag1') values(%d, 0.0) t1(ts, c1, c2, c3, c4) using stb tags('tag1') values(%d, 0.0, 0.0, 0.0, 0.0)" + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + if i == 12: + rows = rows + 1 + else: + rows = rows + 4 + tdSql.query("select * from stb") + tdSql.checkRows(rows) + i = i + 1 + + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from stb") + tdSql.checkRows(rows) + + # case 13, 14, 15, 16 + tdSql.execute("create table stb2(ts timestamp, c1 int, c2 int, c3 int, c4 int) tags(t1 nchar(20))") + tdSql.execute("create table stb3(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 binary(20))") + tdLog.info("test case for case 13, 14, 15, 16") + sql = "insert into t2(ts, c1) using stb2 tags('tag2') values(%d, 0) t2(ts, c1, c2, c3, c4) using stb2 tags('tag2') values(%d, 0, 0, 0, 0) t3(ts, c2) using stb3 tags('tag3') values(%d, 0.0) t3(ts, c1, c2, c3, c4) using stb3 tags('tag3') values(%d, 0.0, 0.0, 0.0, 0.0)" + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + if i == 16: + rows = rows + 1 + else: + rows = rows + 2 + tdSql.query("select * from stb2") + tdSql.checkRows(rows) + tdSql.query("select * from stb3") + tdSql.checkRows(rows) + i = i + 1 + + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from stb2") + tdSql.checkRows(rows) + tdSql.query("select * from stb3") + tdSql.checkRows(rows) + + # case 17, 18, 19, 20 + tdSql.execute("drop table if exists stb") + tdSql.execute("create table stb(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 nchar(20), t2 int, t3 binary(20))") + tdLog.info("test case for case 17, 18, 19, 20") + sql = "insert into t1(ts, c1) using stb(t1) tags('tag1') values(%d, 0.0) t1(ts, c1) using stb(t2) tags(1) values(%d, 0.0) t1(ts, c1) using stb(t1, t2) tags('tag1', 1) values(%d, 0.0) t1(ts, c1, c2, c3, c4) using stb(t1, t2, t3) tags('tag1', 1, 'tag3') values(%d, 0.0, 0.0, 0.0, 0.0)" + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + if i == 20: + rows = rows + 1 + else: + rows = rows + 4 + tdSql.query("select * from stb") + tdSql.checkRows(rows) + i = i + 1 + + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from stb") + tdSql.checkRows(rows) + + # case 21, 22, 23, 24 + tdSql.execute("drop table if exists stb2") + tdSql.execute("drop table if exists stb3") + tdSql.execute("create table stb2(ts timestamp, c1 int, c2 int, c3 int, c4 int) tags(t1 nchar(20), t2 int)") + tdSql.execute("create table stb3(ts timestamp, c1 double, c2 double, c3 double, c4 double) tags(t1 binary(20), t2 double)") + tdLog.info("test case for case 21, 22, 23, 24") + sql = "insert into t2(ts, c1) using stb2(t1) tags('tag2') values(%d, 0) t2(ts, c1, c2, c3, c4) using stb2(t1, t2) tags('tag2', 1) values(%d, 0, 0, 0, 0) t3(ts, c2) using stb3(t1) tags('tag3') values(%d, 0.0) t3(ts, c1, c2, c3, c4) using stb3(t1, t2) tags('tag3', 0.0) values(%d, 0.0, 0.0, 0.0, 0.0)" + rows = 0 + for arg in args: + tdLog.info("test case for case %d" % i) + tdLog.info(sql % arg) + tdSql.execute(sql % arg) + if i == 24: + rows = rows + 1 + else: + rows = rows + 2 + tdSql.query("select * from stb2") + tdSql.checkRows(rows) + tdSql.query("select * from stb3") + tdSql.checkRows(rows) + i = i + 1 + + # restart taosd and check again + tdDnodes.stop(1) + tdDnodes.start(1) + tdSql.query("select * from stb2") + tdSql.checkRows(rows) + tdSql.query("select * from stb3") + tdSql.checkRows(rows) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/develop-test/fulltest.sh b/tests/develop-test/fulltest.sh index 5c3b225f3fa1e24a098bcfafb19981c58115c337..9ec1dd23ac27928950befc35bd49ba8b4e6270eb 100755 --- a/tests/develop-test/fulltest.sh +++ b/tests/develop-test/fulltest.sh @@ -1,2 +1,3 @@ python3 test.py -f 0-management/3-tag/json_tag.py python3 test.py -f 1-insert/0-sql/basic.py +python3 test.py -f 1-insert/0-sql/batchInsert.py \ No newline at end of file diff --git a/tests/examples/C#/C#checker/TDengineDriver.cs b/tests/examples/C#/C#checker/TDengineDriver.cs deleted file mode 100644 index 0f6477ff75a9b457069112c477746dd036c71251..0000000000000000000000000000000000000000 --- a/tests/examples/C#/C#checker/TDengineDriver.cs +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace TDengineDriver -{ - enum TDengineDataType - { - TSDB_DATA_TYPE_NULL = 0, // 1 bytes - TSDB_DATA_TYPE_BOOL = 1, // 1 bytes - TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes - TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes - TSDB_DATA_TYPE_INT = 4, // 4 bytes - TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes - TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes - TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes - TSDB_DATA_TYPE_BINARY = 8, // string - TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes - TSDB_DATA_TYPE_NCHAR = 10, // unicode string - TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte - TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes - TSDB_DATA_TYPE_UINT = 13, // 4 bytes - TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes - } - - enum TDengineInitOption - { - TSDB_OPTION_LOCALE = 0, - TSDB_OPTION_CHARSET = 1, - TSDB_OPTION_TIMEZONE = 2, - TDDB_OPTION_CONFIGDIR = 3, - TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 - } - - class TDengineMeta - { - public string name; - public short size; - public byte type; - public string TypeName() - { - switch ((TDengineDataType)type) - { - case TDengineDataType.TSDB_DATA_TYPE_BOOL: - return "BOOL"; - case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - return "TINYINT"; - case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - return "SMALLINT"; - case TDengineDataType.TSDB_DATA_TYPE_INT: - return "INT"; - case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - return "BIGINT"; - case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: - return "TINYINT UNSIGNED"; - case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: - return "SMALLINT UNSIGNED"; - case TDengineDataType.TSDB_DATA_TYPE_UINT: - return "INT UNSIGNED"; - case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: - return "BIGINT UNSIGNED"; - case TDengineDataType.TSDB_DATA_TYPE_FLOAT: - return "FLOAT"; - case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: - return "DOUBLE"; - case TDengineDataType.TSDB_DATA_TYPE_BINARY: - return "STRING"; - case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: - return "TIMESTAMP"; - case TDengineDataType.TSDB_DATA_TYPE_NCHAR: - return "NCHAR"; - default: - return "undefine"; - } - } - } - - class TDengine - { - public const int TSDB_CODE_SUCCESS = 0; - - [DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] - static extern public void Init(); - - [DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] - static extern public void Cleanup(); - - [DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] - static extern public void Options(int option, string value); - - [DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Connect(string ip, string user, string password, string db, short port); - - [DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_errstr(IntPtr res); - static public string Error(IntPtr res) - { - IntPtr errPtr = taos_errstr(res); - return Marshal.PtrToStringAnsi(errPtr); - } - - [DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] - static extern public int ErrorNo(IntPtr res); - - [DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Query(IntPtr conn, string sqlstr); - - [DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] - static extern public int AffectRows(IntPtr res); - - [DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] - static extern public int FieldCount(IntPtr res); - - [DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_fetch_fields(IntPtr res); - static public List FetchFields(IntPtr res) - { - const int fieldSize = 68; - - List metas = new List(); - if (res == IntPtr.Zero) - { - return metas; - } - - int fieldCount = FieldCount(res); - IntPtr fieldsPtr = taos_fetch_fields(res); - - for (int i = 0; i < fieldCount; ++i) - { - int offset = i * fieldSize; - - TDengineMeta meta = new TDengineMeta(); - meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); - meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); - meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); - metas.Add(meta); - } - - return metas; - } - - [DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FetchRows(IntPtr res); - - [DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FreeResult(IntPtr res); - - [DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] - static extern public int Close(IntPtr taos); - - //get precision in restultset - [DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)] - static extern public int ResultPrecision(IntPtr taos); - - //schemaless API - [DllImport("taos",SetLastError = true, EntryPoint = "taos_schemaless_insert", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr SchemalessInsert(IntPtr taos, string[] lines, int numLines, int protocol, int precision); - } -} diff --git a/tests/examples/C#/TDengineTest/TDengineTest.cs b/tests/examples/C#/TDengineTest/TDengineTest.cs index 89ef57bd41ac8f68ac2bc34e4ebe5ad90d213b17..9f84634ffb400e5d891a9fdeaeee0c013829f969 100644 --- a/tests/examples/C#/TDengineTest/TDengineTest.cs +++ b/tests/examples/C#/TDengineTest/TDengineTest.cs @@ -168,7 +168,7 @@ namespace TDengineDriver host = this.GetArgumentAsString(argv, "-h", "127.0.0.1"); user = this.GetArgumentAsString(argv, "-u", "root"); password = this.GetArgumentAsString(argv, "-p", "taosdata"); - dbName = this.GetArgumentAsString(argv, "-d", "db"); + dbName = this.GetArgumentAsString(argv, "-d", "tdengint_test_cs"); stableName = this.GetArgumentAsString(argv, "-s", "st"); tablePrefix = this.GetArgumentAsString(argv, "-t", "t"); isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0; diff --git a/tests/examples/C#/schemaless/schemaless.csproj b/tests/examples/C#/schemaless/schemaless.csproj new file mode 100644 index 0000000000000000000000000000000000000000..d132e34589525826d5b0ff0f0055156fad2d5a38 --- /dev/null +++ b/tests/examples/C#/schemaless/schemaless.csproj @@ -0,0 +1,12 @@ + + + + Exe + net5.0 + + + + + + + diff --git a/tests/examples/C#/taosdemo/taosdemo.cs b/tests/examples/C#/taosdemo/taosdemo.cs index e092c48f15314f5cad0a9509190d7b9970a7073a..2c77285488830323ed03a04a1d1c89c048ad2ea8 100644 --- a/tests/examples/C#/taosdemo/taosdemo.cs +++ b/tests/examples/C#/taosdemo/taosdemo.cs @@ -118,7 +118,7 @@ namespace TDengineDriver port = (short)this.GetArgumentAsLong(argv, "-p", 0, 65535, 6030); user = this.GetArgumentAsString(argv, "-u", "root"); password = this.GetArgumentAsString(argv, "-P", "taosdata"); - dbName = this.GetArgumentAsString(argv, "-d", "db"); + dbName = this.GetArgumentAsString(argv, "-d", "taosdemo_cs"); stablePrefix = this.GetArgumentAsString(argv, "-s", "st"); tablePrefix = this.GetArgumentAsString(argv, "-m", "t"); isInsertOnly = this.GetArgumentAsFlag(argv, "-x", true); diff --git a/tests/examples/JDBC/connectionPools/pom.xml b/tests/examples/JDBC/connectionPools/pom.xml index 81c549274c81ddc69d52508c46cd215edd8c5467..91f1cb36f28840b7d5eeb428aca3f940365ed59d 100644 --- a/tests/examples/JDBC/connectionPools/pom.xml +++ b/tests/examples/JDBC/connectionPools/pom.xml @@ -53,7 +53,7 @@ org.apache.logging.log4j log4j-core - 2.14.1 + 2.15.0 diff --git a/tests/examples/JDBC/taosdemo/pom.xml b/tests/examples/JDBC/taosdemo/pom.xml index 91b976c2ae6c76a5ae2d7b76c3b90d05e4dae57f..c6e61f5d22ca83c5d56deef7db9354913a3321b1 100644 --- a/tests/examples/JDBC/taosdemo/pom.xml +++ b/tests/examples/JDBC/taosdemo/pom.xml @@ -88,7 +88,7 @@ org.apache.logging.log4j log4j-core - 2.14.1 + 2.15.0 diff --git a/tests/get_catalog.py b/tests/get_catalog.py index e1449ed78dcbc24bb66f0339862f9c50e6a5d749..2a8a290c1966b278c1c84d52e15407428578fc1d 100644 --- a/tests/get_catalog.py +++ b/tests/get_catalog.py @@ -17,8 +17,11 @@ import sys import getopt import os from fabric2 import Connection + sys.path.append("pytest") import importlib +import re + class CatalogGen: def __init__(self, CaseDirList, CatalogName, DirDepth): @@ -31,7 +34,7 @@ class CatalogGen: for i in self.CaseDirList: self.GetCatalog(i) self.CollectLog(i) - print('Catalog Generation done') + print("Catalog Generation done") def CollectLog(self, CaseDir): DirorFiles = os.listdir(CaseDir) @@ -43,12 +46,14 @@ class CatalogGen: else: if i == self.CatalogName and fileName not in self.blacklist: self.blacklist.append(fileName) - with open(fileName, "r") as f : + with open(fileName, "r") as f: Catalog = f.read() title = CaseDir.split("/")[-1] TitleLevel = CaseDir.count("/") - with open(os.path.dirname(CaseDir) + '/' + self.CatalogName, "a") as f : - f.write("#" * TitleLevel + ' %s\n' % title) + with open( + os.path.dirname(CaseDir) + "/" + self.CatalogName, "a" + ) as f: + f.write("#" * TitleLevel + " %s\n" % title) f.write(Catalog) def GetCatalog(self, CaseDir): @@ -58,16 +63,20 @@ class CatalogGen: fileName = os.path.join(root, file) moduleName = fileName.replace(".py", "").replace("/", ".") uModule = importlib.import_module(moduleName) - title = file.split('.')[0] - TitleLevel = root.count('/') + 1 + title = file.split(".")[0] + TitleLevel = root.count("/") + 1 try: ucase = uModule.TDTestCase() - with open(root + '/' + self.CatalogName, 'a') as f: - f.write('#'*TitleLevel + ' %s\n' % title) - for i in ucase.caseDescription.__doc__.split('\n'): - if i.lstrip() == '':continue - f.write('* ' + i.strip()+'\n') - except : + with open(root + "/" + self.CatalogName, "a") as f: + f.write("#" * TitleLevel + " %s\n" % title) + for i in ucase.caseDescription.__doc__.split("\n"): + if i.lstrip() == "": + continue + if re.match("^case.*:", i.strip()): + f.write("* " + i.strip() + "\n") + else: + f.write(i.strip() + "\n") + except: print(fileName) def CleanCatalog(self): @@ -75,57 +84,61 @@ class CatalogGen: for root, dirs, files in os.walk(i): for file in files: if file == self.CatalogName: - os.remove(root + '/' + self.CatalogName) - print('clean is done') + os.remove(root + "/" + self.CatalogName) + print("clean is done") + if __name__ == "__main__": CaseDirList = [] - CatalogName = '' + CatalogName = "" DirDepth = 0 generate = True delete = True - opts, args = getopt.gnu_getopt(sys.argv[1:], 'd:c:v:n:th') + opts, args = getopt.gnu_getopt(sys.argv[1:], "d:c:v:n:th") for key, value in opts: - if key in ['-h', '--help']: + if key in ["-h", "--help"]: + print("A collection of test cases catalog written using Python") print( - 'A collection of test cases catalog written using Python') - print("-d root dir of test case files written by Python, default: system-test,develop-test") - print('-c catalog file name, default: catalog.md') - print('-v dir depth of test cases.default: 5') - print('-n generate') - print('-r delete') + "-d root dir of test case files written by Python, default: system-test,develop-test" + ) + print("-c catalog file name, default: catalog.md") + print("-v dir depth of test cases.default: 5") + print("-n generate") + print("-r delete") sys.exit(0) - if key in ['-d']: - CaseDirList = value.split(',') + if key in ["-d"]: + CaseDirList = value.split(",") - if key in ['-c']: + if key in ["-c"]: CatalogName = value - if key in ['-v']: + if key in ["-v"]: DirDepth = int(value) - if key in ['-n']: - if (value.upper() == "TRUE"): + if key in ["-n"]: + if value.upper() == "TRUE": generate = True - elif (value.upper() == "FALSE"): + elif value.upper() == "FALSE": generate = False - if key in ['-r']: - if (value.upper() == "TRUE"): + if key in ["-r"]: + if value.upper() == "TRUE": delete = True - elif (value.upper() == "FALSE"): + elif value.upper() == "FALSE": delete = False print(CaseDirList, CatalogName) - if CaseDirList == [] : - CaseDirList = ['system-test', 'develop-test'] - if CatalogName == '' : - CatalogName = 'catalog.md' + if CaseDirList == []: + CaseDirList = ["system-test", "develop-test"] + if CatalogName == "": + CatalogName = "catalog.md" if DirDepth == 0: DirDepth = 5 - print('opt:\n\tcatalogname: %s\n\tcasedirlist: %s\n\tdepth: %d\n\tgenerate: %s\n\tdelete: %s' - % (CatalogName, ','.join(CaseDirList), DirDepth, generate, delete)) + print( + "opt:\n\tcatalogname: %s\n\tcasedirlist: %s\n\tdepth: %d\n\tgenerate: %s\n\tdelete: %s" + % (CatalogName, ",".join(CaseDirList), DirDepth, generate, delete) + ) f = CatalogGen(CaseDirList, CatalogName, DirDepth) if delete: f.CleanCatalog() diff --git a/tests/pytest/functions/function_interp.py b/tests/pytest/functions/function_interp.py index b3cf42fd275c07745109cf37eb9e1712b67ba7a9..e45983427d64a801fc866058a6468414d62b81c5 100644 --- a/tests/pytest/functions/function_interp.py +++ b/tests/pytest/functions/function_interp.py @@ -8360,6 +8360,45 @@ class TDTestCase: sql += "where ts >= '%s' AND ts <= '%s' range('%s' , '%s') EVERY(1s) FILL(NULL);" % (self.ts , self.ts + 10000 , self.ts + 150000 , self.ts + 200000) datacheck = tdSql.error(sql) + # TD-10736 Exception use case for coredump + + tdSql.execute("create database db_except;") + tdSql.execute("use db_except;") + tdSql.execute("create table tb (ts timestamp, c1 int);") + tdSql.execute("insert into tb values ('2021-10-01 08:00:00.000' ,1);") + tdSql.execute("insert into tb values ('2021-10-01 08:00:01.000' ,2);") + tdSql.execute("insert into tb values ('2021-10-01 08:00:02.000' ,3);") + tdSql.execute("insert into tb values ('2021-10-01 08:00:03.000' ,4);") + + tdSql.execute("create stable stb (ts timestamp, c1 int) tags (id int);") + tdSql.execute("insert into sub_1 using stb tags (1) values ('2021-10-01 08:00:00.000' ,1);") + tdSql.execute("insert into sub_1 using stb tags (1) values ('2021-10-01 08:00:01.000' ,2);") + + tdSql.execute("insert into sub_2 using stb tags (1) values ('2021-10-01 08:00:00.000' ,3);") + tdSql.execute("insert into sub_2 using stb tags (1) values ('2021-10-01 08:00:01.000' ,4);") + + tdSql.execute("insert into sub_3 using stb tags (1) values ('2021-10-01 08:00:01.000' ,1);") + tdSql.execute("insert into sub_3 using stb tags (1) values ('2021-10-01 08:00:02.000' ,2);") + tdSql.execute("insert into sub_3 using stb tags (1) values ('2021-10-01 08:00:03.000' ,3);") + tdSql.execute("insert into sub_3 using stb tags (1) values ('2021-10-01 08:00:04.000' ,4);") + + tdSql.query("select interp(c1) from tb where ts = '2021-10-01 08:00:00.000' every(1s); ") + tdSql.checkData(0,1,1) + tdSql.query("select interp(c1) from tb where ts = '2021-10-01 08:00:98.000' every(1s); ") + tdSql.checkRows(0) + + tdSql.query("select interp(c1) from sub_1 where ts = '2021-10-01 08:00:00.000' every(1s); ") + tdSql.checkData(0,1,1) + tdSql.query("select interp(c1) from sub_1 where ts = '2021-10-01 08:00:98.000' every(1s); ") + tdSql.checkRows(0) + + tdSql.error("select interp(c1) from stb where ts = '2021-10-01 08:00:00.000' every(1s); ") + tdSql.error("select interp(c1) from stb where ts = '2021-10-01 08:00:98.000' every(1s); ") + tdSql.query("select interp(c1) from stb where ts = '2021-10-01 08:00:00.000' every(1s) group by tbname; ") + tdSql.checkRows(2) + tdSql.query("select interp(c1) from stb where ts = '2021-10-01 08:00:98.000' every(1s) group by tbname; ") + tdSql.checkRows(0) + # Nested Query + where + range + FILL(NULL) + EVERY( s)(3) # sql = "select * from (select %s from stable_1 where ts BETWEEN '%s' AND '%s' range('%s' , '%s') EVERY(1s) FILL(NULL) group by tbname) z1," % (interp_select , self.ts , self.ts + 10000 , self.ts - 10000 , self.ts + 100000) # sql += "(select %s from stable_2 where ts BETWEEN '%s' AND '%s' range('%s' , '%s') EVERY(1s) FILL(NULL) group by tbname) z2 where z1.ts=z2.ts ;" % (interp_select , self.ts , self.ts + 10000 , self.ts - 10000 , self.ts + 100000) diff --git a/tests/pytest/tag_lite/json_tag_extra.py b/tests/pytest/tag_lite/json_tag_extra.py deleted file mode 100644 index 3e0853d78bbab03344157604b83d1f28399cab75..0000000000000000000000000000000000000000 --- a/tests/pytest/tag_lite/json_tag_extra.py +++ /dev/null @@ -1,533 +0,0 @@ -################################################################### -# Copyright (c) 2016 by TAOS Technologies, Inc. -# All rights reserved. -# -# This file is proprietary and confidential to TAOS Technologies. -# No part of this file may be reproduced, db_test.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 sys -import taos -from util.log import tdLog -from util.cases import tdCases -from util.sql import tdSql -import time -import random - -class TDTestCase: - - def init(self, conn, logSql): - tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor(), logSql) - - def run(self): - tdSql.prepare() - tdSql.execute("drop database if exists db_json;") - print("==============step1 tag format =======") - tdLog.info("create database ") - tdSql.execute("create database db_json") - tdSql.execute("use db_json") - # test tag format - tdSql.execute("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(128))") - tdSql.error("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(64),jtag1 json(100))") - tdSql.error("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(64),dataBool bool)") - - tdSql.execute("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{\"loc\":\"fff\",\"id\":5}')") - - # two stables: jsons1 jsons2 ,test tag's value and key - tdSql.execute("insert into jsons1_1(ts,dataInt) using jsons1 tags('{\"loc+\":\"fff\",\"id\":5}') values (now,12)") - - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{oc:\"fff\",\"id\":5}')") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{\"loc\":fff,\"id\":5}')") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('3333')") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{\"loc\":}')") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{\"loc\":bool)") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags(true)") - tdSql.error("CREATE TABLE if not exists jsons1_1 using jsons1 tags('[{\"num\":5}]')") - - # test object and key max length. max key length is 256, max object length is 4096 include abcd. - tdSql.execute("create table if not exists jsons4(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(128))") - - char1= ''.join(['abcd']*64) - char2=''.join(char1) - char3= ''.join(['abcd']*1022) - print(len(char3)) # 4088 - tdSql.execute("CREATE TABLE if not exists jsons4_1 using jsons4 tags('{\"%s\":5}')" % char1) # len(key)=256 - tdSql.error("CREATE TABLE if not exists jsons4_1 using jsons4 tags('{\"%s1\":5}')" % char2) # len(key)=257 - tdSql.execute("CREATE TABLE if not exists jsons4_2 using jsons4 tags('{\"T\":\"%s\"}')" % char3) # len(object)=4096 - tdSql.error("CREATE TABLE if not exists jsons4_2 using jsons4 tags('{\"TS\":\"%s\"}')" % char3) # len(object)=4097 - - tdSql.execute("insert into jsons1_1 values(now, 1, 'json1')") - tdSql.execute("insert into jsons1_1 values(now+1s, 1, 'json1')") - tdSql.execute("insert into jsons1_2 using jsons1 tags('{\"num\":5,\"location\":\"beijing\"}') values (now, 1, 'json2')") - tdSql.execute("insert into jsons1_3 using jsons1 tags('{\"num\":34,\"location\":\"beijing\",\"level\":\"l1\"}') values (now, 1, 'json3')") - tdSql.execute("insert into jsons1_4 using jsons1 tags('{\"class\":55,\"location\":\"beijing\",\"name\":\"name4\"}') values (now, 1, 'json4')") - - # test : json'vaule is null and - tdSql.execute("create table if not exists jsons2(ts timestamp, dataInt2 int, dataStr2 nchar(50)) tags(jtag2 json(300))") - tdSql.execute("CREATE TABLE if not exists jsons2_1 using jsons2 tags('{}')") - tdSql.query("select jtag2 from jsons2_1") - tdSql.checkData(0, 0, None) - tdSql.execute("CREATE TABLE if not exists jsons2_2 using jsons2 tags('')") - tdSql.query("select jtag2 from jsons2_2") - tdSql.checkData(0, 0, None) - tdSql.execute("CREATE TABLE if not exists jsons2_3 using jsons2 tags('null')") - tdSql.query("select jtag2 from jsons2_3") - tdSql.checkData(0, 0, None) - tdSql.execute("CREATE TABLE if not exists jsons2_4 using jsons2 tags('\t')") - tdSql.query("select jtag2 from jsons2_4") - tdSql.checkData(0, 0, None) - tdSql.execute("CREATE TABLE if not exists jsons2_5 using jsons2 tags(' ')") - tdSql.query("select jtag2 from jsons2_5") - tdSql.checkData(0, 0, None) - tdSql.execute("CREATE TABLE if not exists jsons2_6 using jsons2 tags('{\"nv\":null,\"tea\":true,\"\":false,\"\":123,\"tea\":false}')") - tdSql.query("select jtag2 from jsons2_6") - tdSql.checkData(0, 0, "{\"nv\":null,\"tea\":true}") - tdSql.error("CREATE TABLE if not exists jsons2_7 using jsons2 tags('{\"nv\":null,\"tea\":123,\"\":false,\"\":123,\"tea\":false}')") - tdSql.execute("CREATE TABLE if not exists jsons2_7 using jsons2 tags('{\"test7\":\"\"}')") - tdSql.query("select jtag2 from jsons2_7") - tdSql.checkData(0, 0, "{\"test7\":\"\"}") - - print("==============step2 alter json table==") - tdLog.info("alter stable add tag") - tdSql.error("ALTER STABLE jsons2 add tag jtag3 nchar(20)") - tdSql.error("ALTER STABLE jsons2 drop tag jtag2") - tdSql.execute("ALTER STABLE jsons2 change tag jtag2 jtag3") - tdSql.query("select jtag3->'tea' from jsons2_6") - tdSql.checkData(0, 0, "true") - tdSql.error("ALTER TABLE jsons2_6 SET TAG jtag3='{\"tea-=[].;!@#$%^&*()/\":}'") - tdSql.execute("ALTER TABLE jsons2_6 SET TAG jtag3='{\"tea-=[].;!@#$%^&*()/\":false}'") - tdSql.query("select jtag3 from jsons2_6") - tdSql.checkData(0, 0, "{\"tea-=[].;!@#$%^&*()/\":false}") - tdSql.execute("ALTER TABLE jsons1_1 SET TAG jtag='{\"sex\":\"femail\",\"age\":35}'") - tdSql.query("select jtag from jsons1_1") - tdSql.checkData(0, 0, "{\"sex\":\"femail\",\"age\":35}") - - - - print("==============step3") - tdLog.info("select table") - - tdSql.query("select jtag from jsons1_1") - tdSql.checkData(0, 0, "{\"sex\":\"femail\",\"age\":35}") - - tdSql.query("select jtag from jsons1 where jtag->'name'='name4'") - tdSql.checkData(0, 0, "{\"class\":55,\"location\":\"beijing\",\"name\":\"name4\"}") - - - tdSql.query("select * from jsons1") - tdSql.checkRows(6) - - tdSql.query("select * from jsons1_1") - tdSql.checkRows(3) - - tdSql.query("select * from jsons1 where jtag->'location'='beijing'") - tdSql.checkRows(3) - - tdSql.query("select jtag->'location' from jsons1_2") - tdSql.checkData(0, 0, "\"beijing\"") - - - tdSql.query("select jtag->'num' from jsons1 where jtag->'level'='l1'") - tdSql.checkData(0, 0, 34) - - tdSql.query("select jtag->'location' from jsons1") - tdSql.checkRows(4) - - tdSql.query("select jtag from jsons1_1") - tdSql.checkRows(1) - - tdSql.query("select * from jsons1 where jtag?'sex' or jtag?'num'") - tdSql.checkRows(5) - - tdSql.query("select * from jsons1 where jtag?'sex' and jtag?'num'") - tdSql.checkRows(0) - - tdSql.query("select jtag->'sex' from jsons1 where jtag?'sex' or jtag?'num'") - tdSql.checkRows(3) - - tdSql.query("select *,tbname from jsons1 where jtag->'location'='beijing'") - tdSql.checkRows(3) - - tdSql.query("select *,tbname from jsons1 where jtag->'num'=5 or jtag?'sex'") - tdSql.checkRows(4) - - # test with tbname - tdSql.query("select * from jsons1 where tbname = 'jsons1_1'") - tdSql.checkRows(3) - - tdSql.query("select * from jsons1 where tbname = 'jsons1_1' or jtag?'num'") - tdSql.checkRows(5) - - tdSql.query("select * from jsons1 where tbname = 'jsons1_1' and jtag?'num'") - tdSql.checkRows(0) - - tdSql.query("select * from jsons1 where tbname = 'jsons1_1' or jtag->'num'=5") - tdSql.checkRows(4) - - # test where condition like - tdSql.query("select *,tbname from jsons1 where jtag->'location' like 'bei%'") - tdSql.checkRows(3) - - tdSql.query("select *,tbname from jsons1 where jtag->'location' like 'bei%' and jtag->'location'='beijin'") - tdSql.checkRows(0) - - tdSql.query("select *,tbname from jsons1 where jtag->'location' like 'bei%' or jtag->'location'='beijin'") - tdSql.checkRows(3) - - tdSql.query("select *,tbname from jsons1 where jtag->'location' like 'bei%' and jtag->'num'=34") - tdSql.checkRows(1) - - tdSql.query("select *,tbname from jsons1 where (jtag->'location' like 'shanghai%' or jtag->'num'=34) and jtag->'class'=55") - tdSql.checkRows(0) - - tdSql.error("select * from jsons1 where jtag->'num' like '5%'") - - # test where condition in - tdSql.query("select * from jsons1 where jtag->'location' in ('beijing')") - tdSql.checkRows(3) - - tdSql.query("select * from jsons1 where jtag->'num' in (5,34)") - tdSql.checkRows(2) - - tdSql.error("select * from jsons1 where jtag->'num' in ('5',34)") - - tdSql.query("select * from jsons1 where jtag->'location' in ('beijing') and jtag->'class'=55") - tdSql.checkRows(1) - - # test where condition match - tdSql.query("select * from jsons1 where jtag->'location' match 'jin$'") - tdSql.checkRows(0) - - tdSql.query("select * from jsons1 where jtag->'location' match 'jin'") - tdSql.checkRows(3) - - tdSql.query("select * from jsons1 where datastr match 'json' and jtag->'location' match 'jin'") - tdSql.checkRows(3) - - tdSql.error("select * from jsons1 where jtag->'num' match '5'") - - # test json string parse - tdSql.error("CREATE TABLE if not exists jsons1_5 using jsons1 tags('efwewf')") - tdSql.execute("CREATE TABLE if not exists jsons1_5 using jsons1 tags('\t')") - tdSql.execute("CREATE TABLE if not exists jsons1_6 using jsons1 tags('')") - - tdSql.query("select jtag from jsons1_6") - tdSql.checkData(0, 0, None) - - tdSql.execute("CREATE TABLE if not exists jsons1_7 using jsons1 tags('{}')") - tdSql.query("select jtag from jsons1_7") - tdSql.checkData(0, 0, None) - - tdSql.execute("CREATE TABLE if not exists jsons1_8 using jsons1 tags('null')") - tdSql.query("select jtag from jsons1_8") - tdSql.checkData(0, 0, None) - - tdSql.execute("CREATE TABLE if not exists jsons1_9 using jsons1 tags('{\"\":4, \"time\":null}')") - tdSql.query("select jtag from jsons1_9") - tdSql.checkData(0, 0, "{\"time\":null}") - - tdSql.execute("CREATE TABLE if not exists jsons1_10 using jsons1 tags('{\"k1\":\"\",\"k1\":\"v1\",\"k2\":true,\"k3\":false,\"k4\":55}')") - tdSql.query("select jtag from jsons1_10") - tdSql.checkData(0, 0, "{\"k1\":\"\",\"k2\":true,\"k3\":false,\"k4\":55}") - - tdSql.query("select jtag->'k2' from jsons1_10") - tdSql.checkData(0, 0, "true") - - tdSql.query("select jtag from jsons1 where jtag->'k1'=''") - tdSql.checkRows(1) - - tdSql.query("select jtag from jsons1 where jtag->'k2'=true") - tdSql.checkRows(1) - - tdSql.query("select jtag from jsons1 where jtag is null") - tdSql.checkRows(4) - - tdSql.query("select jtag from jsons1 where jtag is not null") - tdSql.checkRows(6) - - tdSql.query("select * from jsons1 where jtag->'location' is not null") - tdSql.checkRows(3) - - tdSql.query("select tbname,jtag from jsons1 where jtag->'location' is null") - tdSql.checkRows(7) - - tdSql.query("select * from jsons1 where jtag->'num' is not null") - tdSql.checkRows(2) - - tdSql.query("select * from jsons1 where jtag->'location'='null'") - tdSql.checkRows(0) - - tdSql.error("select * from jsons1 where jtag->'num'='null'") - - # test distinct - tdSql.query("select distinct jtag from jsons1") - tdSql.checkRows(7) - - tdSql.query("select distinct jtag->'location' from jsons1") - tdSql.checkRows(2) - - # test chinese - tdSql.execute("CREATE TABLE if not exists jsons1_11 using jsons1 tags('{\"k1\":\"中国\",\"k5\":\"是是是\"}')") - - tdSql.query("select tbname,jtag from jsons1 where jtag->'k1' match '中'") - tdSql.checkRows(1) - - tdSql.query("select tbname,jtag from jsons1 where jtag->'k1'='中国'") - tdSql.checkRows(1) - - #test dumplicate key with normal colomn - tdSql.execute("INSERT INTO jsons1_12 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"dataStr\":\"是是是\"}') values(now, 4, \"你就会\")") - - tdSql.query("select *,tbname,jtag from jsons1 where jtag->'dataStr' match '是'") - tdSql.checkRows(1) - - tdSql.query("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt'") - tdSql.checkRows(1) - - # test filter : and /or / in/ like - tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool'") - tdSql.checkRows(2) - - tdSql.query("select * from jsons1 where jtag->'num' is not null and jtag?'class' or jtag?'databool'") - tdSql.checkRows(1) - tdSql.checkData(0, 1, 4) - - tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%'") - tdSql.checkRows(3) - - tdSql.query("select * from jsons1 where datastr like '你就会' and ( jtag->'num' is not null or jtag?'tbname' and jtag?'databool' )") - tdSql.checkRows(1) - tdSql.checkData(0, 1, 4) - - tdSql.error("select * from jsons1 where datastr like '你就会' and jtag->'num' is not null or jtag?'class' and jtag?'databool'") - - - tdSql.error("select * from jsons1 where datastr like '你就会' or jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%' ") - - tdSql.query("select * from jsons1 where datastr like '你就会' and (jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%' )") - tdSql.checkRows(0) - - tdSql.error("select *,tbname,jtag from jsons1 where dataBool=true") - - # test error - tdSql.error("CREATE TABLE if not exists jsons1_13 using jsons1 tags(3333)") - tdSql.execute("CREATE TABLE if not exists jsons1_13 using jsons1 tags('{\"1loc\":\"fff\",\";id\":5}')") - tdSql.error("CREATE TABLE if not exists jsons1_13 using jsons1 tags('{\"。loc\":\"fff\",\"fsd\":5}')") - tdSql.error("CREATE TABLE if not exists jsons1_13 using jsons1 tags('{\"试试\":\"fff\",\";id\":5}')") - tdSql.error("insert into jsons1_13 using jsons1 tags(3)") - - # test query normal column,tag and tbname - tdSql.execute("create stable if not exists jsons3(ts timestamp, dataInt3 int(100), dataBool3 bool, dataStr3 nchar(50)) tags(jtag3 json)") - tdSql.execute("create table jsons3_2 using jsons3 tags('{\"t\":true,\"t123\":123,\"\":\"true\"}')") - - tdSql.execute("create table jsons3_3 using jsons3 tags('{\"t\":true,\"t123\":456,\"k1\":true,\"str1\":\"111\"}')") - tdSql.execute("insert into jsons3_3 values(now, 4, true, 'test')") - - tdSql.execute("insert into jsons3_4 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":false,\"s\":null,\"str1\":\"112\"}') values(now, 5, true, 'test')") - tdSql.query("select * from jsons3 where jtag3->'k1'=true") - tdSql.checkRows(1) - tdSql.error("select jtag3->k1 from jsons3 ") - tdSql.error("select jtag3 from jsons3 where jtag3->'k1'") - tdSql.error("select jtag3 from jsons3 where jtag3?'k1'=true") - tdSql.error("select jtag3?'k1' from jsons3;") - tdSql.error("select jtag3?'k1'=true from jsons3;") - tdSql.error("select jtag3->'k1'=true from jsons3;") - tdSql.error("insert into jsons3_5 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":1,\"s\":null}') values(now, 5, true, 'test')") - tdSql.execute("insert into jsons3_5 using jsons3 tags('{\"t\":true,\"t123\":012,\"k2\":null,\"s\":null}') values(now, 5, true, 'test')") - tdSql.execute("insert into jsons3_6 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":false,\"s\":null}') values(now, 5, true, 'test')") - tdSql.query("select jtag3 from jsons3 where jtag3->'t123'=12 or jtag3?'k1'") - tdSql.checkRows(4) - tdSql.query("select distinct jtag3 from jsons3 where jtag3->'t123'=12 or jtag3?'k1'") - tdSql.checkRows(4) - - - tdSql.execute("INSERT INTO jsons1_14 using jsons1 tags('{\"tbname\":\"tt\",\"location\":\"tianjing\",\"dataStr\":\"是是是\"}') values(now,5, \"你就会\")") - - tdSql.query("select ts,jtag->'tbname',tbname from jsons1 where dataint>=1 and jtag->'location' in ('tianjing','123') and jtag?'tbname'") - tdSql.checkRows(1) - tdSql.checkData(0, 1, '\"tt\"') - - tdSql.query("select ts,jtag->'tbname',tbname from jsons1 where dataint between 1 and 5 and jtag->'location' in ('tianjing','123')") - tdSql.checkRows(1) - tdSql.checkData(0, 2, 'jsons1_14') - - tdSql.query("select ts,jtag3->'tbname', jtag3->'str1',tbname from jsons3 where jtag3->'t123' between 456 and 789 and jtag3->'str1' like '11%' ") - tdSql.checkRows(2) - for i in range(1): - if tdSql.queryResult[i][1] == 'jsons3_3': - tdSql.checkData(i, 2, 111) - - tdSql.query("select jtag3->'',dataint3 from jsons3") - tdSql.checkRows(4) - for i in range(4): - if tdSql.queryResult[i][1] == 4: - tdSql.checkData(i, 0, None) - tdSql.query("select tbname,dataint3,jtag3->'k1' from jsons3;") - tdSql.checkRows(4) - for i in range(3): - if tdSql.queryResult[i][1] == 4: - tdSql.checkData(i, 2, 'true') - - # Select_exprs is SQL function -Aggregation function , tests includes group by and order by - - tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by jtag->'location';") - tdSql.checkData(2, 3, '\"tianjing\"') - tdSql.checkRows(3) - for i in range(2): - if tdSql.queryResult[i][3] == '\"beijing\"': - tdSql.checkData(i, 0, 1) - tdSql.checkData(i, 1, 3) - # tdSql.query("select avg(dataInt) as 123 ,count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by 123") - # tdSql.query("select avg(dataInt) as avgdata ,count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by avgdata ;") - tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by ts;") - tdSql.checkRows(3) - #tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'age' order by tbname;") - #tdSql.checkRows(2) - tdSql.error("select avg(dataInt) from jsons1 group by jtag->'location' order by dataInt;") - tdSql.error("select avg(dataInt),tbname from jsons1 group by jtag->'location' order by tbname;") - tdSql.execute("CREATE TABLE if not exists jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"location\":\"beijing\"}')") - tdSql.execute("insert into jsons1_15 values(now+1s, 2, 'json1')") - tdSql.error("select twa(dataint) from jsons1 group by jtag->'location' order by jtag->'location';") - tdSql.error("select irate(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - # tdSql.query(" select stddev(dataint) from jsons1 group by jtag->'location';") - # tdSql.checkRows(2) - tdSql.query(" select stddev(dataint) from jsons1 where jtag->'location'='beijing';") - tdSql.checkRows(1) - tdSql.error(" select LEASTSQUARES(dataint,1,2) from jsons1_1 where jtag->'location' ='beijing' ;") - - # Select_exprs is SQL function -Selection function - - tdSql.query(" select min(dataint),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 1) - tdSql.query(" select max(dataint),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.checkData(0, 0, 12) - tdSql.query(" select first(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select last(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.error(" select last(*),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.query(" select last_row(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,0) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,50) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,90) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,100) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,0,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,50,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query(" select apercentile(dataint,100,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkRows(1) - tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location';") - #tdSql.query("select tbname,top(dataint,1) from jsons1 group by jtag->'location' order by tbname asc;") - #tdSql.query("select tbname,top(dataint,1) from jsons1 group by jtag->'location' order by tbname desc") - tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by jtag->'location' asc;") - tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by jtag->'location' desc;") - tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by ts desc;") - tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by ts asc;") - - # tdSql.query("select top(dataint,100) from jsons1 group by jtag->'location';") - # tdSql.query("select bottom(dataint,1) from jsons1 group by jtag->'location';") - # tdSql.query("select bottom(dataint,100) from jsons1 group by jtag->'location';") - - tdSql.execute("create table if not exists jsons_interp(ts timestamp, dataInt int, dataBool bool, datafloat float, datadouble double,dataStr nchar(50)) tags(jtag json)") - tdSql.execute("insert into jsons_interp_1 using jsons_interp tags('{\"nv\":null,\"tea\":true,\"\":false,\"rate\":456,\"tea\":false}') values ('2021-07-25 02:19:54.119',2,'true',0.9,0.1,'123')") - tdSql.execute("insert into jsons_interp_1 values ('2021-07-25 02:19:54.219',3,'true',-4.8,-5.5,'123') ") - tdSql.execute("insert into jsons_interp_2 using jsons_interp tags('{\"nv\":null,\"tea\":true,\"level\":\"123456\",\"rate\":123,\"tea\":false}') values ('2021-07-25 02:19:54.319',4,'true',0.9,0.1,'123')") - tdSql.execute("insert into jsons_interp_2 values ('2021-07-25 02:19:54.419',5,'true',-5.1,1.3,'123') ") - #tdSql.query(" select interp(dataint) from jsons_interp where jtag->'rate' in (123,456) and ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") - #tdSql.query(" select interp(dataint) from jsons_interp where jtag->'rate'=123 and ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") - #tdSql.query(" select interp(dataint) from jsons_interp where ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") - - - # tdSql.checkData(0,0,1) - # tdSql.checkRows(1) - - # Select_exprs is SQL function -Calculation function - - tdSql.error(" select diff(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.error(" select Derivative(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.query(" select SPREAD(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.checkData(0, 0, 11) - tdSql.query(" select ceil(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.query(" select floor(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - tdSql.query(" select round(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") - #need insert new data --data type is double or float and tests ceil floor round . - tdSql.execute("create table if not exists jsons7(ts timestamp, dataInt int, dataBool bool, datafloat float, datadouble double,dataStr nchar(50)) tags(jtag json)") - tdSql.execute("insert into jsons7_1 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\" \":123,\"tea\":false}') values (now,2,'true',0.9,0.1,'123')") - tdSql.query("select * from jsons7 where jtag->'tea'=0 ;") - tdSql.checkRows(0) - tdSql.query("select * from jsons7 where jtag->'tea'=3;") - # tdSql.checkRows(0) - tdSql.execute("insert into jsons7_1 values (now+1s,3,'true',-4.8,-5.5,'123') ") - tdSql.execute("insert into jsons7_1 values (now+2s,4,'true',1.9998,2.00001,'123') ") - tdSql.execute("insert into jsons7_2 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\"tag\":123,\"tea\":false}') values (now,5,'true',4.01,2.2,'123') ") - tdSql.execute("insert into jsons7_2 (ts,datadouble) values (now+3s,-0.9) ") - tdSql.execute("insert into jsons7_2 (ts,datadouble) values (now+4s,-2.9) ") - tdSql.execute("insert into jsons7_2 (ts,datafloat) values (now+1s,-0.9) ") - tdSql.execute("insert into jsons7_2 (ts,datafloat) values (now+2s,-1.9) ") - # tdSql.execute("CREATE TABLE if not exists jsons7_3 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\"tag\":4569\"tea\":false}') ") - tdSql.query("select ts,ceil(dataint),ceil(datafloat),ceil(datadouble) from jsons7 where jtag?'tea';") - tdSql.query("select ceil(dataint),ceil(datafloat),ceil(datadouble) from jsons7 where jtag?'tea';") - tdSql.query("select ts,floor(dataint),floor(datafloat),floor(datadouble) from jsons7 where jtag?'tea';") - tdSql.query("select floor(dataint),floor(datafloat),floor(datadouble) from jsons7 where jtag?'tea';") - tdSql.query("select ts,round(dataint),round(datafloat),round(datadouble) from jsons7 where jtag?'tea';") - tdSql.query("select round(dataint),round(datafloat),round(datadouble) from jsons7 where jtag?'tea';") - - - # test join - tdSql.execute("create table if not exists jsons6(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json)") - tdSql.execute("create table if not exists jsons5(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json)") - tdSql.execute("CREATE TABLE if not exists jsons6_1 using jsons6 tags('{\"loc\":\"fff\",\"id\":6,\"user\":\"ffc\"}')") - tdSql.execute("CREATE TABLE if not exists jsons6_2 using jsons6 tags('{\"loc\":\"ffc\",\"id\":5}')") - tdSql.execute("insert into jsons6_1 values ('2020-04-18 15:00:00.000', 1, false, 'json1')") - tdSql.execute("insert into jsons6_2 values ('2020-04-18 15:00:01.000', 2, false, 'json1')") - tdSql.execute("insert into jsons5_1 using jsons5 tags('{\"loc\":\"fff\",\"num\":5,\"location\":\"beijing\"}') values ('2020-04-18 15:00:00.000', 2, true, 'json2')") - tdSql.execute("insert into jsons5_2 using jsons5 tags('{\"loc\":\"fff\",\"id\":5,\"location\":\"beijing\"}') values ('2020-04-18 15:00:01.000', 2, true, 'json2')") - - tdSql.error("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'loc'=b.jtag->'loc'") - tdSql.error("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'user'=b.jtag->'loc';") - tdSql.query("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'id'=b.jtag->'id'") - tdSql.checkData(0, 0, "sss") - tdSql.checkData(0, 2, "\"ffc\"") - - #nested query - tdSql.query("select jtag->'tag' from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where cdata=3 ") - # tdSql.query("select * from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where cdata=3 ") - # tdSql.query("select jtag from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where jtag->'tag'=123 ") - - # query child table - # tdSql.error("select * from jsons3_2 where jtag3->'k1'=true;") - # tdSql.checkData(0, 0, None) - # tdSql.checkRows(3) - - - - # # test drop tables and databases - # tdSql.execute("drop table jsons1_1") - # tdSql.execute("drop stable jsons1") - # tdSql.execute("drop stable jsons3") - # tdSql.execute("drop stable jsons2") - # tdSql.execute("drop database db_json") - - - - def stop(self): - tdSql.close() - tdLog.success("%s successfully executed" % __file__) - - -tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase())