diff --git a/Jenkinsfile b/Jenkinsfile index 433b46067a..dfe9ed4389 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,20 +42,52 @@ def pre_test(){ killall -9 taosd ||echo "no taosd running" killall -9 gdb || echo "no gdb running" cd ${WKC} - git checkout develop - git reset --hard HEAD~10 >/dev/null + git reset --hard HEAD~10 >/dev/null + ''' + script { + if (env.CHANGE_TARGET == 'master') { + sh ''' + cd ${WKC} + git checkout master + ''' + } + else { + sh ''' + cd ${WKC} + git checkout develop + ''' + } + } + sh''' + cd ${WKC} git pull >/dev/null git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - find ${WKC}/tests/pytest -name \'*\'.sql -exec rm -rf {} \\; + git clean -dfx cd ${WK} git reset --hard HEAD~10 - git checkout develop - git pull >/dev/null + ''' + script { + if (env.CHANGE_TARGET == 'master') { + sh ''' + cd ${WK} + git checkout master + ''' + } + else { + sh ''' + cd ${WK} + git checkout develop + ''' + } + } + sh ''' cd ${WK} + git pull >/dev/null + export TZ=Asia/Harbin date - rm -rf ${WK}/debug + git clean -dfx mkdir debug cd debug cmake .. > /dev/null @@ -92,7 +124,8 @@ pipeline { git pull git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - ''' + ''' + script{ env.skipstage=sh(script:"cd ${WORKSPACE}.tes && git --no-pager diff --name-only FETCH_HEAD develop|grep -v -E '.*md|//src//connector|Jenkinsfile|test-all.sh' || echo 0 ",returnStdout:true) } @@ -185,14 +218,12 @@ pipeline { rm -rf /var/log/taos/* ./handle_crash_gen_val_log.sh ''' - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - sh ''' - cd ${WKC}/tests/pytest - rm -rf /var/lib/taos/* - rm -rf /var/log/taos/* - ./handle_taosd_val_log.sh - ''' - } + sh ''' + cd ${WKC}/tests/pytest + rm -rf /var/lib/taos/* + rm -rf /var/log/taos/* + ./handle_taosd_val_log.sh + ''' timeout(time: 45, unit: 'MINUTES'){ sh ''' date diff --git a/cmake/install.inc b/cmake/install.inc index 01d3c8a4df..5823ef743e 100755 --- a/cmake/install.inc +++ b/cmake/install.inc @@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS) #INSTALL(TARGETS taos RUNTIME DESTINATION driver) #INSTALL(TARGETS shell RUNTIME DESTINATION .) IF (TD_MVN_INSTALLED) - INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.24-dist.jar DESTINATION connector/jdbc) + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.25-dist.jar DESTINATION connector/jdbc) ENDIF () ELSEIF (TD_DARWIN) SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh") diff --git a/cmake/version.inc b/cmake/version.inc index b1e09c9532..fe4c017c71 100755 --- a/cmake/version.inc +++ b/cmake/version.inc @@ -4,7 +4,7 @@ PROJECT(TDengine) IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "2.0.18.0") + SET(TD_VER_NUMBER "2.0.19.0") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/documentation20/cn/02.getting-started/docs.md b/documentation20/cn/02.getting-started/docs.md index f86e616c42..b46322cef2 100644 --- a/documentation20/cn/02.getting-started/docs.md +++ b/documentation20/cn/02.getting-started/docs.md @@ -101,7 +101,7 @@ $ taos -h 192.168.0.1 -s "use db; show tables;" ### 运行SQL命令脚本 -TDengine终端可以通过`source`命令来运行SQL命令脚本. +TDengine 终端可以通过 `source` 命令来运行 SQL 命令脚本. ```mysql taos> source ; @@ -109,10 +109,10 @@ taos> source ; ### Shell小技巧 -- 可以使用上下光标键查看已经历史输入的命令 -- 修改用户密码。在shell中使用alter user命令 +- 可以使用上下光标键查看历史输入的指令 +- 修改用户密码。在 shell 中使用 alter user 指令 - ctrl+c 中止正在进行中的查询 -- 执行`RESET QUERY CACHE`清空本地缓存的表的schema +- 执行 `RESET QUERY CACHE` 清空本地缓存的表 schema ## TDengine 极速体验 @@ -179,19 +179,20 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s); ### TDengine服务器支持的平台列表 -| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | -| -------------- | --------------------- | ------------------------ | --------------- | --------------- | ------------------------- | --------------------- | -| X64 | ● | ● | | ○ | ● | ● | -| 树莓派 ARM32 | | ● | ● | | | | -| 龙芯 MIPS64 | | | ● | | | | -| 鲲鹏 ARM64 | | ○ | ○ | | ● | | -| 申威 Alpha64 | | | ○ | ● | | | -| 飞腾 ARM64 | | ○ 优麒麟 | | | | | -| 海光 X64 | ● | ● | ● | ○ | ● | ● | -| 瑞芯微 ARM64/32 | | | ○ | | | | -| 全志 ARM64/32 | | | ○ | | | | -| 炬力 ARM64/32 | | | ○ | | | | -| TI ARM32 | | | ○ | | | | +| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | **华为 EulerOS** | +| -------------- | --------------------- | ------------------------ | --------------- | --------------- | ------------------------- | --------------------- | --------------------- | +| X64 | ● | ● | | ○ | ● | ● | ● | +| 树莓派 ARM32 | | ● | ● | | | | | +| 龙芯 MIPS64 | | | ● | | | | | +| 鲲鹏 ARM64 | | ○ | ○ | | ● | | | +| 申威 Alpha64 | | | ○ | ● | | | | +| 飞腾 ARM64 | | ○ 优麒麟 | | | | | | +| 海光 X64 | ● | ● | ● | ○ | ● | ● | | +| 瑞芯微 ARM64/32 | | | ○ | | | | | +| 全志 ARM64/32 | | | ○ | | | | | +| 炬力 ARM64/32 | | | ○ | | | | | +| TI ARM32 | | | ○ | | | | | +| 华为云 ARM64 | | | | | | | ● | 注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。 @@ -211,7 +212,7 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s); | **Python** | ● | ● | ● | ○ | ● | ● | ● | -- | ● | | **Go** | ● | ● | ● | ○ | ● | ● | ○ | -- | -- | | **NodeJs** | ● | ● | ○ | ○ | ● | ● | ○ | -- | -- | -| **C#** | ○ | ● | ● | ○ | ○ | ○ | ○ | -- | -- | +| **C#** | ● | ● | ○ | ○ | ○ | ○ | ○ | -- | -- | | **RESTful** | ● | ● | ● | ● | ● | ● | ● | ● | ● | 注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。 diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index fb50e20e51..6811315e7d 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -14,7 +14,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 | **Python** | ● | ● | ● | ○ | ● | ● | ○ | -- | ○ | | **Go** | ● | ● | ● | ○ | ● | ● | ○ | -- | -- | | **NodeJs** | ● | ● | ○ | ○ | ● | ● | ○ | -- | -- | -| **C#** | ○ | ● | ● | ○ | ○ | ○ | ○ | -- | -- | +| **C#** | ● | ● | ○ | ○ | ○ | ○ | ○ | -- | -- | | **RESTful** | ● | ● | ● | ● | ● | ● | ○ | ○ | ○ | 其中 ● 表示经过官方测试验证, ○ 表示非官方测试验证。 @@ -23,7 +23,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 * 在没有安装TDengine服务端软件的系统中使用连接器(除RESTful外)访问 TDengine 数据库,需要安装相应版本的客户端安装包来使应用驱动(Linux系统中文件名为libtaos.so,Windows系统中为taos.dll)被安装在系统中,否则会产生无法找到相应库文件的错误。 * 所有执行 SQL 语句的 API,例如 C/C++ Connector 中的 `tao_query`、`taos_query_a`、`taos_subscribe` 等,以及其它语言中与它们对应的API,每次都只能执行一条 SQL 语句,如果实际参数中包含了多条语句,它们的行为是未定义的。 -* 升级到TDengine到2.0.8.0版本的用户,必须更新JDBC连接TDengine必须升级taos-jdbcdriver到2.0.12及以上。 +* 升级到TDengine到2.0.8.0版本的用户,必须更新JDBC连接TDengine必须升级taos-jdbcdriver到2.0.12及以上。详细的版本依赖关系请参见 [taos-jdbcdriver 文档](https://www.taosdata.com/cn/documentation/connector/java#version)。 * 无论选用何种编程语言的连接器,2.0 及以上版本的 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池,以避免连接内的“USE statement”状态量在线程之间相互干扰(但连接的查询和写入操作都是线程安全的)。 ## 安装连接器驱动步骤 diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index b4fa2b160a..58191e0bd8 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -29,21 +29,21 @@ taos> DESCRIBE meters; ## 支持的数据类型 -使用TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则: +使用 TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则: -- 时间格式为```YYYY-MM-DD HH:mm:ss.MS```, 默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128``` -- 内部函数now是服务器的当前时间 -- 插入记录时,如果时间戳为now,插入数据时使用服务器当前时间 -- Epoch Time: 时间戳也可以是一个长整数,表示从1970-01-01 08:00:00.000开始的毫秒数 -- 时间可以加减,比如 now-2h,表明查询时刻向前推2个小时(最近2小时)。 数字后面的时间单位可以是 a(毫秒)、s(秒)、 m(分)、h(小时)、d(天)、w(周)。 比如select * from t1 where ts > now-2w and ts <= now-1w, 表示查询两周前整整一周的数据。 在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。 +- 时间格式为 ```YYYY-MM-DD HH:mm:ss.MS```,默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128``` +- 内部函数 now 是客户端的当前时间 +- 插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间 +- Epoch Time:时间戳也可以是一个长整数,表示从 1970-01-01 08:00:00.000 开始的毫秒数 +- 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。 -TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMicrosecond就可支持微秒。 +TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableMicrosecond 就可以支持微秒。 -在TDengine中,普通表的数据模型中可使用以下10种数据类型。 +在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。 | | 类型 | Bytes | 说明 | | ---- | :-------: | ------ | ------------------------------------------------------------ | -| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。 | +| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18 版本开始,已经去除了这一时间范围限制) | | 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL | | 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL | | 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh index e63889aff1..9241f01efa 100755 --- a/packaging/tools/remove.sh +++ b/packaging/tools/remove.sh @@ -120,7 +120,7 @@ function clean_service_on_systemd() { if [ "$verMode" == "cluster" ]; then nginx_service_config="${service_config_dir}/${nginx_service_name}.service" - if [ -d ${bin_dir}/web ]; then + if [ -d ${install_nginxd_dir} ]; then if systemctl is-active --quiet ${nginx_service_name}; then echo "Nginx for TDengine is running, stopping it..." ${csudo} systemctl stop ${nginx_service_name} &> /dev/null || echo &> /dev/null diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 88628b4db6..65bf5447e2 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: tdengine base: core18 -version: '2.0.18.0' +version: '2.0.19.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. description: | @@ -72,7 +72,7 @@ parts: - usr/bin/taosd - usr/bin/taos - usr/bin/taosdemo - - usr/lib/libtaos.so.2.0.18.0 + - usr/lib/libtaos.so.2.0.19.0 - usr/lib/libtaos.so.1 - usr/lib/libtaos.so diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 4869f65645..c91943e232 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -96,6 +96,25 @@ typedef struct STableMetaInfo { SArray *tagColList; // SArray, involved tag columns } STableMetaInfo; + +typedef struct SColumnIndex { + int16_t tableIndex; + int16_t columnIndex; +} SColumnIndex; + + +typedef struct SFieldInfo { + int16_t numOfOutput; // number of column in result + TAOS_FIELD* final; + SArray *internalField; // SArray +} SFieldInfo; + +typedef struct SColumn { + SColumnIndex colIndex; + int32_t numOfFilters; + SColumnFilterInfo *filterInfo; +} SColumn; + /* the structure for sql function in select clause */ typedef struct SSqlExpr { char aliasName[TSDB_COL_NAME_LEN]; // as aliasName @@ -109,32 +128,24 @@ typedef struct SSqlExpr { tVariant param[3]; // parameters are not more than 3 int32_t offset; // sub result column value of arithmetic expression. int16_t resColId; // result column id + SColumn *pFilter; // expr filter } SSqlExpr; -typedef struct SColumnIndex { - int16_t tableIndex; - int16_t columnIndex; -} SColumnIndex; +typedef struct SExprFilter { + tSqlExpr *pExpr; //used for having parse + SSqlExpr *pSqlExpr; + SArray *fp; + SColumn *pFilters; //having filter info +}SExprFilter; typedef struct SInternalField { TAOS_FIELD field; bool visible; SExprInfo *pArithExprInfo; SSqlExpr *pSqlExpr; + SExprFilter *pFieldFilters; } SInternalField; -typedef struct SFieldInfo { - int16_t numOfOutput; // number of column in result - TAOS_FIELD* final; - SArray *internalField; // SArray -} SFieldInfo; - -typedef struct SColumn { - SColumnIndex colIndex; - int32_t numOfFilters; - SColumnFilterInfo *filterInfo; -} SColumn; - typedef struct SCond { uint64_t uid; int32_t len; // length of tag query condition data @@ -243,6 +254,7 @@ typedef struct SQueryInfo { int32_t round; // 0/1/.... int32_t bufLen; char* buf; + int32_t havingFieldNum; } SQueryInfo; typedef struct { @@ -261,10 +273,10 @@ typedef struct { char * curSql; // current sql, resume position of sql after parsing paused int8_t parseFinished; - char reserve2[3]; // fix bus error on arm32 + char reserve2[3]; // fix bus error on arm32 int16_t numOfCols; - char reserve3[2]; // fix bus error on arm32 + char reserve3[2]; // fix bus error on arm32 uint32_t allocSize; char * payload; int32_t payloadLen; @@ -274,9 +286,9 @@ typedef struct { int32_t numOfParams; int8_t dataSourceType; // load data from file or not - char reserve4[3]; // fix bus error on arm32 + char reserve4[3]; // fix bus error on arm32 int8_t submitSchema; // submit block is built with table schema - char reserve5[3]; // fix bus error on arm32 + char reserve5[3]; // fix bus error on arm32 STagData tagData; // NOTE: pTagData->data is used as a variant length array SName **pTableNameList; // all involved tableMeta list of current insert sql statement. @@ -316,6 +328,7 @@ typedef struct { char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) SColumnIndex* pColumnIndex; + TAOS_FIELD* final; SArithmeticSupport *pArithSup; // support the arithmetic expression calculation on agg functions struct SLocalMerger *pLocalMerger; } SSqlRes; diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index 851f7398db..c296072393 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -22,6 +22,7 @@ #include "tscUtil.h" #include "tschemautil.h" #include "tsclient.h" +#include "qUtil.h" typedef struct SCompareParam { SLocalDataSource **pLocalData; @@ -1243,6 +1244,76 @@ static bool saveGroupResultInfo(SSqlObj *pSql) { return false; } + +bool doFilterFieldData(char *input, SExprFilter* pFieldFilters, int16_t type, bool* notSkipped) { + bool qualified = false; + + for(int32_t k = 0; k < pFieldFilters->pFilters->numOfFilters; ++k) { + __filter_func_t fp = taosArrayGetP(pFieldFilters->fp, k); + SColumnFilterElem filterElem = {.filterInfo = pFieldFilters->pFilters->filterInfo[k]}; + + bool isnull = isNull(input, type); + if (isnull) { + if (fp == isNullOperator) { + qualified = true; + break; + } else { + continue; + } + } else { + if (fp == notNullOperator) { + qualified = true; + break; + } else if (fp == isNullOperator) { + continue; + } + } + + if (fp(&filterElem, input, input, type)) { + qualified = true; + break; + } + } + + *notSkipped = qualified; + + return TSDB_CODE_SUCCESS; +} + + +int32_t doHavingFilter(SQueryInfo* pQueryInfo, tFilePage* pOutput, bool* notSkipped) { + *notSkipped = true; + + if (pQueryInfo->havingFieldNum <= 0) { + return TSDB_CODE_SUCCESS; + } + + //int32_t exprNum = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + + size_t numOfOutput = tscNumOfFields(pQueryInfo); + for(int32_t i = 0; i < numOfOutput; ++i) { + SInternalField* pInterField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); + SExprFilter* pFieldFilters = pInterField->pFieldFilters; + + if (pFieldFilters == NULL) { + continue; + } + + int32_t type = pInterField->field.type; + + char* pInput = pOutput->data + pOutput->num* pFieldFilters->pSqlExpr->offset; + + doFilterFieldData(pInput, pFieldFilters, type, notSkipped); + if (*notSkipped == false) { + return TSDB_CODE_SUCCESS; + } + } + + return TSDB_CODE_SUCCESS; +} + + + /** * * @param pSql @@ -1283,6 +1354,22 @@ bool genFinalResults(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool noMoreCurren doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalMerge->finalModel->rowSize); } + bool notSkipped = true; + + doHavingFilter(pQueryInfo, pResBuf, ¬Skipped); + + if (!notSkipped) { + pRes->numOfRows = 0; + pLocalMerge->discard = !noMoreCurrentGroupRes; + + if (pLocalMerge->discard) { + SColumnModel *pInternModel = pLocalMerge->pDesc->pColumnModel; + tColModelAppend(pInternModel, pLocalMerge->discardData, pLocalMerge->pTempBuffer->data, 0, 1, 1); + } + + return notSkipped; + } + // no interval query, no fill operation if (pQueryInfo->interval.interval == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) { genFinalResWithoutFill(pRes, pLocalMerge, pQueryInfo); diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 6f74101164..920937928f 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -118,7 +118,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1 if (sToken.type == TK_PLUS) { useconds += interval; } else { - useconds = (useconds >= interval) ? useconds - interval : 0; + useconds = useconds - interval; } *next = pTokenEnd; @@ -937,6 +937,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC return ret; } + if (sql == NULL) { + return TSDB_CODE_TSC_INVALID_SQL; + } + code = tscGetTableMetaEx(pSql, pTableMetaInfo, true); if (TSDB_CODE_TSC_ACTION_IN_PROGRESS == code) { return code; @@ -945,6 +949,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } else { sql = sToken.z; + if (sql == NULL) { + return TSDB_CODE_TSC_INVALID_SQL; + } + code = tscGetTableMetaEx(pSql, pTableMetaInfo, false); if (pCmd->curSql == NULL) { assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS); @@ -952,10 +960,6 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC } *sqlstr = sql; - - if (*sqlstr == NULL) { - code = TSDB_CODE_TSC_INVALID_SQL; - } return code; } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 5841aa0cd5..f83e7fe79d 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -34,6 +34,7 @@ #include "tstoken.h" #include "tstrbuild.h" #include "ttokendef.h" +#include "qUtil.h" #define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0" @@ -1097,6 +1098,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { return true; } + static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd) { assert(pTagsList != NULL); @@ -1606,7 +1608,7 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) { int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) { assert(pSelectList != NULL && pCmd != NULL); - + const char* msg1 = "too many columns in selection clause"; const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; const char* msg5 = "invalid function name"; @@ -1655,7 +1657,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis } if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) { - return TSDB_CODE_TSC_INVALID_SQL; + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -1676,18 +1678,6 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - /* - * transfer sql functions that need secondary merge into another format - * in dealing with super table queries such as: count/first/last - */ - if (isSTable) { - tscTansformFuncForSTableQuery(pQueryInfo); - - if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { - return TSDB_CODE_TSC_INVALID_SQL; - } - } - return TSDB_CODE_SUCCESS; } @@ -3065,6 +3055,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) return TSDB_CODE_SUCCESS; } + static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) { if (pColumn == NULL) { return NULL; @@ -3088,15 +3079,11 @@ static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) { } static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter, - SColumnIndex* columnIndex, tSqlExpr* pExpr) { + int16_t colType, tSqlExpr* pExpr) { const char* msg = "not supported filter condition"; tSqlExpr* pRight = pExpr->pRight; - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, columnIndex->tableIndex); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex->columnIndex); - - int16_t colType = pSchema->type; if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) { colType = TSDB_DATA_TYPE_BIGINT; } else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) { @@ -3301,7 +3288,10 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC } pColumn->colIndex = *pIndex; - return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr); + + int16_t colType = pSchema->type; + + return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, colType, pExpr); } static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pTableCond, SStringBuilder* sb) { @@ -6030,7 +6020,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo if (TSDB_COL_IS_TAG(pColIndex->flag)) { SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); + SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, (int32_t)size - pQueryInfo->havingFieldNum, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); memset(pExpr->aliasName, 0, sizeof(pExpr->aliasName)); tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName)); @@ -6039,7 +6029,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo // NOTE: tag column does not add to source column list SColumnList ids = getColumnList(1, 0, pColIndex->colIndex); - insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr); + insertResultField(pQueryInfo, (int32_t)size - pQueryInfo->havingFieldNum, &ids, bytes, (int8_t)type, name, pExpr); } else { // if this query is "group by" normal column, time window query is not allowed if (isTimeWindowQuery(pQueryInfo)) { @@ -6166,7 +6156,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { } // projection query on super table does not compatible with "group by" syntax - if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { + if (tscIsProjectionQuery(pQueryInfo)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -6336,7 +6326,7 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { int32_t totalBufSize = 1024; - char str[1024] = {0}; + char str[1024+1] = {0}; int32_t offset = 0; offset += sprintf(str, "num:%d [", size); @@ -6769,6 +6759,313 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } + + int32_t tscInsertExprFields(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SInternalField** interField) { + tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL, .distinct = false}; + + int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); + + // ADD TRUE FOR TEST + if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, true) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + ++pQueryInfo->havingFieldNum; + + size_t n = tscSqlExprNumOfExprs(pQueryInfo); + SSqlExpr* pSqlExpr = tscSqlExprGet(pQueryInfo, (int32_t)n - 1); + + int32_t slot = tscNumOfFields(pQueryInfo) - 1; + SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); + pInfo->visible = false; + + if (pInfo->pFieldFilters == NULL) { + SExprFilter* pFieldFilters = calloc(1, sizeof(SExprFilter)); + if (pFieldFilters == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SColumn* pFilters = calloc(1, sizeof(SColumn)); + if (pFilters == NULL) { + tfree(pFieldFilters); + + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + pFieldFilters->pFilters = pFilters; + pFieldFilters->pSqlExpr = pSqlExpr; + pSqlExpr->pFilter = pFilters; + pInfo->pFieldFilters = pFieldFilters; + } + + pInfo->pFieldFilters->pExpr = pExpr; + + *interField = pInfo; + + return TSDB_CODE_SUCCESS; +} + +int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SInternalField** pField) { + SInternalField* pInfo = NULL; + + for (int32_t i = pQueryInfo->havingFieldNum - 1; i >= 0; --i) { + pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, pQueryInfo->fieldsInfo.numOfOutput - 1 - i); + + if (pInfo->pFieldFilters && 0 == tSqlExprCompare(pInfo->pFieldFilters->pExpr, pExpr)) { + *pField = pInfo; + return TSDB_CODE_SUCCESS; + } + } + + int32_t ret = tscInsertExprFields(pCmd, pQueryInfo, pExpr, &pInfo); + if (ret) { + return ret; + } + + *pField = pInfo; + + return TSDB_CODE_SUCCESS; +} + +static int32_t genExprFilter(SExprFilter * exprFilter) { + exprFilter->fp = taosArrayInit(4, sizeof(__filter_func_t)); + if (exprFilter->fp == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < exprFilter->pFilters->numOfFilters; ++i) { + SColumnFilterInfo *filterInfo = &exprFilter->pFilters->filterInfo[i]; + + int32_t lower = filterInfo->lowerRelOptr; + int32_t upper = filterInfo->upperRelOptr; + if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) { + tscError("invalid rel optr"); + return TSDB_CODE_TSC_APP_ERROR; + } + + __filter_func_t ffp = getFilterOperator(lower, upper); + if (ffp == NULL) { + tscError("invalid filter info"); + return TSDB_CODE_TSC_APP_ERROR; + } + + taosArrayPush(exprFilter->fp, &ffp); + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t sqlOptr) { + const char* msg1 = "non binary column not support like operator"; + const char* msg2 = "invalid operator for binary column in having clause"; + const char* msg3 = "invalid operator for bool column in having clause"; + + SColumn* pColumn = NULL; + SColumnFilterInfo* pColFilter = NULL; + SInternalField* pInfo = NULL; + + /* + * in case of TK_AND filter condition, we first find the corresponding column and build the query condition together + * the already existed condition. + */ + if (sqlOptr == TK_AND) { + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pExpr->pLeft, &pInfo); + if (ret) { + return ret; + } + + pColumn = pInfo->pFieldFilters->pFilters; + + // this is a new filter condition on this column + if (pColumn->numOfFilters == 0) { + pColFilter = addColumnFilterInfo(pColumn); + } else { // update the existed column filter information, find the filter info here + pColFilter = &pColumn->filterInfo[0]; + } + + if (pColFilter == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + } else if (sqlOptr == TK_OR) { + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pExpr->pLeft, &pInfo); + if (ret) { + return ret; + } + + pColumn = pInfo->pFieldFilters->pFilters; + + // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2" + pColFilter = addColumnFilterInfo(pColumn); + if (pColFilter == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + } else { // error; + return TSDB_CODE_TSC_INVALID_SQL; + } + + pColFilter->filterstr = + ((pInfo->field.type == TSDB_DATA_TYPE_BINARY || pInfo->field.type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0); + + if (pColFilter->filterstr) { + if (pExpr->tokenId != TK_EQ + && pExpr->tokenId != TK_NE + && pExpr->tokenId != TK_ISNULL + && pExpr->tokenId != TK_NOTNULL + && pExpr->tokenId != TK_LIKE + ) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + } + } else { + if (pExpr->tokenId == TK_LIKE) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pInfo->field.type == TSDB_DATA_TYPE_BOOL) { + if (pExpr->tokenId != TK_EQ && pExpr->tokenId != TK_NE) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + } + } + + int32_t ret = doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pInfo->field.type, pExpr); + if (ret) { + return ret; + } + + return genExprFilter(pInfo->pFieldFilters); +} + +int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t parentOptr) { + if (pExpr == NULL) { + return TSDB_CODE_SUCCESS; + } + + const char* msg1 = "invalid having clause"; + + tSqlExpr* pLeft = pExpr->pLeft; + tSqlExpr* pRight = pExpr->pRight; + + if (pExpr->tokenId == TK_AND || pExpr->tokenId == TK_OR) { + int32_t ret = getHavingExpr(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId); + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } + + return getHavingExpr(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId); + } + + if (pLeft == NULL || pRight == NULL) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pLeft->type == pRight->type) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + exchangeExpr(pExpr); + + pLeft = pExpr->pLeft; + pRight = pExpr->pRight; + + + if (pLeft->type != SQL_NODE_SQLFUNCTION) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pRight->type != SQL_NODE_VALUE) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pExpr->tokenId >= TK_BITAND) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + //if (pLeft->pParam == NULL || pLeft->pParam->nExpr < 1) { + // return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + //} + + if (pLeft->pParam) { + size_t size = taosArrayGetSize(pLeft->pParam); + for (int32_t i = 0; i < size; i++) { + tSqlExprItem* pParamElem = taosArrayGet(pLeft->pParam, i); + if (pParamElem->pNode->tokenId != TK_ALL && + pParamElem->pNode->tokenId != TK_ID && + pParamElem->pNode->tokenId != TK_STRING && + pParamElem->pNode->tokenId != TK_INTEGER && + pParamElem->pNode->tokenId != TK_FLOAT) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pParamElem->pNode->tokenId == TK_ID && (pParamElem->pNode->colInfo.z == NULL && pParamElem->pNode->colInfo.n == 0)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pParamElem->pNode->tokenId == TK_ID) { + SColumnIndex index = COLUMN_INDEX_INITIALIZER; + if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + + if (index.columnIndex <= 0 || + index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + } + } + } + + pLeft->functionId = isValidFunction(pLeft->operand.z, pLeft->operand.n); + if (pLeft->functionId < 0) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + return handleExprInHavingClause(pCmd, pQueryInfo, pExpr, parentOptr); +} + + + +int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd, bool isSTable, int32_t joinQuery, int32_t timeWindowQuery) { + const char* msg1 = "having only works with group by"; + const char* msg2 = "functions or others can not be mixed up"; + const char* msg3 = "invalid expression in having clause"; + + if (pExpr == NULL) { + return TSDB_CODE_SUCCESS; + } + + if (pQueryInfo->groupbyExpr.numOfGroupCols <= 0) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pExpr->pLeft == NULL || pExpr->pRight == NULL) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + + if (pQueryInfo->colList == NULL) { + pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); + } + + int32_t ret = 0; + + if ((ret = getHavingExpr(pCmd, pQueryInfo, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) { + return ret; + } + + //REDO function check + if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + } + + return TSDB_CODE_SUCCESS; +} + + + + + int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index) { assert(pQuerySqlNode != NULL && (pQuerySqlNode->from == NULL || taosArrayGetSize(pQuerySqlNode->from->tableList) > 0)); @@ -6934,6 +7231,23 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i } } + // parse the having clause in the first place + if (parseHavingClause(pQueryInfo, pQuerySqlNode->pHaving, pCmd, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + /* + * transfer sql functions that need secondary merge into another format + * in dealing with super table queries such as: count/first/last + */ + if (isSTable) { + tscTansformFuncForSTableQuery(pQueryInfo); + + if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { + return TSDB_CODE_TSC_INVALID_SQL; + } + } + if (parseSessionClause(pCmd, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -7125,3 +7439,10 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { return false; } + + + + + + + diff --git a/src/client/src/tscSchemaUtil.c b/src/client/src/tscSchemaUtil.c index 67352ca71c..2ea382132b 100644 --- a/src/client/src/tscSchemaUtil.c +++ b/src/client/src/tscSchemaUtil.c @@ -144,8 +144,9 @@ SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) { SNewVgroupInfo info = {0}; info.numOfEps = pVgroupMsg->numOfEps; info.vgId = pVgroupMsg->vgId; - info.inUse = 0; + info.inUse = 0; // 0 is the default value of inUse in case of multiple replica + assert(info.numOfEps >= 1 && info.vgId >= 1); for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) { tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN); info.ep[i].port = pVgroupMsg->epAddr[i].port; diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 7085318e35..8889e25177 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -34,6 +34,7 @@ int tscKeepConn[TSDB_SQL_MAX] = {0}; TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid, TSKEY dflt); void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts); void tscSaveSubscriptionProgress(void* sub); +static int32_t extractSTableQueryVgroupId(STableMetaInfo* pTableMetaInfo); static int32_t minMsgSize() { return tsRpcHeadSize + 100; } static int32_t getWaitingTimeInterval(int32_t count) { @@ -78,7 +79,8 @@ static void tscEpSetHtons(SRpcEpSet *s) { for (int32_t i = 0; i < s->numOfEps; i++) { s->port[i] = htons(s->port[i]); } -} +} + bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) { if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) { return false; @@ -111,19 +113,22 @@ static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SNewVgroupInfo *pVgrou } } -static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) { - SSqlCmd *pCmd = &pObj->cmd; +static void tscUpdateVgroupInfo(SSqlObj *pSql, SRpcEpSet *pEpSet) { + SSqlCmd *pCmd = &pSql->cmd; STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return; } - int32_t vgId = pTableMetaInfo->pTableMeta->vgId; + int32_t vgId = -1; if (pTableMetaInfo->pTableMeta->tableType == TSDB_SUPER_TABLE) { - assert(vgId == 0); - return; + vgId = extractSTableQueryVgroupId(pTableMetaInfo); + } else { + vgId = pTableMetaInfo->pTableMeta->vgId; } + assert(vgId > 0); + SNewVgroupInfo vgroupInfo = {.vgId = -1}; taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo)); assert(vgroupInfo.numOfEps > 0 && vgroupInfo.vgId > 0); @@ -138,6 +143,33 @@ static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) { tscDebug("after: EndPoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps); taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(SNewVgroupInfo)); + + // Update the local cached epSet info cached by SqlObj + int32_t inUse = pSql->epSet.inUse; + tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo); + tscDebug("%p update the epSet in SqlObj, in use before:%d, after:%d", pSql, inUse, pSql->epSet.inUse); + +} + +int32_t extractSTableQueryVgroupId(STableMetaInfo* pTableMetaInfo) { + assert(pTableMetaInfo != NULL); + + int32_t vgIndex = pTableMetaInfo->vgroupIndex; + int32_t vgId = -1; + + if (pTableMetaInfo->pVgroupTables == NULL) { + SVgroupsInfo *pVgroupInfo = pTableMetaInfo->vgroupList; + assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups); + vgId = pVgroupInfo->vgroups[vgIndex].vgId; + } else { + int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables); + assert(vgIndex >= 0 && vgIndex < numOfVgroups); + + SVgroupTableInfo *pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex); + vgId = pTableIdList->vgInfo.vgId; + } + + return vgId; } void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { @@ -515,21 +547,22 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { int32_t vgIndex = pTableMetaInfo->vgroupIndex; + int32_t vgId = -1; + if (pTableMetaInfo->pVgroupTables == NULL) { SVgroupsInfo *pVgroupInfo = pTableMetaInfo->vgroupList; assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups); - - pRetrieveMsg->header.vgId = htonl(pVgroupInfo->vgroups[vgIndex].vgId); - tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qhandle:%" PRIX64, pSql, pVgroupInfo->vgroups[vgIndex].vgId, vgIndex, pSql->res.qId); + vgId = pVgroupInfo->vgroups[vgIndex].vgId; } else { int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables); assert(vgIndex >= 0 && vgIndex < numOfVgroups); SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex); - - pRetrieveMsg->header.vgId = htonl(pTableIdList->vgInfo.vgId); - tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qId:%" PRIu64, pSql, pTableIdList->vgInfo.vgId, vgIndex, pSql->res.qId); + vgId = pTableIdList->vgInfo.vgId; } + + pRetrieveMsg->header.vgId = htonl(vgId); + tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qId:%" PRIu64, pSql, vgId, vgIndex, pSql->res.qId); } else { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId); @@ -862,8 +895,44 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pSqlFuncExpr->functionId = htons(pExpr->functionId); pSqlFuncExpr->numOfParams = htons(pExpr->numOfParams); pSqlFuncExpr->resColId = htons(pExpr->resColId); + if (pTableMeta->tableType != TSDB_SUPER_TABLE && pExpr->pFilter && pExpr->pFilter->numOfFilters > 0) { + pSqlFuncExpr->filterNum = htonl(pExpr->pFilter->numOfFilters); + } else { + pSqlFuncExpr->filterNum = 0; + } + pMsg += sizeof(SSqlFuncMsg); + if (pSqlFuncExpr->filterNum) { + pMsg += sizeof(SColumnFilterInfo) * pExpr->pFilter->numOfFilters; + + // append the filter information after the basic column information + for (int32_t f = 0; f < pExpr->pFilter->numOfFilters; ++f) { + SColumnFilterInfo *pColFilter = &pExpr->pFilter->filterInfo[f]; + + SColumnFilterInfo *pFilterMsg = &pSqlFuncExpr->filterInfo[f]; + pFilterMsg->filterstr = htons(pColFilter->filterstr); + + if (pColFilter->filterstr) { + pFilterMsg->len = htobe64(pColFilter->len); + memcpy(pMsg, (void *)pColFilter->pz, (size_t)(pColFilter->len + 1)); + pMsg += (pColFilter->len + 1); // append the additional filter binary info + } else { + pFilterMsg->lowerBndi = htobe64(pColFilter->lowerBndi); + pFilterMsg->upperBndi = htobe64(pColFilter->upperBndi); + } + + pFilterMsg->lowerRelOptr = htons(pColFilter->lowerRelOptr); + pFilterMsg->upperRelOptr = htons(pColFilter->upperRelOptr); + + if (pColFilter->lowerRelOptr == TSDB_RELATION_INVALID && pColFilter->upperRelOptr == TSDB_RELATION_INVALID) { + tscError("invalid filter info"); + return TSDB_CODE_TSC_INVALID_SQL; + } + } + } + + for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log pSqlFuncExpr->arg[j].argType = htons((uint16_t)pExpr->param[j].nType); pSqlFuncExpr->arg[j].argBytes = htons(pExpr->param[j].nLen); @@ -1944,7 +2013,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) { (vgroupInfo.inUse < 0)) { // vgroup info exists, compare with it vgroupInfo = createNewVgroupInfo(&pMetaMsg->vgroup); taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo)); - tscDebug("add new VgroupInfo, vgId:%d, total:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap)); + tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap)); } } @@ -2096,18 +2165,33 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) { tscError("%p empty vgroup info", pSql); } else { for (int32_t j = 0; j < pInfo->vgroupList->numOfVgroups; ++j) { - //just init, no need to lock - SVgroupInfo *pVgroups = &pInfo->vgroupList->vgroups[j]; + // just init, no need to lock + SVgroupInfo *pVgroup = &pInfo->vgroupList->vgroups[j]; SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j]; - pVgroups->vgId = htonl(vmsg->vgId); - pVgroups->numOfEps = vmsg->numOfEps; + vmsg->vgId = htonl(vmsg->vgId); + vmsg->numOfEps = vmsg->numOfEps; + for (int32_t k = 0; k < vmsg->numOfEps; ++k) { + vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port); + } - assert(pVgroups->numOfEps >= 1 && pVgroups->vgId >= 1); + SNewVgroupInfo newVi = createNewVgroupInfo(vmsg); + pVgroup->numOfEps = newVi.numOfEps; + pVgroup->vgId = newVi.vgId; + for (int32_t k = 0; k < vmsg->numOfEps; ++k) { + pVgroup->epAddr[k].port = newVi.ep[k].port; + pVgroup->epAddr[k].fqdn = strndup(newVi.ep[k].fqdn, TSDB_FQDN_LEN); + } - for (int32_t k = 0; k < pVgroups->numOfEps; ++k) { - pVgroups->epAddr[k].port = htons(vmsg->epAddr[k].port); - pVgroups->epAddr[k].fqdn = strndup(vmsg->epAddr[k].fqdn, tListLen(vmsg->epAddr[k].fqdn)); + // check if current buffer contains the vgroup info. + // If not, add it + SNewVgroupInfo existVgroupInfo = {.inUse = -1}; + taosHashGetClone(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), NULL, &existVgroupInfo, sizeof(SNewVgroupInfo)); + + if (((existVgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&existVgroupInfo, vmsg)) || + (existVgroupInfo.inUse < 0)) { // vgroup info exists, compare with it + taosHashPut(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), &newVi, sizeof(newVi)); + tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", newVi.vgId, (int32_t) taosHashGetSize(tscVgroupMap)); } } } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 93d0e9fd09..13c8f025ea 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -405,6 +405,7 @@ int taos_affected_rows(TAOS_RES *tres) { TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { SSqlObj *pSql = (SSqlObj *)res; + SSqlRes *pRes = &pSql->res; if (pSql == NULL || pSql->signature != pSql) return 0; SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); @@ -419,7 +420,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { SFieldInfo *pFieldInfo = &pQueryInfo->fieldsInfo; - if (pFieldInfo->final == NULL) { + if (pRes->final == NULL) { TAOS_FIELD* f = calloc(pFieldInfo->numOfOutput, sizeof(TAOS_FIELD)); int32_t j = 0; @@ -439,10 +440,10 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { } } - pFieldInfo->final = f; + pRes->final = f; } - return pFieldInfo->final; + return pRes->final; } static bool needToFetchNewBlock(SSqlObj* pSql) { diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 7699e6f459..d90b5fead1 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -619,7 +619,7 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p if (code == TSDB_CODE_SUCCESS) { tscCreateStream(pStream, pSql, code); } else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) { - tscError("%p open stream failed, sql:%s, code:%s", pSql, sqlstr, tstrerror(pRes->code)); + tscError("%p open stream failed, sql:%s, code:%s", pSql, sqlstr, tstrerror(code)); taosReleaseRef(tscObjRef, pSql->self); free(pStream); return NULL; diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 299cf03805..484610818e 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -2986,7 +2986,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { } tscDebug("%p sub:%p query complete, ep:%s, vgId:%d, orderOfSub:%d, retrieve data", trsupport->pParentSql, pSql, - pVgroup->epAddr[0].fqdn, pVgroup->vgId, trsupport->subqueryIndex); + pVgroup->epAddr[pSql->epSet.inUse].fqdn, pVgroup->vgId, trsupport->subqueryIndex); if (pSql->res.qId == 0) { // qhandle is NULL, code is TSDB_CODE_SUCCESS means no results generated from this vnode tscRetrieveFromDnodeCallBack(param, pSql, 0); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 438e5618df..4e8bfdf064 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -429,6 +429,8 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { tfree(pRes->pArithSup->data); tfree(pRes->pArithSup); } + + tfree(pRes->final); pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free } @@ -1045,6 +1047,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { .pSqlExpr = NULL, .pArithExprInfo = NULL, .visible = true, + .pFieldFilters = NULL, }; info.field = *pField; @@ -1057,6 +1060,7 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F .pSqlExpr = NULL, .pArithExprInfo = NULL, .visible = true, + .pFieldFilters = NULL, }; info.field = *field; @@ -1130,6 +1134,22 @@ int32_t tscGetResRowLength(SArray* pExprList) { return size; } +static void destroyFilterInfo(SColumnFilterInfo* pFilterInfo, int32_t numOfFilters) { + for(int32_t i = 0; i < numOfFilters; ++i) { + if (pFilterInfo[i].filterstr) { + tfree(pFilterInfo[i].pz); + } + } + + tfree(pFilterInfo); +} + +static void tscColumnDestroy(SColumn* pCol) { + destroyFilterInfo(pCol->filterInfo, pCol->numOfFilters); + free(pCol); +} + + void tscFieldInfoClear(SFieldInfo* pFieldInfo) { if (pFieldInfo == NULL) { return; @@ -1150,10 +1170,14 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) { tfree(pInfo->pArithExprInfo); } + + if (pInfo->pFieldFilters != NULL) { + tscColumnDestroy(pInfo->pFieldFilters->pFilters); + tfree(pInfo->pFieldFilters); + } } taosArrayDestroy(pFieldInfo->internalField); - tfree(pFieldInfo->final); memset(pFieldInfo, 0, sizeof(SFieldInfo)); } @@ -1411,15 +1435,7 @@ SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { return taosArrayGetP(pColumnList, i); } -static void destroyFilterInfo(SColumnFilterInfo* pFilterInfo, int32_t numOfFilters) { - for(int32_t i = 0; i < numOfFilters; ++i) { - if (pFilterInfo[i].filterstr) { - tfree(pFilterInfo[i].pz); - } - } - - tfree(pFilterInfo); -} + SColumn* tscColumnClone(const SColumn* src) { assert(src != NULL); @@ -1436,10 +1452,6 @@ SColumn* tscColumnClone(const SColumn* src) { return dst; } -static void tscColumnDestroy(SColumn* pCol) { - destroyFilterInfo(pCol->filterInfo, pCol->numOfFilters); - free(pCol); -} void tscColumnListCopy(SArray* dst, const SArray* src, int16_t tableIndex) { assert(src != NULL && dst != NULL); diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 3f96466cc0..26475834d5 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -39,6 +39,7 @@ extern int8_t tsEnableTelemetryReporting; extern char tsEmail[]; extern char tsArbitrator[]; extern int8_t tsArbOnline; +extern int32_t tsDnodeId; // common extern int tsRpcTimer; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 5f4ce046ed..69b01e6c08 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -43,6 +43,7 @@ int8_t tsEnableVnodeBak = 1; int8_t tsEnableTelemetryReporting = 1; int8_t tsArbOnline = 0; char tsEmail[TSDB_FQDN_LEN] = {0}; +int32_t tsDnodeId = 0; // common int32_t tsRpcTimer = 1000; @@ -212,7 +213,7 @@ float tsAvailTmpDirectorySpace = 0; float tsAvailDataDirGB = 0; float tsUsedDataDirGB = 0; float tsReservedTmpDirectorySpace = 1.0f; -float tsMinimalDataDirGB = 1.0f; +float tsMinimalDataDirGB = 2.0f; int32_t tsTotalMemoryMB = 0; uint32_t tsVersion = 0; diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index 540dc8eb58..eb158b1f76 100644 --- a/src/connector/jdbc/CMakeLists.txt +++ b/src/connector/jdbc/CMakeLists.txt @@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED) ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} POST_BUILD COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.24-dist.jar ${LIBRARY_OUTPUT_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.25-dist.jar ${LIBRARY_OUTPUT_PATH} COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMENT "build jdbc driver") ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) diff --git a/src/connector/jdbc/deploy-pom.xml b/src/connector/jdbc/deploy-pom.xml index 935b3f7e4a..eb8c92575c 100755 --- a/src/connector/jdbc/deploy-pom.xml +++ b/src/connector/jdbc/deploy-pom.xml @@ -5,7 +5,7 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.24 + 2.0.25 jar JDBCDriver diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 5d7c89e2d2..1f75754b0c 100755 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.taosdata.jdbc taos-jdbcdriver - 2.0.24 + 2.0.25 jar JDBCDriver https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc @@ -62,6 +62,14 @@ + + + src/main/resources + + **/*.md + + + org.apache.maven.plugins diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java index 999df06fc7..7df7252ae2 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java @@ -15,7 +15,7 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P @Override public int getParameterCount() throws SQLException { - return parameters.length; + return parameters == null ? 0 : parameters.length; } @Override diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index 7d3741917c..5e3ffffa4f 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -29,45 +29,25 @@ public class TSDBJNIConnector { private static volatile Boolean isInitialized = false; private TaosInfo taosInfo = TaosInfo.getInstance(); + // Connection pointer used in C + private long taos = TSDBConstants.JNI_NULL_POINTER; + // result set status in current connection + private boolean isResultsetClosed = true; + private int affectedRows = -1; static { System.loadLibrary("taos"); System.out.println("java.library.path:" + System.getProperty("java.library.path")); } - /** - * Connection pointer used in C - */ - private long taos = TSDBConstants.JNI_NULL_POINTER; - - /** - * Result set pointer for the current connection - */ -// private long taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER; - - /** - * result set status in current connection - */ - private boolean isResultsetClosed = true; - private int affectedRows = -1; - - /** - * Whether the connection is closed - */ public boolean isClosed() { return this.taos == TSDBConstants.JNI_NULL_POINTER; } - /** - * Returns the status of last result set in current connection - */ public boolean isResultsetClosed() { return this.isResultsetClosed; } - /** - * Initialize static variables in JNI to optimize performance - */ public static void init(String configDir, String locale, String charset, String timezone) throws SQLWarning { synchronized (isInitialized) { if (!isInitialized) { @@ -93,11 +73,6 @@ public class TSDBJNIConnector { public static native String getTsCharset(); - /** - * Get connection pointer - * - * @throws SQLException - */ public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException { if (this.taos != TSDBConstants.JNI_NULL_POINTER) { // this.closeConnectionImp(this.taos); @@ -185,13 +160,6 @@ public class TSDBJNIConnector { private native String getErrMsgImp(long pSql); - /** - * Get resultset pointer - * Each connection should have a single open result set at a time - */ -// public long getResultSet() { -// return taosResultSetPointer; -// } private native long getResultSetImp(long connection, long pSql); public boolean isUpdateQuery(long pSql) { @@ -231,6 +199,7 @@ public class TSDBJNIConnector { // } // return resCode; // } + private native int freeResultSetImp(long connection, long result); /** @@ -323,8 +292,7 @@ public class TSDBJNIConnector { * Validate if a create table sql statement is correct without actually creating that table */ public boolean validateCreateTableSql(String sql) { - long connection = taos; - int res = validateCreateTableSqlImp(connection, sql.getBytes()); + int res = validateCreateTableSqlImp(taos, sql.getBytes()); return res != 0 ? false : true; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java index 856f5257bf..5c2d4c45b0 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -84,9 +84,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return new Timestamp(row.getDate(colIndex).getTime()); case TSDBConstants.TSDB_DATA_TYPE_BINARY: - return row.getString(colIndex).getBytes(); + return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes(); case TSDBConstants.TSDB_DATA_TYPE_NCHAR: - return row.getString(colIndex); + return row.getString(colIndex) == null ? null : row.getString(colIndex); default: return row.get(colIndex); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/OSUtils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/OSUtils.java new file mode 100644 index 0000000000..a67b4763f9 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/OSUtils.java @@ -0,0 +1,17 @@ +package com.taosdata.jdbc.utils; + +public class OSUtils { + private static final String OS = System.getProperty("os.name").toLowerCase(); + + public static boolean isWindows() { + return OS.indexOf("win") >= 0; + } + + public static boolean isMac() { + return OS.indexOf("mac") >= 0; + } + + public static boolean isLinux() { + return OS.indexOf("nux") >= 0; + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DriverAutoloadTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DriverAutoloadTest.java index 580b2ac1b5..9826e6ed76 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DriverAutoloadTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DriverAutoloadTest.java @@ -17,7 +17,6 @@ public class DriverAutoloadTest { @Test public void testRestful() throws SQLException { -// Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; Connection conn = DriverManager.getConnection(url, properties); Assert.assertNotNull(conn); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java new file mode 100644 index 0000000000..f2ac94adc1 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java @@ -0,0 +1,64 @@ +package com.taosdata.jdbc.cases; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; + +public class NullValueInResultSetForJdbcRestfulTest { + + private static final String host = "127.0.0.1"; + Connection conn; + + @Test + public void test() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from weather"); + ResultSetMetaData meta = rs.getMetaData(); + while (rs.next()) { + for (int i = 1; i <= meta.getColumnCount(); i++) { + Object value = rs.getObject(i); + System.out.print(meta.getColumnLabel(i) + ": " + value + "\t"); + } + System.out.println(); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Before + public void before() throws SQLException { + final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; + conn = DriverManager.getConnection(url); + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop database if exists test_null"); + stmt.execute("create database if not exists test_null"); + stmt.execute("use test_null"); + stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64))"); + stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, 1)"); + stmt.executeUpdate("insert into weather(ts, f2) values(now+2s, 2)"); + stmt.executeUpdate("insert into weather(ts, f3) values(now+3s, 3.0)"); + stmt.executeUpdate("insert into weather(ts, f4) values(now+4s, 4.0)"); + stmt.executeUpdate("insert into weather(ts, f5) values(now+5s, 5)"); + stmt.executeUpdate("insert into weather(ts, f6) values(now+6s, 6)"); + stmt.executeUpdate("insert into weather(ts, f7) values(now+7s, true)"); + stmt.executeUpdate("insert into weather(ts, f8) values(now+8s, 'hello')"); + stmt.executeUpdate("insert into weather(ts, f9) values(now+9s, '涛思数据')"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + if (conn != null) + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/OSUtilsTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/OSUtilsTest.java new file mode 100644 index 0000000000..fd6c83ad1c --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/OSUtilsTest.java @@ -0,0 +1,30 @@ +package com.taosdata.jdbc.utils; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class OSUtilsTest { + + private String OS; + + @Test + public void inWindows() { + Assert.assertEquals(OS.indexOf("win") >= 0, OSUtils.isWindows()); + } + + @Test + public void isMac() { + Assert.assertEquals(OS.indexOf("mac") >= 0, OSUtils.isMac()); + } + + @Test + public void isLinux() { + Assert.assertEquals(OS.indexOf("nux") >= 0, OSUtils.isLinux()); + } + + @Before + public void before() { + OS = System.getProperty("os.name").toLowerCase(); + } +} \ No newline at end of file diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c index fb0c1508cb..fb683786ad 100644 --- a/src/cq/src/cqMain.c +++ b/src/cq/src/cqMain.c @@ -73,6 +73,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row); static void cqCreateStream(SCqContext *pContext, SCqObj *pObj); int32_t cqObjRef = -1; +int32_t cqVnodeNum = 0; void cqRmFromList(SCqObj *pObj) { //LOCK in caller @@ -166,6 +167,8 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) { return NULL; } + atomic_add_fetch_32(&cqVnodeNum, 1); + cqCreateRef(); pContext->tmrCtrl = taosTmrInit(0, 0, 0, "CQ"); @@ -240,6 +243,13 @@ void cqClose(void *handle) { if (hasCq == 0) { freeSCqContext(pContext); } + + int32_t remainn = atomic_sub_fetch_32(&cqVnodeNum, 1); + if (remainn <= 0) { + int32_t ref = cqObjRef; + cqObjRef = -1; + taosCloseRef(ref); + } } void cqStart(void *handle) { @@ -294,14 +304,29 @@ void cqStop(void *handle) { pthread_mutex_unlock(&pContext->mutex); } -void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, char *sqlStr, STSchema *pSchema) { +void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, char *sqlStr, STSchema *pSchema, int start) { if (tsEnableStream == 0) { return NULL; } SCqContext *pContext = handle; int64_t rid = 0; + + pthread_mutex_lock(&pContext->mutex); + + SCqObj *pObj = pContext->pHead; + while (pObj) { + if (pObj->uid == uid) { + rid = pObj->rid; + pthread_mutex_unlock(&pContext->mutex); + return (void *)rid; + } + + pObj = pObj->next; + } - SCqObj *pObj = calloc(sizeof(SCqObj), 1); + pthread_mutex_unlock(&pContext->mutex); + + pObj = calloc(sizeof(SCqObj), 1); if (pObj == NULL) return NULL; pObj->uid = uid; @@ -326,7 +351,11 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch pObj->rid = taosAddRef(cqObjRef, pObj); - cqCreateStream(pContext, pObj); + if(start && pContext->master) { + cqCreateStream(pContext, pObj); + } else { + pObj->pContext = pContext; + } rid = pObj->rid; @@ -372,12 +401,15 @@ static void doCreateStream(void *param, TAOS_RES *result, int32_t code) { if (pObj == NULL) { return; } - + SCqContext* pContext = pObj->pContext; - SSqlObj* pSql = (SSqlObj*)result; - if (atomic_val_compare_exchange_ptr(&(pContext->dbConn), NULL, pSql->pTscObj) != NULL) { - taos_close(pSql->pTscObj); + SSqlObj* pSql = (SSqlObj*)result; + if (code == TSDB_CODE_SUCCESS) { + if (atomic_val_compare_exchange_ptr(&(pContext->dbConn), NULL, pSql->pTscObj) != NULL) { + taos_close(pSql->pTscObj); + } } + pthread_mutex_lock(&pContext->mutex); cqCreateStream(pContext, pObj); pthread_mutex_unlock(&pContext->mutex); @@ -413,6 +445,7 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { pObj->tmrId = taosTmrStart(cqProcessCreateTimer, 1000, (void *)pObj->rid, pContext->tmrCtrl); return; } + pObj->tmrId = 0; if (pObj->pStream == NULL) { diff --git a/src/cq/test/cqtest.c b/src/cq/test/cqtest.c index f378835f0a..b1153397ba 100644 --- a/src/cq/test/cqtest.c +++ b/src/cq/test/cqtest.c @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { tdDestroyTSchemaBuilder(&schemaBuilder); for (int sid =1; sid<10; ++sid) { - cqCreate(pCq, sid, sid, NULL, "select avg(speed) from demo.t1 sliding(1s) interval(5s)", pSchema); + cqCreate(pCq, sid, sid, NULL, "select avg(speed) from demo.t1 sliding(1s) interval(5s)", pSchema, 1); } tdFreeSchema(pSchema); diff --git a/src/dnode/src/dnodeCfg.c b/src/dnode/src/dnodeCfg.c index fd5956b37f..c573d709f5 100644 --- a/src/dnode/src/dnodeCfg.c +++ b/src/dnode/src/dnodeCfg.c @@ -17,6 +17,7 @@ #include "os.h" #include "cJSON.h" #include "dnodeCfg.h" +#include "tglobal.h" static SDnodeCfg tsCfg = {0}; static pthread_mutex_t tsCfgMutex; @@ -70,6 +71,7 @@ static void dnodeResetCfg(SDnodeCfg *cfg) { pthread_mutex_lock(&tsCfgMutex); tsCfg.dnodeId = cfg->dnodeId; + tsDnodeId = cfg->dnodeId; tstrncpy(tsCfg.clusterId, cfg->clusterId, TSDB_CLUSTER_ID_LEN); dnodePrintCfg(cfg); dnodeWriteCfg(); diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c index 2cd5c637e5..410e6bb188 100644 --- a/src/dnode/src/dnodeMain.c +++ b/src/dnode/src/dnodeMain.c @@ -237,6 +237,20 @@ static int32_t dnodeInitStorage() { return -1; } + TDIR *tdir = tfsOpendir("vnode_bak/.staging"); + bool stagingNotEmpty = tfsReaddir(tdir) != NULL; + tfsClosedir(tdir); + + if (stagingNotEmpty) { + dError("vnode_bak/.staging dir not empty, fix it first."); + return -1; + } + + if (tfsMkdir("vnode_bak/.staging") < 0) { + dError("failed to create vnode_bak/.staging dir since %s", tstrerror(terrno)); + return -1; + } + dnodeCheckDataDirOpenned(tsDnodeDir); dInfo("dnode storage is initialized at %s", tsDnodeDir); diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c index 87b31e4604..26084a52eb 100644 --- a/src/dnode/src/dnodeVWrite.c +++ b/src/dnode/src/dnodeVWrite.c @@ -205,7 +205,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) { pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead.msgType], qtypeStr[qtype], pWrite->pHead.version); pWrite->code = vnodeProcessWrite(pVnode, &pWrite->pHead, qtype, pWrite); - if (pWrite->code <= 0) pWrite->processedCount = 1; + if (pWrite->code <= 0) atomic_add_fetch_32(&pWrite->processedCount, 1); if (pWrite->code > 0) pWrite->code = 0; if (pWrite->code == 0 && pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true; @@ -222,7 +222,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) { dnodeSendRpcVWriteRsp(pVnode, pWrite, pWrite->code); } else { if (qtype == TAOS_QTYPE_FWD) { - vnodeConfirmForward(pVnode, pWrite->pHead.version, 0, pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT); + vnodeConfirmForward(pVnode, pWrite->pHead.version, pWrite->code, pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT); } if (pWrite->rspRet.rsp) { rpcFreeCont(pWrite->rspRet.rsp); diff --git a/src/inc/query.h b/src/inc/query.h index c9dabcef54..38078cf21f 100644 --- a/src/inc/query.h +++ b/src/inc/query.h @@ -88,10 +88,11 @@ void* qOpenQueryMgmt(int32_t vgId); void qQueryMgmtNotifyClosed(void* pExecutor); void qQueryMgmtReOpen(void *pExecutor); void qCleanupQueryMgmt(void* pExecutor); -void** qRegisterQInfo(void* pMgmt, uint64_t qId, uint64_t qInfo); +void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo); void** qAcquireQInfo(void* pMgmt, uint64_t key); void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle); bool checkQIdEqual(void *qHandle, uint64_t qId); +int64_t genQueryId(void); #ifdef __cplusplus } diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 252e37a5d9..024bc198df 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -259,7 +259,7 @@ do { \ #define TSDB_MIN_TABLES 4 #define TSDB_MAX_TABLES 10000000 #define TSDB_DEFAULT_TABLES 1000000 -#define TSDB_TABLES_STEP 100 +#define TSDB_TABLES_STEP 1000 #define TSDB_MIN_DAYS_PER_FILE 1 #define TSDB_MAX_DAYS_PER_FILE 3650 diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 8daccee1f2..eff4eecbc1 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -163,6 +163,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0362) //"Table does not exist") #define TSDB_CODE_MND_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0363) //"Invalid table type in tsdb") #define TSDB_CODE_MND_TOO_MANY_TAGS TAOS_DEF_ERROR_CODE(0, 0x0364) //"Too many tags") +#define TSDB_CODE_MND_TOO_MANY_COLUMNS TAOS_DEF_ERROR_CODE(0, 0x0365) //"Too many columns") #define TSDB_CODE_MND_TOO_MANY_TIMESERIES TAOS_DEF_ERROR_CODE(0, 0x0366) //"Too many time series") #define TSDB_CODE_MND_NOT_SUPER_TABLE TAOS_DEF_ERROR_CODE(0, 0x0367) //"Not super table") // operation only available for super table #define TSDB_CODE_MND_COL_NAME_TOO_LONG TAOS_DEF_ERROR_CODE(0, 0x0368) //"Tag name too long") diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 99f4e1518f..d7ac7dd277 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -399,36 +399,6 @@ typedef struct SColIndex { char name[TSDB_COL_NAME_LEN]; // TODO remove it } SColIndex; -/* sql function msg, to describe the message to vnode about sql function - * operations in select clause */ -typedef struct SSqlFuncMsg { - int16_t functionId; - int16_t numOfParams; - - int16_t resColId; // result column id, id of the current output column - int16_t colType; - int16_t colBytes; - - SColIndex colInfo; - struct ArgElem { - int16_t argType; - int16_t argBytes; - union { - double d; - int64_t i64; - char * pz; - } argValue; - } arg[3]; -} SSqlFuncMsg; - -typedef struct SExprInfo { - SSqlFuncMsg base; - struct tExprNode* pExpr; - int16_t bytes; - int16_t type; - int32_t interBytes; - int64_t uid; -} SExprInfo; typedef struct SColumnFilterInfo { int16_t lowerRelOptr; @@ -451,6 +421,42 @@ typedef struct SColumnFilterInfo { }; } SColumnFilterInfo; +/* sql function msg, to describe the message to vnode about sql function + * operations in select clause */ +typedef struct SSqlFuncMsg { + int16_t functionId; + int16_t numOfParams; + + int16_t resColId; // result column id, id of the current output column + int16_t colType; + int16_t colBytes; + + SColIndex colInfo; + struct ArgElem { + int16_t argType; + int16_t argBytes; + union { + double d; + int64_t i64; + char * pz; + } argValue; + } arg[3]; + + int32_t filterNum; + SColumnFilterInfo filterInfo[]; +} SSqlFuncMsg; + + +typedef struct SExprInfo { + SColumnFilterInfo * pFilter; + struct tExprNode* pExpr; + int16_t bytes; + int16_t type; + int32_t interBytes; + int64_t uid; + SSqlFuncMsg base; +} SExprInfo; + /* * for client side struct, we only need the column id, type, bytes are not necessary * But for data in vnode side, we need all the following information. diff --git a/src/inc/tcq.h b/src/inc/tcq.h index 1941649d0a..552a40665a 100644 --- a/src/inc/tcq.h +++ b/src/inc/tcq.h @@ -42,7 +42,7 @@ void cqStart(void *handle); void cqStop(void *handle); // cqCreate is called by TSDB to start an instance of CQ -void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, char *sqlStr, STSchema *pSchema); +void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, char *sqlStr, STSchema *pSchema, int start); // cqDrop is called by TSDB to stop an instance of CQ, handle is the return value of cqCreate void cqDrop(void *handle); diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 495bfa2384..85ee9f0443 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -51,7 +51,7 @@ typedef struct { void *cqH; int (*notifyStatus)(void *, int status, int eno); int (*eventCallBack)(void *); - void *(*cqCreateFunc)(void *handle, uint64_t uid, int32_t sid, const char *dstTable, char *sqlStr, STSchema *pSchema); + void *(*cqCreateFunc)(void *handle, uint64_t uid, int32_t sid, const char *dstTable, char *sqlStr, STSchema *pSchema, int start); void (*cqDropFunc)(void *handle); } STsdbAppH; diff --git a/src/inc/tsync.h b/src/inc/tsync.h index 99dfd3a6a3..d1b68e3f5a 100644 --- a/src/inc/tsync.h +++ b/src/inc/tsync.h @@ -79,9 +79,6 @@ typedef void (*FStopSyncFile)(int32_t vgId, uint64_t fversion); // get file version typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver); -// reset version -typedef int32_t (*FResetVersion)(int32_t vgId, uint64_t fver); - typedef int32_t (*FSendFile)(void *tsdb, SOCKET socketFd); typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd); @@ -99,7 +96,6 @@ typedef struct { FStartSyncFile startSyncFileFp; FStopSyncFile stopSyncFileFp; FGetVersion getVersionFp; - FResetVersion resetVersionFp; FSendFile sendFileFp; FRecvFile recvFileFp; } SSyncInfo; diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index e9f95660f7..5f47d9896f 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -205,6 +205,11 @@ #define TK_VALUES 186 + + + + + #define TK_SPACE 300 #define TK_COMMENT 301 #define TK_ILLEGAL 302 diff --git a/src/kit/shell/inc/shell.h b/src/kit/shell/inc/shell.h index d0b7149541..2374150c52 100644 --- a/src/kit/shell/inc/shell.h +++ b/src/kit/shell/inc/shell.h @@ -27,7 +27,7 @@ #define MAX_IP_SIZE 20 #define MAX_PASSWORD_SIZE 20 #define MAX_HISTORY_SIZE 1000 -#define MAX_COMMAND_SIZE 65536 +#define MAX_COMMAND_SIZE 1048586 #define HISTORY_FILE ".taos_history" #define DEFAULT_RES_SHOW_NUM 100 diff --git a/src/kit/shell/src/shellCommand.c b/src/kit/shell/src/shellCommand.c index 16545a5fe8..9173ab0efd 100644 --- a/src/kit/shell/src/shellCommand.c +++ b/src/kit/shell/src/shellCommand.c @@ -238,7 +238,7 @@ void resetCommand(Command *cmd, const char s[]) { clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size); memset(cmd->buffer, 0, MAX_COMMAND_SIZE); memset(cmd->command, 0, MAX_COMMAND_SIZE); - strcpy(cmd->command, s); + strncpy(cmd->command, s, MAX_COMMAND_SIZE); int size = 0; int width = 0; getMbSizeInfo(s, &size, &width); diff --git a/src/kit/shell/src/shellWindows.c b/src/kit/shell/src/shellWindows.c index 11c1ac34d8..87d11a3516 100644 --- a/src/kit/shell/src/shellWindows.c +++ b/src/kit/shell/src/shellWindows.c @@ -199,15 +199,19 @@ void updateBuffer(Command *cmd) { } int isReadyGo(Command *cmd) { - char total[MAX_COMMAND_SIZE]; + char *total = malloc(MAX_COMMAND_SIZE); memset(total, 0, MAX_COMMAND_SIZE); sprintf(total, "%s%s", cmd->buffer, cmd->command); char *reg_str = "(^.*;\\s*$)|(^\\s*$)|(^\\s*exit\\s*$)|(^\\s*q\\s*$)|(^\\s*quit\\s*$)|(^" "\\s*clear\\s*$)"; - if (regex_match(total, reg_str, REG_EXTENDED | REG_ICASE)) return 1; + if (regex_match(total, reg_str, REG_EXTENDED | REG_ICASE)) { + free(total); + return 1; + } + free(total); return 0; } diff --git a/src/kit/taosdemo/CMakeLists.txt b/src/kit/taosdemo/CMakeLists.txt index ba27044a87..4e38a8842e 100644 --- a/src/kit/taosdemo/CMakeLists.txt +++ b/src/kit/taosdemo/CMakeLists.txt @@ -9,19 +9,18 @@ IF (GIT_FOUND) EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} log --pretty=oneline -n 1 ${CMAKE_CURRENT_LIST_DIR}/taosdemo.c RESULT_VARIABLE RESULT - OUTPUT_VARIABLE TAOSDEMO_COMMIT) - EXECUTE_PROCESS( - COMMAND bash "-c" "echo '${TAOSDEMO_COMMIT}' | awk '{print $1}' | cut -c -9" - RESULT_VARIABLE RESULT OUTPUT_VARIABLE TAOSDEMO_COMMIT_SHA1) + STRING(SUBSTRING "${TAOSDEMO_COMMIT_SHA1}" 0 7 TAOSDEMO_COMMIT_SHA1) EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} status -z -s ${CMAKE_CURRENT_LIST_DIR}/taosdemo.c RESULT_VARIABLE RESULT OUTPUT_VARIABLE TAOSDEMO_STATUS) - EXECUTE_PROCESS( + IF (TD_LINUX) + EXECUTE_PROCESS( COMMAND bash "-c" "echo '${TAOSDEMO_STATUS}' | awk '{print $1}'" RESULT_VARIABLE RESULT OUTPUT_VARIABLE TAOSDEMO_STATUS) + ENDIF (TD_LINUX) MESSAGE("taosdemo.c status: " ${TAOSDEMO_STATUS}) ELSE() MESSAGE("Git not found") @@ -29,9 +28,9 @@ ELSE() SET(TAOSDEMO_STATUS "unknown") ENDIF (GIT_FOUND) -STRING(STRIP ${TAOSDEMO_COMMIT_SHA1} TAOSDEMO_COMMIT_SHA1) +STRING(STRIP "${TAOSDEMO_COMMIT_SHA1}" TAOSDEMO_COMMIT_SHA1) MESSAGE("taosdemo's latest commit in short is:" ${TAOSDEMO_COMMIT_SHA1}) -STRING(STRIP ${TAOSDEMO_STATUS} TAOSDEMO_STATUS) +STRING(STRIP "${TAOSDEMO_STATUS}" TAOSDEMO_STATUS) IF (TAOSDEMO_STATUS MATCHES "M") SET(TAOSDEMO_STATUS "modified") diff --git a/src/kit/taosdemo/insert-interlace.json b/src/kit/taosdemo/insert-interlace.json index 344db4fd00..cf3e1de2f4 100644 --- a/src/kit/taosdemo/insert-interlace.json +++ b/src/kit/taosdemo/insert-interlace.json @@ -40,7 +40,6 @@ "data_source": "rand", "insert_mode": "taosc", "insert_rows": 1000, - "multi_thread_write_one_tbl": "no", "interlace_rows": 20, "max_sql_len": 1024000, "disorder_ratio": 0, diff --git a/src/kit/taosdemo/insert.json b/src/kit/taosdemo/insert.json index f0e3ab1d50..5f152a2d0c 100644 --- a/src/kit/taosdemo/insert.json +++ b/src/kit/taosdemo/insert.json @@ -40,7 +40,6 @@ "data_source": "rand", "insert_mode": "taosc", "insert_rows": 100000, - "multi_thread_write_one_tbl": "no", "interlace_rows": 0, "max_sql_len": 1024000, "disorder_ratio": 0, diff --git a/src/kit/taosdemo/query.json b/src/kit/taosdemo/query.json index 33ac120bda..d84f997c32 100644 --- a/src/kit/taosdemo/query.json +++ b/src/kit/taosdemo/query.json @@ -1,5 +1,5 @@ { - "filetype":"query", + "filetype": "query", "cfgdir": "/etc/taos", "host": "127.0.0.1", "port": 6030, @@ -7,13 +7,30 @@ "password": "taosdata", "confirm_parameter_prompt": "yes", "databases": "dbx", - "specified_table_query": - {"query_interval":1, "concurrent":4, - "sqls": [{"sql": "select last_row(*) from stb where color='red'", "result": "./query_res0.txt"}, - {"sql": "select count(*) from stb_01", "result": "./query_res1.txt"}] - }, - "super_table_query": - {"stblname": "stb", "query_interval":1, "threads":4, - "sqls": [{"sql": "select last_row(*) from xxxx", "result": "./query_res2.txt"}] - } + "query_times": 1, + "specified_table_query": { + "query_interval": 1, + "concurrent": 4, + "sqls": [ + { + "sql": "select last_row(*) from stb where color='red'", + "result": "./query_res0.txt" + }, + { + "sql": "select count(*) from stb_01", + "result": "./query_res1.txt" + } + ] + }, + "super_table_query": { + "stblname": "stb", + "query_interval": 1, + "threads": 4, + "sqls": [ + { + "sql": "select last_row(*) from xxxx", + "result": "./query_res2.txt" + } + ] + } } diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 3725712339..1bb9b8767a 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -18,6 +18,7 @@ when in some thread query return error, thread don't exit, but return, otherwise coredump in other thread. */ +#include #define _GNU_SOURCE #define CURL_STATICLIB @@ -67,6 +68,12 @@ enum TEST_MODE { INVAID_TEST }; +enum QUERY_MODE { + SYNC_QUERY_MODE, // 0 + ASYNC_QUERY_MODE, // 1 + INVALID_MODE +}; + #define MAX_SQL_SIZE 65536 #define BUFFER_SIZE (65536*2) #define MAX_USERNAME_SIZE 64 @@ -85,7 +92,7 @@ enum TEST_MODE { #define MAX_NUM_DATATYPE 10 #define MAX_DB_COUNT 8 -#define MAX_SUPER_TABLE_COUNT 8 +#define MAX_SUPER_TABLE_COUNT 200 #define MAX_COLUMN_COUNT 1024 #define MAX_TAG_COUNT 128 @@ -124,7 +131,7 @@ typedef enum enum_INSERT_MODE { typedef enum enumQUERY_TYPE { NO_INSERT_TYPE, - INSERT_TYPE, + INSERT_TYPE, QUERY_TYPE_BUT } QUERY_TYPE; @@ -198,7 +205,7 @@ typedef struct SArguments_S { bool verbose_print; bool performance_print; char * output_file; - int mode; + int query_mode; char * datatype[MAX_NUM_DATATYPE + 1]; int len_of_binary; int num_of_CPR; @@ -211,8 +218,8 @@ typedef struct SArguments_S { int num_of_tables; int num_of_DPT; int abort; - int disorderRatio; - int disorderRange; + int disorderRatio; // 0: no disorder, >0: x% + int disorderRange; // ms or us by database precision int method_of_delete; char ** arg_list; int64_t totalInsertRows; @@ -229,25 +236,25 @@ typedef struct SColumn_S { typedef struct SSuperTable_S { char sTblName[MAX_TB_NAME_SIZE+1]; int childTblCount; - bool childTblExists; // 0: no, 1: yes - int batchCreateTableNum; // 0: no batch, > 0: batch table number in one sql - int8_t autoCreateTable; // 0: create sub table, 1: auto create sub table + bool childTblExists; // 0: no, 1: yes + int batchCreateTableNum; // 0: no batch, > 0: batch table number in one sql + int8_t autoCreateTable; // 0: create sub table, 1: auto create sub table char childTblPrefix[MAX_TB_NAME_SIZE]; char dataSource[MAX_TB_NAME_SIZE+1]; // rand_gen or sample - char insertMode[MAX_TB_NAME_SIZE]; // taosc, restful + char insertMode[MAX_TB_NAME_SIZE]; // taosc, restful int childTblLimit; int childTblOffset; - int multiThreadWriteOneTbl; // 0: no, 1: yes - int interlaceRows; // - int disorderRatio; // 0: no disorder, >0: x% - int disorderRange; // ms or us by database precision - int maxSqlLen; // + int multiThreadWriteOneTbl; // 0: no, 1: yes + int interlaceRows; // + int disorderRatio; // 0: no disorder, >0: x% + int disorderRange; // ms or us by database precision + int maxSqlLen; // int insertInterval; // insert interval, will override global insert interval - int64_t insertRows; // 0: no limit + int64_t insertRows; // 0: no limit int timeStampStep; - char startTimestamp[MAX_TB_NAME_SIZE]; // + char startTimestamp[MAX_TB_NAME_SIZE]; char sampleFormat[MAX_TB_NAME_SIZE]; // csv, json char sampleFile[MAX_FILE_NAME_LEN+1]; char tagsFile[MAX_FILE_NAME_LEN+1]; @@ -263,7 +270,6 @@ typedef struct SSuperTable_S { int lenOfTagOfOneRow; char* sampleDataBuf; - int sampleDataBufSize; //int sampleRowCount; //int sampleUsePos; @@ -352,7 +358,7 @@ typedef struct SpecifiedQueryInfo_S { int rate; // 0: unlimit > 0 loop/s int concurrent; int sqlCount; - int subscribeMode; // 0: sync, 1: async + int mode; // 0: sync, 1: async int subscribeInterval; // ms int queryTimes; int subscribeRestart; @@ -360,13 +366,14 @@ typedef struct SpecifiedQueryInfo_S { char sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1]; char result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1]; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT]; + int totalQueried; } SpecifiedQueryInfo; typedef struct SuperQueryInfo_S { char sTblName[MAX_TB_NAME_SIZE+1]; int rate; // 0: unlimit > 0 loop/s int threadCnt; - int subscribeMode; // 0: sync, 1: async + int mode; // 0: sync, 1: async int subscribeInterval; // ms int subscribeRestart; int subscribeKeepProgress; @@ -379,6 +386,7 @@ typedef struct SuperQueryInfo_S { TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT]; char* childTblName; + int totalQueried; } SuperQueryInfo; typedef struct SQueryMetaInfo_S { @@ -392,6 +400,7 @@ typedef struct SQueryMetaInfo_S { SpecifiedQueryInfo specifiedQueryInfo; SuperQueryInfo superQueryInfo; + int totalQueried; } SQueryMetaInfo; typedef struct SThreadInfo_S { @@ -430,6 +439,8 @@ typedef struct SThreadInfo_S { int64_t maxDelay; int64_t minDelay; + // query + int querySeq; // sequence number of sql command } threadInfo; #ifdef WINDOWS @@ -488,7 +499,7 @@ static int taosRandom() return number; } -#else +#else // Not windows static void setupForAnsiEscape(void) {} static void resetAfterAnsiEscape(void) { @@ -500,13 +511,12 @@ static void resetAfterAnsiEscape(void) { static int taosRandom() { - srand(time(NULL)); return rand(); } -#endif +#endif // ifdef Windows -static int createDatabases(); +static int createDatabasesAndStables(); static void createChildTables(); static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet); @@ -539,7 +549,7 @@ SArguments g_args = { true, // insert_only false, // debug_print false, // verbose_print - false, // performance statistic print + false, // performance statistic print false, // answer_yes; "./output.txt", // output_file 0, // mode : sync or async @@ -641,7 +651,7 @@ static void printHelp() { "The password to use when connecting to the server. Default is 'taosdata'."); printf("%s%s%s%s\n", indent, "-c", indent, "Configuration directory. Default is '/etc/taos/'."); -#endif +#endif printf("%s%s%s%s\n", indent, "-h", indent, "The host to connect to TDengine. Default is localhost."); printf("%s%s%s%s\n", indent, "-p", indent, @@ -677,33 +687,26 @@ static void printHelp() { printf("%s%s%s%s\n", indent, "-x", indent, "Not insert only flag."); printf("%s%s%s%s\n", indent, "-y", indent, "Default input yes for prompt."); printf("%s%s%s%s\n", indent, "-O", indent, - "Insert mode--0: In order, > 0: disorder ratio. Default is in order."); + "Insert mode--0: In order, 1 ~ 50: disorder ratio. Default is in order."); printf("%s%s%s%s\n", indent, "-R", indent, "Out of order data's range, ms, default is 1000."); printf("%s%s%s%s\n", indent, "-g", indent, "Print debug info."); printf("%s%s%s%s\n", indent, "-V, --version", indent, "Print version info."); -/* printf("%s%s%s%s\n", indent, "-D", indent, +/* printf("%s%s%s%s\n", indent, "-D", indent, "if elete database if exists. 0: no, 1: yes, default is 1"); */ } static void parse_args(int argc, char *argv[], SArguments *arguments) { char **sptr; - wordexp_t full_path; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-f") == 0) { arguments->metaFile = argv[++i]; } else if (strcmp(argv[i], "-c") == 0) { - char *configPath = argv[++i]; - if (wordexp(configPath, &full_path, 0) != 0) { - errorPrint( "Invalid path %s\n", configPath); - return; - } - taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]); - wordfree(&full_path); + tstrncpy(configDir, argv[++i], MAX_FILE_NAME_LEN); } else if (strcmp(argv[i], "-h") == 0) { arguments->host = argv[++i]; @@ -718,7 +721,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (strcmp(argv[i], "-s") == 0) { arguments->sqlFile = argv[++i]; } else if (strcmp(argv[i], "-q") == 0) { - arguments->mode = atoi(argv[++i]); + arguments->query_mode = atoi(argv[++i]); } else if (strcmp(argv[i], "-T") == 0) { arguments->num_of_threads = atoi(argv[++i]); } else if (strcmp(argv[i], "-i") == 0) { @@ -749,7 +752,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { && strcasecmp(argv[i], "SMALLINT") && strcasecmp(argv[i], "BIGINT") && strcasecmp(argv[i], "DOUBLE") - && strcasecmp(argv[i], "BINARY") + && strcasecmp(argv[i], "BINARY") && strcasecmp(argv[i], "NCHAR")) { printHelp(); ERROR_EXIT( "Invalid data_type!\n"); @@ -762,7 +765,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { char *dupstr = strdup(argv[i]); char *running = dupstr; char *token = strsep(&running, ","); - while (token != NULL) { + while(token != NULL) { if (strcasecmp(token, "INT") && strcasecmp(token, "FLOAT") && strcasecmp(token, "TINYINT") @@ -773,6 +776,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { && strcasecmp(token, "BINARY") && strcasecmp(token, "NCHAR")) { printHelp(); + free(dupstr); ERROR_EXIT("Invalid data_type!\n"); exit(EXIT_FAILURE); } @@ -780,6 +784,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { token = strsep(&running, ","); if (index >= MAX_NUM_DATATYPE) break; } + free(dupstr); sptr[index] = NULL; } } else if (strcmp(argv[i], "-w") == 0) { @@ -798,23 +803,22 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { arguments->verbose_print = true; } else if (strcmp(argv[i], "-pp") == 0) { arguments->performance_print = true; - } else if (strcmp(argv[i], "-c") == 0) { - strcpy(configDir, argv[++i]); } else if (strcmp(argv[i], "-O") == 0) { + arguments->disorderRatio = atoi(argv[++i]); - if (arguments->disorderRatio > 1 - || arguments->disorderRatio < 0) { + + if (arguments->disorderRatio > 50) + arguments->disorderRatio = 50; + + if (arguments->disorderRatio < 0) arguments->disorderRatio = 0; - } else if (arguments->disorderRatio == 1) { - arguments->disorderRange = 10; - } + } else if (strcmp(argv[i], "-R") == 0) { + arguments->disorderRange = atoi(argv[++i]); - if (arguments->disorderRange == 1 - && (arguments->disorderRange > 50 - || arguments->disorderRange <= 0)) { - arguments->disorderRange = 10; - } + if (arguments->disorderRange < 0) + arguments->disorderRange = 1000; + } else if (strcmp(argv[i], "-a") == 0) { arguments->replica = atoi(argv[++i]); if (arguments->replica > 3 || arguments->replica < 1) { @@ -967,7 +971,7 @@ static void getResult(TAOS_RES *res, char* resultFileName) { char temp[16000]; // fetch the records row by row - while ((row = taos_fetch_row(res))) { + while((row = taos_fetch_row(res))) { if (totalLen >= 100*1024*1024 - 32000) { if (fp) fprintf(fp, "%s", databuf); totalLen = 0; @@ -989,7 +993,8 @@ static void getResult(TAOS_RES *res, char* resultFileName) { static void selectAndGetResult(TAOS *taos, char *command, char* resultFileName) { TAOS_RES *res = taos_query(taos, command); if (res == NULL || taos_errno(res) != 0) { - printf("failed to sql:%s, reason:%s\n", command, taos_errstr(res)); + errorPrint("%s() LN%d, failed to execute sql:%s, reason:%s\n", + __func__, __LINE__, command, taos_errstr(res)); taos_free_result(res); return; } @@ -998,8 +1003,9 @@ static void selectAndGetResult(TAOS *taos, char *command, char* resultFileName) taos_free_result(res); } -static double getCurrentTime() { +static double getCurrentTimeUs() { struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { perror("Failed to get current time in ms"); return 0.0; @@ -1057,7 +1063,7 @@ static void rand_string(char *str, int size) { //--size; int n; for (n = 0; n < size - 1; n++) { - int key = rand_tinyint() % (int)(sizeof(charset) - 1); + int key = abs(rand_tinyint()) % (int)(sizeof(charset) - 1); str[n] = charset[key]; } str[n] = 0; @@ -1107,6 +1113,7 @@ static int printfInsertMeta() { printf("host: \033[33m%s:%u\033[0m\n", g_Dbs.host, g_Dbs.port); printf("user: \033[33m%s\033[0m\n", g_Dbs.user); printf("password: \033[33m%s\033[0m\n", g_Dbs.password); + printf("configDir: \033[33m%s\033[0m\n", configDir); printf("resultFile: \033[33m%s\033[0m\n", g_Dbs.resultFile); printf("thread num of insert data: \033[33m%d\033[0m\n", g_Dbs.threadCount); printf("thread num of create table: \033[33m%d\033[0m\n", g_Dbs.threadCountByCreateTbl); @@ -1164,7 +1171,8 @@ static int printfInsertMeta() { if (g_Dbs.db[i].dbCfg.precision[0] != 0) { if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2)) || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) { - printf(" precision: \033[33m%s\033[0m\n", g_Dbs.db[i].dbCfg.precision); + printf(" precision: \033[33m%s\033[0m\n", + g_Dbs.db[i].dbCfg.precision); } else { printf("\033[1m\033[40;31m precision error: %s\033[0m\n", g_Dbs.db[i].dbCfg.precision); @@ -1172,11 +1180,13 @@ static int printfInsertMeta() { } } - printf(" super table count: \033[33m%d\033[0m\n", g_Dbs.db[i].superTblCount); + printf(" super table count: \033[33m%d\033[0m\n", + g_Dbs.db[i].superTblCount); for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { printf(" super table[\033[33m%d\033[0m]:\n", j); - printf(" stbName: \033[33m%s\033[0m\n", g_Dbs.db[i].superTbls[j].sTblName); + printf(" stbName: \033[33m%s\033[0m\n", + g_Dbs.db[i].superTbls[j].sTblName); if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) { printf(" autoCreateTable: \033[33m%s\033[0m\n", "no"); @@ -1242,7 +1252,7 @@ static int printfInsertMeta() { g_Dbs.db[i].superTbls[j].sampleFile); printf(" tagsFile: \033[33m%s\033[0m\n", g_Dbs.db[i].superTbls[j].tagsFile); - printf(" columnCount: \033[33m%d\033[0m\n ", + printf(" columnCount: \033[33m%d\033[0m\n", g_Dbs.db[i].superTbls[j].columnCount); for (int k = 0; k < g_Dbs.db[i].superTbls[j].columnCount; k++) { //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen); @@ -1292,6 +1302,7 @@ static void printfInsertMetaToFile(FILE* fp) { fprintf(fp, "host: %s:%u\n", g_Dbs.host, g_Dbs.port); fprintf(fp, "user: %s\n", g_Dbs.user); + fprintf(fp, "configDir: %s\n", configDir); fprintf(fp, "resultFile: %s\n", g_Dbs.resultFile); fprintf(fp, "thread num of insert data: %d\n", g_Dbs.threadCount); fprintf(fp, "thread num of create table: %d\n", g_Dbs.threadCountByCreateTbl); @@ -1459,41 +1470,61 @@ static void printfQueryMeta() { printf("\n"); printf("specified table query info: \n"); - printf("query interval: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.rate); + printf("query interval: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.rate); printf("top query times:\033[33m%d\033[0m\n", g_args.query_times); - printf("concurrent: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.concurrent); - printf("sqlCount: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.sqlCount); + printf("concurrent: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.concurrent); + printf("sqlCount: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.sqlCount); printf("specified tbl query times:\n"); - printf(" \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.queryTimes); + printf(" \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.queryTimes); if (SUBSCRIBE_TEST == g_args.test_mode) { - printf("mod: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeMode); - printf("interval: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeInterval); - printf("restart: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeRestart); - printf("keepProgress: \033[33m%d\033[0m\n", g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); + printf("mod: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.mode); + printf("interval: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.subscribeInterval); + printf("restart: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.subscribeRestart); + printf("keepProgress: \033[33m%d\033[0m\n", + g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); } for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - printf(" sql[%d]: \033[33m%s\033[0m\n", i, g_queryInfo.specifiedQueryInfo.sql[i]); + printf(" sql[%d]: \033[33m%s\033[0m\n", + i, g_queryInfo.specifiedQueryInfo.sql[i]); } printf("\n"); - printf("super table query info: \n"); - printf("query interval: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.rate); - printf("threadCnt: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.threadCnt); - printf("childTblCount: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.childTblCount); - printf("stable name: \033[33m%s\033[0m\n", g_queryInfo.superQueryInfo.sTblName); - printf("stb query times:\033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.queryTimes); + printf("super table query info:\n"); + printf("query interval: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.rate); + printf("threadCnt: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.threadCnt); + printf("childTblCount: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.childTblCount); + printf("stable name: \033[33m%s\033[0m\n", + g_queryInfo.superQueryInfo.sTblName); + printf("stb query times:\033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.queryTimes); if (SUBSCRIBE_TEST == g_args.test_mode) { - printf("mod: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.subscribeMode); - printf("interval: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.subscribeInterval); - printf("restart: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.subscribeRestart); - printf("keepProgress: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.subscribeKeepProgress); + printf("mod: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.mode); + printf("interval: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.subscribeInterval); + printf("restart: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.subscribeRestart); + printf("keepProgress: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.subscribeKeepProgress); } - printf("sqlCount: \033[33m%d\033[0m\n", g_queryInfo.superQueryInfo.sqlCount); + printf("sqlCount: \033[33m%d\033[0m\n", + g_queryInfo.superQueryInfo.sqlCount); for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { - printf(" sql[%d]: \033[33m%s\033[0m\n", i, g_queryInfo.superQueryInfo.sql[i]); + printf(" sql[%d]: \033[33m%s\033[0m\n", + i, g_queryInfo.superQueryInfo.sql[i]); } printf("\n"); @@ -1637,7 +1668,7 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { TAOS_FIELD *fields = taos_fetch_fields(res); - while ((row = taos_fetch_row(res)) != NULL) { + while((row = taos_fetch_row(res)) != NULL) { // sys database name : 'log' if (strncasecmp(row[TSDB_SHOW_DB_NAME_INDEX], "log", fields[TSDB_SHOW_DB_NAME_INDEX].bytes) == 0) { @@ -1670,7 +1701,8 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { dbInfos[count]->wallevel = *((int8_t *)row[TSDB_SHOW_DB_WALLEVEL_INDEX]); dbInfos[count]->fsync = *((int32_t *)row[TSDB_SHOW_DB_FSYNC_INDEX]); dbInfos[count]->comp = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_COMP_INDEX])); - dbInfos[count]->cachelast = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX])); + dbInfos[count]->cachelast = + (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX])); tstrncpy(dbInfos[count]->precision, (char *)row[TSDB_SHOW_DB_PRECISION_INDEX], @@ -1681,7 +1713,8 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { count++; if (count > MAX_DATABASE_COUNT) { - errorPrint( "The database count overflow than %d\n", MAX_DATABASE_COUNT); + errorPrint("%s() LN%d, The database count overflow than %d\n", + __func__, __LINE__, MAX_DATABASE_COUNT); break; } } @@ -1691,6 +1724,7 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { static void printfDbInfoForQueryToFile( char* filename, SDbInfo* dbInfos, int index) { + if (filename[0] == 0) return; @@ -1762,7 +1796,7 @@ static void printfQuerySystemInfo(TAOS * taos) { } for (int i = 0; i < dbCount; i++) { - // printf database info + // printf database info printfDbInfoForQueryToFile(filename, dbInfos[i], i); // show db.vgroups @@ -1909,7 +1943,7 @@ static int postProceSql(char* host, uint16_t port, char* sqlstr) if (bytes == 0) break; sent+=bytes; - } while (sent < req_str_len); + } while(sent < req_str_len); memset(response_buf, 0, RESP_BUF_LEN); resp_len = sizeof(response_buf) - 1; @@ -1927,7 +1961,7 @@ static int postProceSql(char* host, uint16_t port, char* sqlstr) if (bytes == 0) break; received += bytes; - } while (received < resp_len); + } while(received < resp_len); if (received == resp_len) { free(request_buf); @@ -1951,7 +1985,8 @@ static int postProceSql(char* host, uint16_t port, char* sqlstr) static char* getTagValueFromTagSample(SSuperTable* stbInfo, int tagUsePos) { char* dataBuf = (char*)calloc(TSDB_MAX_SQL_LEN+1, 1); if (NULL == dataBuf) { - errorPrint("%s() LN%d, calloc failed! size:%d\n", __func__, __LINE__, TSDB_MAX_SQL_LEN+1); + errorPrint("%s() LN%d, calloc failed! size:%d\n", + __func__, __LINE__, TSDB_MAX_SQL_LEN+1); return NULL; } @@ -2098,7 +2133,7 @@ static int calcRowLen(SSuperTable* superTbls) { lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6; } else if (strcasecmp(dataType, "FLOAT") == 0) { lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 22; - } else if (strcasecmp(dataType, "DOUBLE") == 0) { + } else if (strcasecmp(dataType, "DOUBLE") == 0) { lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42; } else { printf("get error tag type : %s\n", dataType); @@ -2155,7 +2190,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, } char* pTblName = childTblName; - while ((row = taos_fetch_row(res)) != NULL) { + while((row = taos_fetch_row(res)) != NULL) { int32_t* len = taos_fetch_lengths(res); tstrncpy(pTblName, (char *)row[0], len[0]+1); //printf("==== sub table name: %s\n", pTblName); @@ -2218,7 +2253,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, int tagIndex = 0; int columnIndex = 0; TAOS_FIELD *fields = taos_fetch_fields(res); - while ((row = taos_fetch_row(res)) != NULL) { + while((row = taos_fetch_row(res)) != NULL) { if (0 == count) { count++; continue; @@ -2262,7 +2297,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, /* if (TBL_ALREADY_EXISTS == superTbls->childTblExists) { - //get all child table name use cmd: select tbname from superTblName; + //get all child table name use cmd: select tbname from superTblName; int childTblCount = 10000; superTbls->childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN); if (superTbls->childTblName == NULL) { @@ -2279,7 +2314,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, } static int createSuperTable(TAOS * taos, char* dbName, - SSuperTable* superTbls, bool use_metric) { + SSuperTable* superTbl) { char command[BUFFER_SIZE] = "\0"; char cols[STRING_LEN] = "\0"; @@ -2287,19 +2322,26 @@ static int createSuperTable(TAOS * taos, char* dbName, int len = 0; int lenOfOneRow = 0; - for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) { - char* dataType = superTbls->columns[colIndex].dataType; - + + if (superTbl->columnCount == 0) { + errorPrint("%s() LN%d, super table column count is %d\n", + __func__, __LINE__, superTbl->columnCount); + return -1; + } + + for (colIndex = 0; colIndex < superTbl->columnCount; colIndex++) { + char* dataType = superTbl->columns[colIndex].dataType; + if (strcasecmp(dataType, "BINARY") == 0) { len += snprintf(cols + len, STRING_LEN - len, ", col%d %s(%d)", colIndex, "BINARY", - superTbls->columns[colIndex].dataLen); - lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; + superTbl->columns[colIndex].dataLen); + lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; } else if (strcasecmp(dataType, "NCHAR") == 0) { len += snprintf(cols + len, STRING_LEN - len, ", col%d %s(%d)", colIndex, "NCHAR", - superTbls->columns[colIndex].dataLen); - lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; + superTbl->columns[colIndex].dataLen); + lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; } else if (strcasecmp(dataType, "INT") == 0) { len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "INT"); lenOfOneRow += 11; @@ -2326,97 +2368,107 @@ static int createSuperTable(TAOS * taos, char* dbName, lenOfOneRow += 21; } else { taos_close(taos); - printf("config error data type : %s\n", dataType); + errorPrint("%s() LN%d, config error data type : %s\n", + __func__, __LINE__, dataType); exit(-1); } } - superTbls->lenOfOneRow = lenOfOneRow + 20; // timestamp - //printf("%s.%s column count:%d, column length:%d\n\n", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName, g_Dbs.db[i].superTbls[j].columnCount, lenOfOneRow); + superTbl->lenOfOneRow = lenOfOneRow + 20; // timestamp + //printf("%s.%s column count:%d, column length:%d\n\n", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbl[j].sTblName, g_Dbs.db[i].superTbl[j].columnCount, lenOfOneRow); // save for creating child table - superTbls->colsOfCreateChildTable = (char*)calloc(len+20, 1); - if (NULL == superTbls->colsOfCreateChildTable) { - printf("Failed when calloc, size:%d", len+1); + superTbl->colsOfCreateChildTable = (char*)calloc(len+20, 1); + if (NULL == superTbl->colsOfCreateChildTable) { + errorPrint("%s() LN%d, Failed when calloc, size:%d", + __func__, __LINE__, len+1); taos_close(taos); exit(-1); } - snprintf(superTbls->colsOfCreateChildTable, len+20, "(ts timestamp%s)", cols); - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, superTbls->colsOfCreateChildTable); - if (use_metric) { - char tags[STRING_LEN] = "\0"; - int tagIndex; - len = 0; + snprintf(superTbl->colsOfCreateChildTable, len+20, "(ts timestamp%s)", cols); + verbosePrint("%s() LN%d: %s\n", + __func__, __LINE__, superTbl->colsOfCreateChildTable); - int lenOfTagOfOneRow = 0; - len += snprintf(tags + len, STRING_LEN - len, "("); - for (tagIndex = 0; tagIndex < superTbls->tagCount; tagIndex++) { - char* dataType = superTbls->tags[tagIndex].dataType; - - if (strcasecmp(dataType, "BINARY") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex, - "BINARY", superTbls->tags[tagIndex].dataLen); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3; - } else if (strcasecmp(dataType, "NCHAR") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex, - "NCHAR", superTbls->tags[tagIndex].dataLen); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3; - } else if (strcasecmp(dataType, "INT") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "INT"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 11; - } else if (strcasecmp(dataType, "BIGINT") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "BIGINT"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 21; - } else if (strcasecmp(dataType, "SMALLINT") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "SMALLINT"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6; - } else if (strcasecmp(dataType, "TINYINT") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "TINYINT"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 4; - } else if (strcasecmp(dataType, "BOOL") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "BOOL"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6; - } else if (strcasecmp(dataType, "FLOAT") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "FLOAT"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 22; - } else if (strcasecmp(dataType, "DOUBLE") == 0) { - len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, - "DOUBLE"); - lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42; - } else { - taos_close(taos); - printf("config error tag type : %s\n", dataType); - exit(-1); - } - } - len -= 2; - len += snprintf(tags + len, STRING_LEN - len, ")"); - - superTbls->lenOfTagOfOneRow = lenOfTagOfOneRow; - - snprintf(command, BUFFER_SIZE, - "create table if not exists %s.%s (ts timestamp%s) tags %s", - dbName, superTbls->sTblName, cols, tags); - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, command); - - if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { - errorPrint( "create supertable %s failed!\n\n", - superTbls->sTblName); - return -1; - } - debugPrint("create supertable %s success!\n\n", superTbls->sTblName); + if (superTbl->tagCount == 0) { + errorPrint("%s() LN%d, super table tag count is %d\n", + __func__, __LINE__, superTbl->tagCount); + return -1; } + + char tags[STRING_LEN] = "\0"; + int tagIndex; + len = 0; + + int lenOfTagOfOneRow = 0; + len += snprintf(tags + len, STRING_LEN - len, "("); + for (tagIndex = 0; tagIndex < superTbl->tagCount; tagIndex++) { + char* dataType = superTbl->tags[tagIndex].dataType; + + if (strcasecmp(dataType, "BINARY") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex, + "BINARY", superTbl->tags[tagIndex].dataLen); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3; + } else if (strcasecmp(dataType, "NCHAR") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex, + "NCHAR", superTbl->tags[tagIndex].dataLen); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3; + } else if (strcasecmp(dataType, "INT") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "INT"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 11; + } else if (strcasecmp(dataType, "BIGINT") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "BIGINT"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 21; + } else if (strcasecmp(dataType, "SMALLINT") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "SMALLINT"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6; + } else if (strcasecmp(dataType, "TINYINT") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "TINYINT"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 4; + } else if (strcasecmp(dataType, "BOOL") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "BOOL"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6; + } else if (strcasecmp(dataType, "FLOAT") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "FLOAT"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 22; + } else if (strcasecmp(dataType, "DOUBLE") == 0) { + len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex, + "DOUBLE"); + lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 42; + } else { + taos_close(taos); + errorPrint("%s() LN%d, config error tag type : %s\n", + __func__, __LINE__, dataType); + exit(-1); + } + } + + len -= 2; + len += snprintf(tags + len, STRING_LEN - len, ")"); + + superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow; + + snprintf(command, BUFFER_SIZE, + "create table if not exists %s.%s (ts timestamp%s) tags %s", + dbName, superTbl->sTblName, cols, tags); + verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, command); + + if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { + errorPrint( "create supertable %s failed!\n\n", + superTbl->sTblName); + return -1; + } + debugPrint("create supertable %s success!\n\n", superTbl->sTblName); return 0; } -static int createDatabases() { +static int createDatabasesAndStables() { TAOS * taos = NULL; int ret = 0; taos = taos_connect(g_Dbs.host, g_Dbs.user, g_Dbs.password, NULL, g_Dbs.port); @@ -2434,85 +2486,88 @@ static int createDatabases() { taos_close(taos); return -1; } - } - int dataLen = 0; - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, "create database if not exists %s", g_Dbs.db[i].dbName); + int dataLen = 0; + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, "create database if not exists %s", g_Dbs.db[i].dbName); - if (g_Dbs.db[i].dbCfg.blocks > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " blocks %d", g_Dbs.db[i].dbCfg.blocks); - } - if (g_Dbs.db[i].dbCfg.cache > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " cache %d", g_Dbs.db[i].dbCfg.cache); - } - if (g_Dbs.db[i].dbCfg.days > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " days %d", g_Dbs.db[i].dbCfg.days); - } - if (g_Dbs.db[i].dbCfg.keep > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " keep %d", g_Dbs.db[i].dbCfg.keep); - } - if (g_Dbs.db[i].dbCfg.quorum > 1) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " quorum %d", g_Dbs.db[i].dbCfg.quorum); - } - if (g_Dbs.db[i].dbCfg.replica > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " replica %d", g_Dbs.db[i].dbCfg.replica); - } - if (g_Dbs.db[i].dbCfg.update > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " update %d", g_Dbs.db[i].dbCfg.update); - } - //if (g_Dbs.db[i].dbCfg.maxtablesPerVnode > 0) { - // dataLen += snprintf(command + dataLen, - // BUFFER_SIZE - dataLen, "tables %d ", g_Dbs.db[i].dbCfg.maxtablesPerVnode); - //} - if (g_Dbs.db[i].dbCfg.minRows > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " minrows %d", g_Dbs.db[i].dbCfg.minRows); - } - if (g_Dbs.db[i].dbCfg.maxRows > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " maxrows %d", g_Dbs.db[i].dbCfg.maxRows); - } - if (g_Dbs.db[i].dbCfg.comp > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " comp %d", g_Dbs.db[i].dbCfg.comp); - } - if (g_Dbs.db[i].dbCfg.walLevel > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " wal %d", g_Dbs.db[i].dbCfg.walLevel); - } - if (g_Dbs.db[i].dbCfg.cacheLast > 0) { - dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " cachelast %d", g_Dbs.db[i].dbCfg.cacheLast); - } - if (g_Dbs.db[i].dbCfg.fsync > 0) { - dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen, - " fsync %d", g_Dbs.db[i].dbCfg.fsync); - } - if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms"))) - || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, - "us", strlen("us")))) { - dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen, - " precision \'%s\';", g_Dbs.db[i].dbCfg.precision); - } + if (g_Dbs.db[i].dbCfg.blocks > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " blocks %d", g_Dbs.db[i].dbCfg.blocks); + } + if (g_Dbs.db[i].dbCfg.cache > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " cache %d", g_Dbs.db[i].dbCfg.cache); + } + if (g_Dbs.db[i].dbCfg.days > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " days %d", g_Dbs.db[i].dbCfg.days); + } + if (g_Dbs.db[i].dbCfg.keep > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " keep %d", g_Dbs.db[i].dbCfg.keep); + } + if (g_Dbs.db[i].dbCfg.quorum > 1) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " quorum %d", g_Dbs.db[i].dbCfg.quorum); + } + if (g_Dbs.db[i].dbCfg.replica > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " replica %d", g_Dbs.db[i].dbCfg.replica); + } + if (g_Dbs.db[i].dbCfg.update > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " update %d", g_Dbs.db[i].dbCfg.update); + } + //if (g_Dbs.db[i].dbCfg.maxtablesPerVnode > 0) { + // dataLen += snprintf(command + dataLen, + // BUFFER_SIZE - dataLen, "tables %d ", g_Dbs.db[i].dbCfg.maxtablesPerVnode); + //} + if (g_Dbs.db[i].dbCfg.minRows > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " minrows %d", g_Dbs.db[i].dbCfg.minRows); + } + if (g_Dbs.db[i].dbCfg.maxRows > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " maxrows %d", g_Dbs.db[i].dbCfg.maxRows); + } + if (g_Dbs.db[i].dbCfg.comp > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " comp %d", g_Dbs.db[i].dbCfg.comp); + } + if (g_Dbs.db[i].dbCfg.walLevel > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " wal %d", g_Dbs.db[i].dbCfg.walLevel); + } + if (g_Dbs.db[i].dbCfg.cacheLast > 0) { + dataLen += snprintf(command + dataLen, + BUFFER_SIZE - dataLen, " cachelast %d", g_Dbs.db[i].dbCfg.cacheLast); + } + if (g_Dbs.db[i].dbCfg.fsync > 0) { + dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen, + " fsync %d", g_Dbs.db[i].dbCfg.fsync); + } + if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms"))) + || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, + "us", strlen("us")))) { + dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen, + " precision \'%s\';", g_Dbs.db[i].dbCfg.precision); + } - debugPrint("%s() %d command: %s\n", __func__, __LINE__, command); - if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { - taos_close(taos); - errorPrint( "\ncreate database %s failed!\n\n", g_Dbs.db[i].dbName); - return -1; + debugPrint("%s() %d command: %s\n", __func__, __LINE__, command); + if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) { + taos_close(taos); + errorPrint( "\ncreate database %s failed!\n\n", g_Dbs.db[i].dbName); + return -1; + } + printf("\ncreate database %s success!\n\n", g_Dbs.db[i].dbName); } - printf("\ncreate database %s success!\n\n", g_Dbs.db[i].dbName); debugPrint("%s() %d supertbl count:%d\n", __func__, __LINE__, g_Dbs.db[i].superTblCount); + + int validStbCount = 0; + for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName); @@ -2522,12 +2577,11 @@ static int createDatabases() { if ((ret != 0) || (g_Dbs.db[i].drop)) { ret = createSuperTable(taos, g_Dbs.db[i].dbName, - &g_Dbs.db[i].superTbls[j], g_Dbs.use_metric); + &g_Dbs.db[i].superTbls[j]); if (0 != ret) { - errorPrint("\ncreate super table %d failed!\n\n", j); - taos_close(taos); - return -1; + errorPrint("create super table %d failed!\n\n", j); + continue; } } @@ -2536,10 +2590,13 @@ static int createDatabases() { if (0 != ret) { errorPrint("\nget super table %s.%s info failed!\n\n", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName); - taos_close(taos); - return -1; + continue; } + + validStbCount ++; } + + g_Dbs.db[i].superTblCount = validStbCount; } taos_close(taos); @@ -2548,16 +2605,13 @@ static int createDatabases() { static void* createTable(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; - SSuperTable* superTblInfo = winfo->superTblInfo; + threadInfo *pThreadInfo = (threadInfo *)sarg; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; int64_t lastPrintTime = taosGetTimestampMs(); int buff_len; - if (superTblInfo) - buff_len = superTblInfo->maxSqlLen; - else - buff_len = BUFFER_SIZE; + buff_len = BUFFER_SIZE / 8; char *buffer = calloc(buff_len, 1); if (buffer == NULL) { @@ -2570,15 +2624,15 @@ static void* createTable(void *sarg) verbosePrint("%s() LN%d: Creating table from %d to %d\n", __func__, __LINE__, - winfo->start_table_from, winfo->end_table_to); + pThreadInfo->start_table_from, pThreadInfo->end_table_to); - for (int i = winfo->start_table_from; i <= winfo->end_table_to; i++) { + for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) { if (0 == g_Dbs.use_metric) { snprintf(buffer, buff_len, "create table if not exists %s.%s%d %s;", - winfo->db_name, + pThreadInfo->db_name, g_args.tb_prefix, i, - winfo->cols); + pThreadInfo->cols); } else { if (superTblInfo == NULL) { errorPrint("%s() LN%d, use metric, but super table info is NULL\n", @@ -2592,7 +2646,6 @@ static void* createTable(void *sarg) len += snprintf(buffer + len, buff_len - len, "create table "); } - char* tagsValBuf = NULL; if (0 == superTblInfo->tagSource) { tagsValBuf = generateTagVaulesForStb(superTblInfo, i); @@ -2605,18 +2658,16 @@ static void* createTable(void *sarg) free(buffer); return NULL; } - len += snprintf(buffer + len, - superTblInfo->maxSqlLen - len, + buff_len - len, "if not exists %s.%s%d using %s.%s tags %s ", - winfo->db_name, superTblInfo->childTblPrefix, - i, winfo->db_name, + pThreadInfo->db_name, superTblInfo->childTblPrefix, + i, pThreadInfo->db_name, superTblInfo->sTblName, tagsValBuf); free(tagsValBuf); batchNum++; - if ((batchNum < superTblInfo->batchCreateTableNum) - && ((superTblInfo->maxSqlLen - len) + && ((buff_len - len) >= (superTblInfo->lenOfTagOfOneRow + 256))) { continue; } @@ -2625,7 +2676,7 @@ static void* createTable(void *sarg) len = 0; verbosePrint("%s() LN%d %s\n", __func__, __LINE__, buffer); - if (0 != queryDbExec(winfo->taos, buffer, NO_INSERT_TYPE, false)){ + if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)){ errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer); free(buffer); return NULL; @@ -2634,14 +2685,14 @@ static void* createTable(void *sarg) int64_t currentPrintTime = taosGetTimestampMs(); if (currentPrintTime - lastPrintTime > 30*1000) { printf("thread[%d] already create %d - %d tables\n", - winfo->threadID, winfo->start_table_from, i); + pThreadInfo->threadID, pThreadInfo->start_table_from, i); lastPrintTime = currentPrintTime; } } - + if (0 != len) { verbosePrint("%s() %d buffer: %s\n", __func__, __LINE__, buffer); - if (0 != queryDbExec(winfo->taos, buffer, NO_INSERT_TYPE, false)) { + if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)) { errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer); } } @@ -2688,7 +2739,8 @@ static int startMultiThreadCreateChildTable( db_name, g_Dbs.port); if (t_info->taos == NULL) { - errorPrint( "Failed to connect to TDengine, reason:%s\n", taos_errstr(NULL)); + errorPrint( "%s() LN%d, Failed to connect to TDengine, reason:%s\n", + __func__, __LINE__, taos_errstr(NULL)); free(pids); free(infos); return -1; @@ -2703,7 +2755,7 @@ static int startMultiThreadCreateChildTable( t_info->minDelay = INT16_MAX; pthread_create(pids + i, NULL, createTable, t_info); } - + for (int i = 0; i < threads; i++) { pthread_join(pids[i], NULL); } @@ -2724,58 +2776,60 @@ static void createChildTables() { int len; for (int i = 0; i < g_Dbs.dbCount; i++) { - if (g_Dbs.db[i].superTblCount > 0) { - // with super table - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { - if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) - || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) { - continue; + if (g_Dbs.use_metric) { + if (g_Dbs.db[i].superTblCount > 0) { + // with super table + for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) + || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) { + continue; + } + + verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, + g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); + int startFrom = 0; + g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount; + + verbosePrint("%s() LN%d: create %d child tables from %d\n", + __func__, __LINE__, g_totalChildTables, startFrom); + startMultiThreadCreateChildTable( + g_Dbs.db[i].superTbls[j].colsOfCreateChildTable, + g_Dbs.threadCountByCreateTbl, + startFrom, + g_Dbs.db[i].superTbls[j].childTblCount, + g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j])); } - - verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); - int startFrom = 0; - g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount; - - verbosePrint("%s() LN%d: create %d child tables from %d\n", - __func__, __LINE__, g_totalChildTables, startFrom); - startMultiThreadCreateChildTable( - g_Dbs.db[i].superTbls[j].colsOfCreateChildTable, - g_Dbs.threadCountByCreateTbl, - startFrom, - g_Dbs.db[i].superTbls[j].childTblCount, - g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j])); } } else { - // normal table - len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP"); - int j = 0; - while (g_args.datatype[j]) { - if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0) - || (strncasecmp(g_args.datatype[j], - "NCHAR", strlen("NCHAR")) == 0)) { - snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, - ", COL%d %s(60)", j, g_args.datatype[j]); - } else { - snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, - ", COL%d %s", j, g_args.datatype[j]); - } - len = strlen(tblColsBuf); - j++; - } + // normal table + len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP"); + int j = 0; + while(g_args.datatype[j]) { + if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0) + || (strncasecmp(g_args.datatype[j], + "NCHAR", strlen("NCHAR")) == 0)) { + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, + ", COL%d %s(60)", j, g_args.datatype[j]); + } else { + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, + ", COL%d %s", j, g_args.datatype[j]); + } + len = strlen(tblColsBuf); + j++; + } - len = snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")"); + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")"); - verbosePrint("%s() LN%d: dbName: %s num of tb: %d schema: %s\n", - __func__, __LINE__, - g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf); - startMultiThreadCreateChildTable( - tblColsBuf, - g_Dbs.threadCountByCreateTbl, - 0, - g_args.num_of_tables, - g_Dbs.db[i].dbName, - NULL); + verbosePrint("%s() LN%d: dbName: %s num of tb: %d schema: %s\n", + __func__, __LINE__, + g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf); + startMultiThreadCreateChildTable( + tblColsBuf, + g_Dbs.threadCountByCreateTbl, + 0, + g_args.num_of_tables, + g_Dbs.db[i].dbName, + NULL); } } } @@ -2809,7 +2863,7 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { return -1; } - while ((readLen = tgetline(&line, &n, fp)) != -1) { + while((readLen = tgetline(&line, &n, fp)) != -1) { if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) { line[--readLen] = 0; } @@ -2873,7 +2927,7 @@ static int readSampleFromCsvFileToMem( assert(superTblInfo->sampleDataBuf); memset(superTblInfo->sampleDataBuf, 0, MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow); - while (1) { + while(1) { readLen = tgetline(&line, &n, fp); if (-1 == readLen) { if(0 != fseek(fp, 0, SEEK_SET)) { @@ -2899,9 +2953,6 @@ static int readSampleFromCsvFileToMem( continue; } - verbosePrint("readLen=%ld stb->lenOfOneRow=%d getRows=%d\n", (long)readLen, - superTblInfo->lenOfOneRow, getRows); - memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow, line, readLen); getRows++; @@ -2920,7 +2971,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( cJSON* stbInfo, SSuperTable* superTbls) { bool ret = false; - // columns + // columns cJSON *columns = cJSON_GetObjectItem(stbInfo, "columns"); if (columns && columns->type != cJSON_Array) { printf("ERROR: failed to read json, columns not found\n"); @@ -2932,7 +2983,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( } int columnSize = cJSON_GetArraySize(columns); - if (columnSize > MAX_COLUMN_COUNT) { + if ((columnSize + 1/* ts */) > MAX_COLUMN_COUNT) { errorPrint("%s() LN%d, failed to read json, column size overflow, max column size is %d\n", __func__, __LINE__, MAX_COLUMN_COUNT); goto PARSE_OVER; @@ -2952,17 +3003,20 @@ static bool getColumnAndTagTypeFromInsertJsonFile( if (countObj && countObj->type == cJSON_Number) { count = countObj->valueint; } else if (countObj && countObj->type != cJSON_Number) { - errorPrint("%s() LN%d, failed to read json, column count not found\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, column count not found\n", + __func__, __LINE__); goto PARSE_OVER; } else { count = 1; } - // column info + // column info memset(&columnCase, 0, sizeof(StrColumn)); cJSON *dataType = cJSON_GetObjectItem(column, "type"); - if (!dataType || dataType->type != cJSON_String || dataType->valuestring == NULL) { - errorPrint("%s() LN%d: failed to read json, column type not found\n", __func__, __LINE__); + if (!dataType || dataType->type != cJSON_String + || dataType->valuestring == NULL) { + errorPrint("%s() LN%d: failed to read json, column type not found\n", + __func__, __LINE__); goto PARSE_OVER; } //tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE); @@ -2972,7 +3026,8 @@ static bool getColumnAndTagTypeFromInsertJsonFile( if (dataLen && dataLen->type == cJSON_Number) { columnCase.dataLen = dataLen->valueint; } else if (dataLen && dataLen->type != cJSON_Number) { - debugPrint("%s() LN%d: failed to read json, column len not found\n", __func__, __LINE__); + debugPrint("%s() LN%d: failed to read json, column len not found\n", + __func__, __LINE__); goto PARSE_OVER; } else { columnCase.dataLen = 8; @@ -2985,20 +3040,29 @@ static bool getColumnAndTagTypeFromInsertJsonFile( index++; } } + + if ((index + 1 /* ts */) > MAX_COLUMN_COUNT) { + errorPrint("%s() LN%d, failed to read json, column size overflow, allowed max column size is %d\n", + __func__, __LINE__, MAX_COLUMN_COUNT); + goto PARSE_OVER; + } + superTbls->columnCount = index; count = 1; index = 0; - // tags + // tags cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags"); if (!tags || tags->type != cJSON_Array) { - debugPrint("%s() LN%d, failed to read json, tags not found\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, tags not found\n", + __func__, __LINE__); goto PARSE_OVER; } int tagSize = cJSON_GetArraySize(tags); if (tagSize > MAX_TAG_COUNT) { - debugPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n", __func__, __LINE__, MAX_TAG_COUNT); + errorPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n", + __func__, __LINE__, MAX_TAG_COUNT); goto PARSE_OVER; } @@ -3018,11 +3082,13 @@ static bool getColumnAndTagTypeFromInsertJsonFile( count = 1; } - // column info + // column info memset(&columnCase, 0, sizeof(StrColumn)); cJSON *dataType = cJSON_GetObjectItem(tag, "type"); - if (!dataType || dataType->type != cJSON_String || dataType->valuestring == NULL) { - printf("ERROR: failed to read json, tag type not found\n"); + if (!dataType || dataType->type != cJSON_String + || dataType->valuestring == NULL) { + errorPrint("%s() LN%d, failed to read json, tag type not found\n", + __func__, __LINE__); goto PARSE_OVER; } tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE); @@ -3031,26 +3097,37 @@ static bool getColumnAndTagTypeFromInsertJsonFile( if (dataLen && dataLen->type == cJSON_Number) { columnCase.dataLen = dataLen->valueint; } else if (dataLen && dataLen->type != cJSON_Number) { - printf("ERROR: failed to read json, column len not found\n"); + errorPrint("%s() LN%d, failed to read json, column len not found\n", + __func__, __LINE__); goto PARSE_OVER; } else { columnCase.dataLen = 0; } for (int n = 0; n < count; ++n) { - tstrncpy(superTbls->tags[index].dataType, columnCase.dataType, MAX_TB_NAME_SIZE); + tstrncpy(superTbls->tags[index].dataType, columnCase.dataType, + MAX_TB_NAME_SIZE); superTbls->tags[index].dataLen = columnCase.dataLen; index++; } } + + if (index > MAX_TAG_COUNT) { + errorPrint("%s() LN%d, failed to read json, tags size overflow, allowed max tag count is %d\n", + __func__, __LINE__, MAX_TAG_COUNT); + goto PARSE_OVER; + } + superTbls->tagCount = index; + if ((superTbls->columnCount + superTbls->tagCount + 1 /* ts */) > MAX_COLUMN_COUNT) { + errorPrint("%s() LN%d, columns + tags is more than allowed max columns count: %d\n", + __func__, __LINE__, MAX_COLUMN_COUNT); + goto PARSE_OVER; + } ret = true; PARSE_OVER: - //free(content); - //cJSON_Delete(root); - //fclose(fp); return ret; } @@ -3127,7 +3204,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!gInsertInterval) { g_args.insert_interval = 0; } else { - errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3137,9 +3215,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { // rows per table need be less than insert batch if (g_args.interlace_rows > g_args.num_of_RPR) { - printf("NOTICE: interlace rows value %d > num_of_records_per_request %d\n\n", + printf("NOTICE: interlace rows value %d > num_of_records_per_req %d\n\n", g_args.interlace_rows, g_args.num_of_RPR); - printf(" interlace rows value will be set to num_of_records_per_request %d\n\n", + printf(" interlace rows value will be set to num_of_records_per_req %d\n\n", g_args.num_of_RPR); printf(" press Enter key to continue or Ctrl-C to stop."); (void)getchar(); @@ -3148,7 +3226,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!interlaceRows) { g_args.interlace_rows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req } else { - errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3158,7 +3237,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!maxSqlLen) { g_args.max_sql_len = TSDB_PAYLOAD_SIZE; } else { - errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3166,9 +3246,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { if (numRecPerReq && numRecPerReq->type == cJSON_Number) { g_args.num_of_RPR = numRecPerReq->valueint; } else if (!numRecPerReq) { - g_args.num_of_RPR = 100; + g_args.num_of_RPR = INT32_MAX; } else { - errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3209,7 +3290,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON* dbinfos = cJSON_GetArrayItem(dbs, i); if (dbinfos == NULL) continue; - // dbinfo + // dbinfo cJSON *dbinfo = cJSON_GetObjectItem(dbinfos, "dbinfo"); if (!dbinfo || dbinfo->type != cJSON_Object) { printf("ERROR: failed to read json, dbinfo not found\n"); @@ -3447,6 +3528,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } + /* cJSON* batchCreateTbl = cJSON_GetObjectItem(stbInfo, "batch_create_tbl_num"); if (batchCreateTbl && batchCreateTbl->type == cJSON_Number) { g_Dbs.db[i].superTbls[j].batchCreateTableNum = batchCreateTbl->valueint; @@ -3456,14 +3538,17 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { printf("ERROR: failed to read json, batch_create_tbl_num not found\n"); goto PARSE_OVER; } + */ cJSON *childTblExists = cJSON_GetObjectItem(stbInfo, "child_table_exists"); // yes, no if (childTblExists && childTblExists->type == cJSON_String && childTblExists->valuestring != NULL) { - if (0 == strncasecmp(childTblExists->valuestring, "yes", 3)) { + if ((0 == strncasecmp(childTblExists->valuestring, "yes", 3)) + && (g_Dbs.db[i].drop == false)) { g_Dbs.db[i].superTbls[j].childTblExists = TBL_ALREADY_EXISTS; - } else if (0 == strncasecmp(childTblExists->valuestring, "no", 2)) { + } else if ((0 == strncasecmp(childTblExists->valuestring, "no", 2) + || (g_Dbs.db[i].drop == true))) { g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS; } else { g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS; @@ -3492,7 +3577,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!dataSource) { tstrncpy(g_Dbs.db[i].superTbls[j].dataSource, "rand", MAX_DB_NAME_SIZE); } else { - errorPrint("%s() LN%d, failed to read json, data_source not found\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, data_source not found\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3509,18 +3595,20 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } cJSON* childTbl_limit = cJSON_GetObjectItem(stbInfo, "childtable_limit"); - if (childTbl_limit) { + if ((childTbl_limit) && (g_Dbs.db[i].drop != true) + && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) { if (childTbl_limit->type != cJSON_Number) { printf("ERROR: failed to read json, childtable_limit\n"); goto PARSE_OVER; } g_Dbs.db[i].superTbls[j].childTblLimit = childTbl_limit->valueint; } else { - g_Dbs.db[i].superTbls[j].childTblLimit = -1; // select ... limit -1 means all query result + g_Dbs.db[i].superTbls[j].childTblLimit = -1; // select ... limit -1 means all query result, drop = yes mean all table need recreate, limit value is invalid. } cJSON* childTbl_offset = cJSON_GetObjectItem(stbInfo, "childtable_offset"); - if (childTbl_offset) { + if ((childTbl_offset) && (g_Dbs.db[i].drop != true) + && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) { if (childTbl_offset->type != cJSON_Number || 0 > childTbl_offset->valueint) { printf("ERROR: failed to read json, childtable_offset\n"); goto PARSE_OVER; @@ -3552,19 +3640,6 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { goto PARSE_OVER; } - cJSON* sampleDataBufSize = cJSON_GetObjectItem(stbInfo, "sample_buf_size"); - if (sampleDataBufSize && sampleDataBufSize->type == cJSON_Number) { - g_Dbs.db[i].superTbls[j].sampleDataBufSize = sampleDataBufSize->valueint; - if (g_Dbs.db[i].superTbls[j].sampleDataBufSize < 1024*1024) { - g_Dbs.db[i].superTbls[j].sampleDataBufSize = 1024*1024 + 1024; - } - } else if (!sampleDataBufSize) { - g_Dbs.db[i].superTbls[j].sampleDataBufSize = 1024*1024 + 1024; - } else { - printf("ERROR: failed to read json, sample_buf_size not found\n"); - goto PARSE_OVER; - } - cJSON *sampleFormat = cJSON_GetObjectItem(stbInfo, "sample_format"); if (sampleFormat && sampleFormat->type == cJSON_String && sampleFormat->valuestring != NULL) { @@ -3578,7 +3653,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } cJSON *sampleFile = cJSON_GetObjectItem(stbInfo, "sample_file"); - if (sampleFile && sampleFile->type == cJSON_String && sampleFile->valuestring != NULL) { + if (sampleFile && sampleFile->type == cJSON_String + && sampleFile->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].sampleFile, sampleFile->valuestring, MAX_FILE_NAME_LEN); } else if (!sampleFile) { @@ -3610,17 +3686,18 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { int32_t len = maxSqlLen->valueint; if (len > TSDB_MAX_ALLOWED_SQL_LEN) { len = TSDB_MAX_ALLOWED_SQL_LEN; - } else if (len < TSDB_MAX_SQL_LEN) { - len = TSDB_MAX_SQL_LEN; + } else if (len < 5) { + len = 5; } g_Dbs.db[i].superTbls[j].maxSqlLen = len; } else if (!maxSqlLen) { - g_Dbs.db[i].superTbls[j].maxSqlLen = TSDB_MAX_SQL_LEN; + g_Dbs.db[i].superTbls[j].maxSqlLen = g_args.max_sql_len; } else { - printf("ERROR: failed to read json, maxSqlLen not found\n"); + errorPrint("%s() LN%d, failed to read json, maxSqlLen input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } - +/* cJSON *multiThreadWriteOneTbl = cJSON_GetObjectItem(stbInfo, "multi_thread_write_one_tbl"); // no , yes if (multiThreadWriteOneTbl @@ -3637,15 +3714,15 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { printf("ERROR: failed to read json, multiThreadWriteOneTbl not found\n"); goto PARSE_OVER; } - +*/ cJSON* interlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows"); if (interlaceRows && interlaceRows->type == cJSON_Number) { g_Dbs.db[i].superTbls[j].interlaceRows = interlaceRows->valueint; // rows per table need be less than insert batch if (g_Dbs.db[i].superTbls[j].interlaceRows > g_args.num_of_RPR) { - printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %d > num_of_records_per_request %d\n\n", + printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %d > num_of_records_per_req %d\n\n", i, j, g_Dbs.db[i].superTbls[j].interlaceRows, g_args.num_of_RPR); - printf(" interlace rows value will be set to num_of_records_per_request %d\n\n", + printf(" interlace rows value will be set to num_of_records_per_req %d\n\n", g_args.num_of_RPR); printf(" press Enter key to continue or Ctrl-C to stop."); (void)getchar(); @@ -3662,6 +3739,12 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON* disorderRatio = cJSON_GetObjectItem(stbInfo, "disorder_ratio"); if (disorderRatio && disorderRatio->type == cJSON_Number) { + if (disorderRatio->valueint > 50) + disorderRatio->valueint = 50; + + if (disorderRatio->valueint < 0) + disorderRatio->valueint = 0; + g_Dbs.db[i].superTbls[j].disorderRatio = disorderRatio->valueint; } else if (!disorderRatio) { g_Dbs.db[i].superTbls[j].disorderRatio = 0; @@ -3715,9 +3798,6 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { ret = true; PARSE_OVER: - //free(content); - //cJSON_Delete(root); - //fclose(fp); return ret; } @@ -3748,7 +3828,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* user = cJSON_GetObjectItem(root, "user"); if (user && user->type == cJSON_String && user->valuestring != NULL) { - tstrncpy(g_queryInfo.user, user->valuestring, MAX_USERNAME_SIZE); + tstrncpy(g_queryInfo.user, user->valuestring, MAX_USERNAME_SIZE); } else if (!user) { tstrncpy(g_queryInfo.user, "root", MAX_USERNAME_SIZE); ; } @@ -3783,7 +3863,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { } else if (!gQueryTimes) { g_args.query_times = 1; } else { - errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3805,7 +3886,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { goto PARSE_OVER; } - // super_table_query + // super_table_query cJSON *specifiedQuery = cJSON_GetObjectItem(root, "specified_table_query"); if (!specifiedQuery) { g_queryInfo.specifiedQueryInfo.concurrent = 0; @@ -3821,35 +3902,45 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.specifiedQueryInfo.rate = 0; } - cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery, "query_times"); + cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery, + "query_times"); if (specifiedQueryTimes && specifiedQueryTimes->type == cJSON_Number) { g_queryInfo.specifiedQueryInfo.queryTimes = specifiedQueryTimes->valueint; } else if (!specifiedQueryTimes) { g_queryInfo.specifiedQueryInfo.queryTimes = g_args.query_times; } else { - errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } cJSON* concurrent = cJSON_GetObjectItem(specifiedQuery, "concurrent"); if (concurrent && concurrent->type == cJSON_Number) { g_queryInfo.specifiedQueryInfo.concurrent = concurrent->valueint; + if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) { + errorPrint("%s() LN%d, query sqlCount %d or concurrent %d is not correct.\n", + __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount, + g_queryInfo.specifiedQueryInfo.concurrent); + goto PARSE_OVER; + } } else if (!concurrent) { g_queryInfo.specifiedQueryInfo.concurrent = 1; } - cJSON* mode = cJSON_GetObjectItem(specifiedQuery, "mode"); - if (mode && mode->type == cJSON_String && mode->valuestring != NULL) { - if (0 == strcmp("sync", mode->valuestring)) { - g_queryInfo.specifiedQueryInfo.subscribeMode = 0; - } else if (0 == strcmp("async", mode->valuestring)) { - g_queryInfo.specifiedQueryInfo.subscribeMode = 1; + cJSON* queryMode = cJSON_GetObjectItem(specifiedQuery, "mode"); + if (queryMode && queryMode->type == cJSON_String + && queryMode->valuestring != NULL) { + if (0 == strcmp("sync", queryMode->valuestring)) { + g_queryInfo.specifiedQueryInfo.mode = SYNC_QUERY_MODE; + } else if (0 == strcmp("async", queryMode->valuestring)) { + g_queryInfo.specifiedQueryInfo.mode = ASYNC_QUERY_MODE; } else { - printf("ERROR: failed to read json, subscribe mod error\n"); + errorPrint("%s() LN%d, failed to read json, query mode input error\n", + __func__, __LINE__); goto PARSE_OVER; } } else { - g_queryInfo.specifiedQueryInfo.subscribeMode = 0; + g_queryInfo.specifiedQueryInfo.mode = SYNC_QUERY_MODE; } cJSON* interval = cJSON_GetObjectItem(specifiedQuery, "interval"); @@ -3896,12 +3987,14 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (!superSqls) { g_queryInfo.specifiedQueryInfo.sqlCount = 0; } else if (superSqls->type != cJSON_Array) { - printf("ERROR: failed to read json, super sqls not found\n"); + errorPrint("%s() LN%d, failed to read json, super sqls not found\n", + __func__, __LINE__); goto PARSE_OVER; } else { int superSqlSize = cJSON_GetArraySize(superSqls); if (superSqlSize > MAX_QUERY_SQL_COUNT) { - printf("ERROR: failed to read json, query sql size overflow, max is %d\n", MAX_QUERY_SQL_COUNT); + errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n", + __func__, __LINE__, MAX_QUERY_SQL_COUNT); goto PARSE_OVER; } @@ -3930,7 +4023,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { } } - // sub_table_query + // sub_table_query cJSON *superQuery = cJSON_GetObjectItem(root, "super_table_query"); if (!superQuery) { g_queryInfo.superQueryInfo.threadCnt = 0; @@ -3953,7 +4046,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { } else if (!superQueryTimes) { g_queryInfo.superQueryInfo.queryTimes = g_args.query_times; } else { - errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", __func__, __LINE__); + errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3972,38 +4066,44 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { //} cJSON* stblname = cJSON_GetObjectItem(superQuery, "stblname"); - if (stblname && stblname->type == cJSON_String && stblname->valuestring != NULL) { - tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring, MAX_TB_NAME_SIZE); + if (stblname && stblname->type == cJSON_String + && stblname->valuestring != NULL) { + tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring, + MAX_TB_NAME_SIZE); } else { - printf("ERROR: failed to read json, super table name not found\n"); + errorPrint("%s() LN%d, failed to read json, super table name input error\n", + __func__, __LINE__); goto PARSE_OVER; } cJSON* submode = cJSON_GetObjectItem(superQuery, "mode"); - if (submode && submode->type == cJSON_String && submode->valuestring != NULL) { + if (submode && submode->type == cJSON_String + && submode->valuestring != NULL) { if (0 == strcmp("sync", submode->valuestring)) { - g_queryInfo.superQueryInfo.subscribeMode = 0; + g_queryInfo.superQueryInfo.mode = SYNC_QUERY_MODE; } else if (0 == strcmp("async", submode->valuestring)) { - g_queryInfo.superQueryInfo.subscribeMode = 1; + g_queryInfo.superQueryInfo.mode = ASYNC_QUERY_MODE; } else { - printf("ERROR: failed to read json, subscribe mod error\n"); + errorPrint("%s() LN%d, failed to read json, query mode input error\n", + __func__, __LINE__); goto PARSE_OVER; } } else { - g_queryInfo.superQueryInfo.subscribeMode = 0; + g_queryInfo.superQueryInfo.mode = SYNC_QUERY_MODE; } cJSON* subinterval = cJSON_GetObjectItem(superQuery, "interval"); if (subinterval && subinterval->type == cJSON_Number) { g_queryInfo.superQueryInfo.subscribeInterval = subinterval->valueint; - } else if (!subinterval) { + } else if (!subinterval) { //printf("failed to read json, subscribe interval no found\n"); //goto PARSE_OVER; g_queryInfo.superQueryInfo.subscribeInterval = 10000; } cJSON* subrestart = cJSON_GetObjectItem(superQuery, "restart"); - if (subrestart && subrestart->type == cJSON_String && subrestart->valuestring != NULL) { + if (subrestart && subrestart->type == cJSON_String + && subrestart->valuestring != NULL) { if (0 == strcmp("yes", subrestart->valuestring)) { g_queryInfo.superQueryInfo.subscribeRestart = 1; } else if (0 == strcmp("no", subrestart->valuestring)) { @@ -4037,12 +4137,14 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (!subsqls) { g_queryInfo.superQueryInfo.sqlCount = 0; } else if (subsqls->type != cJSON_Array) { - printf("ERROR: failed to read json, super sqls not found\n"); + errorPrint("%s() LN%d: failed to read json, super sqls not found\n", + __func__, __LINE__); goto PARSE_OVER; } else { int superSqlSize = cJSON_GetArraySize(subsqls); if (superSqlSize > MAX_QUERY_SQL_COUNT) { - printf("ERROR: failed to read json, query sql size overflow, max is %d\n", MAX_QUERY_SQL_COUNT); + errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n", + __func__, __LINE__, MAX_QUERY_SQL_COUNT); goto PARSE_OVER; } @@ -4052,19 +4154,25 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (sql == NULL) continue; cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql"); - if (!sqlStr || sqlStr->type != cJSON_String || sqlStr->valuestring == NULL) { - printf("ERROR: failed to read json, sql not found\n"); + if (!sqlStr || sqlStr->type != cJSON_String + || sqlStr->valuestring == NULL) { + errorPrint("%s() LN%d, failed to read json, sql not found\n", + __func__, __LINE__); goto PARSE_OVER; } - tstrncpy(g_queryInfo.superQueryInfo.sql[j], sqlStr->valuestring, MAX_QUERY_SQL_LENGTH); + tstrncpy(g_queryInfo.superQueryInfo.sql[j], sqlStr->valuestring, + MAX_QUERY_SQL_LENGTH); cJSON *result = cJSON_GetObjectItem(sql, "result"); - if (result != NULL && result->type == cJSON_String && result->valuestring != NULL){ - tstrncpy(g_queryInfo.superQueryInfo.result[j], result->valuestring, MAX_FILE_NAME_LEN); + if (result != NULL && result->type == cJSON_String + && result->valuestring != NULL){ + tstrncpy(g_queryInfo.superQueryInfo.result[j], + result->valuestring, MAX_FILE_NAME_LEN); } else if (NULL == result) { memset(g_queryInfo.superQueryInfo.result[j], 0, MAX_FILE_NAME_LEN); } else { - printf("ERROR: failed to read json, sub query result file not found\n"); + errorPrint("%s() LN%d, failed to read json, sub query result file not found\n", + __func__, __LINE__); goto PARSE_OVER; } } @@ -4074,9 +4182,6 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { ret = true; PARSE_OVER: - //free(content); - //cJSON_Delete(root); - //fclose(fp); return ret; } @@ -4090,7 +4195,7 @@ static bool getInfoFromJsonFile(char* file) { } bool ret = false; - int maxLen = 64000; + int maxLen = 6400000; char *content = calloc(1, maxLen + 1); int len = fread(content, 1, maxLen, fp); if (len <= 0) { @@ -4200,71 +4305,84 @@ static int getRowDataFromSample(char* dataBuf, int maxLen, int64_t timestamp, dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")"); (*sampleUsePos)++; - + return dataLen; } -static int generateRowData(char* dataBuf, int maxLen, int64_t timestamp, SSuperTable* stbInfo) { - int dataLen = 0; - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "(%" PRId64 ", ", timestamp); +static int generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo) { + int dataLen = 0; + char *pstr = recBuf; + int maxLen = MAX_DATA_SIZE; + + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "(%" PRId64 ", ", timestamp); + for (int i = 0; i < stbInfo->columnCount; i++) { if ((0 == strncasecmp(stbInfo->columns[i].dataType, "binary", 6)) || (0 == strncasecmp(stbInfo->columns[i].dataType, "nchar", 5))) { if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) { errorPrint( "binary or nchar length overflow, max size:%u\n", (uint32_t)TSDB_MAX_BINARY_LEN); - return (-1); + return -1; } char* buf = (char*)calloc(stbInfo->columns[i].dataLen+1, 1); if (NULL == buf) { errorPrint( "calloc failed! size:%d\n", stbInfo->columns[i].dataLen); - return (-1); + return -1; } rand_string(buf, stbInfo->columns[i].dataLen); - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "\'%s\', ", buf); + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\', ", buf); tmfree(buf); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "int", 3)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%d, ", rand_int()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "bigint", 6)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%"PRId64", ", rand_bigint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "float", 5)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%f, ", rand_float()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "double", 6)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "%f, ", rand_double()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "smallint", 8)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "%d, ", rand_smallint()); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "tinyint", 7)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "%d, ", rand_tinyint()); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "bool", 4)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "%d, ", rand_bool()); - } else if (0 == strncasecmp(stbInfo->columns[i].dataType, "timestamp", 9)) { - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, "%"PRId64", ", rand_bigint()); + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, + "%d, ", rand_smallint()); + } else if (0 == strncasecmp(stbInfo->columns[i].dataType, + "tinyint", strlen("tinyint"))) { + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, + "%d, ", rand_tinyint()); + } else if (0 == strncasecmp(stbInfo->columns[i].dataType, + "bool", strlen("bool"))) { + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, + "%d, ", rand_bool()); + } else if (0 == strncasecmp(stbInfo->columns[i].dataType, + "timestamp", strlen("timestamp"))) { + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, + "%"PRId64", ", rand_bigint()); } else { errorPrint( "No support data type: %s\n", stbInfo->columns[i].dataType); - return (-1); + return -1; } } dataLen -= 2; - dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")"); + dataLen += snprintf(pstr + dataLen, maxLen - dataLen, ")"); - return dataLen; + verbosePrint("%s() LN%d, recBuf:\n\t%s\n", __func__, __LINE__, recBuf); + + return strlen(recBuf); } -static int32_t generateData(char *res, char **data_type, +static int32_t generateData(char *recBuf, char **data_type, int num_of_cols, int64_t timestamp, int lenOfBinary) { - memset(res, 0, MAX_DATA_SIZE); - char *pstr = res; + memset(recBuf, 0, MAX_DATA_SIZE); + char *pstr = recBuf; pstr += sprintf(pstr, "(%" PRId64, timestamp); int c = 0; @@ -4285,7 +4403,7 @@ static int32_t generateData(char *res, char **data_type, } else if (strcasecmp(data_type[i % c], "smallint") == 0) { pstr += sprintf(pstr, ", %d", rand_smallint()); } else if (strcasecmp(data_type[i % c], "int") == 0) { - pstr += sprintf(pstr, ", %d", rand_int()); + pstr += sprintf(pstr, ", %d", rand_int()); } else if (strcasecmp(data_type[i % c], "bigint") == 0) { pstr += sprintf(pstr, ", %" PRId64, rand_bigint()); } else if (strcasecmp(data_type[i % c], "float") == 0) { @@ -4308,7 +4426,7 @@ static int32_t generateData(char *res, char **data_type, free(s); } - if (pstr - res > MAX_DATA_SIZE) { + if (strlen(recBuf) > MAX_DATA_SIZE) { perror("column length too long, abort"); exit(-1); } @@ -4316,7 +4434,9 @@ static int32_t generateData(char *res, char **data_type, pstr += sprintf(pstr, ")"); - return (int32_t)(pstr - res); + verbosePrint("%s() LN%d, recBuf:\n\t%s\n", __func__, __LINE__, recBuf); + + return (int32_t)strlen(recBuf); } static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { @@ -4325,9 +4445,9 @@ static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { sampleDataBuf = calloc( superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1); if (sampleDataBuf == NULL) { - errorPrint("%s() LN%d, Failed to calloc %d Bytes, reason:%s\n", + errorPrint("%s() LN%d, Failed to calloc %d Bytes, reason:%s\n", __func__, __LINE__, - superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, + superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, strerror(errno)); return -1; } @@ -4336,7 +4456,8 @@ static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { int ret = readSampleFromCsvFileToMem(superTblInfo); if (0 != ret) { - errorPrint("%s() LN%d, read sample from csv file failed.\n", __func__, __LINE__); + errorPrint("%s() LN%d, read sample from csv file failed.\n", + __func__, __LINE__); tmfree(sampleDataBuf); superTblInfo->sampleDataBuf = NULL; return -1; @@ -4358,7 +4479,8 @@ static int execInsert(threadInfo *pThreadInfo, char *buffer, int k) } else { if (0 != postProceSql(g_Dbs.host, g_Dbs.port, buffer)) { affectedRows = -1; - printf("========restful return fail, threadID[%d]\n", pThreadInfo->threadID); + printf("========restful return fail, threadID[%d]\n", + pThreadInfo->threadID); } else { affectedRows = k; } @@ -4394,13 +4516,15 @@ static void getTableName(char *pTblName, threadInfo* pThreadInfo, int tableSeq) } } -static int generateDataTail(char *tableName, int32_t tableSeq, - threadInfo* pThreadInfo, SSuperTable* superTblInfo, - int batch, char* buffer, int64_t insertRows, +static int generateDataTail( + SSuperTable* superTblInfo, + int batch, char* buffer, int remainderBufLen, int64_t insertRows, int64_t startFrom, uint64_t startTime, int *pSamplePos, int *dataLen) { int len = 0; int ncols_per_record = 1; // count first col ts + char *pstr = buffer; + if (superTblInfo == NULL) { int datatypeSeq = 0; while(g_args.datatype[datatypeSeq]) { @@ -4413,80 +4537,81 @@ static int generateDataTail(char *tableName, int32_t tableSeq, int k = 0; for (k = 0; k < batch;) { - if (superTblInfo) { - int retLen = 0; + char data[MAX_DATA_SIZE]; + memset(data, 0, MAX_DATA_SIZE); - if (0 == strncasecmp(superTblInfo->dataSource, + int retLen = 0; + + if (superTblInfo) { + if (0 == strncasecmp(superTblInfo->dataSource, "sample", strlen("sample"))) { retLen = getRowDataFromSample( - buffer + len, - superTblInfo->maxSqlLen - len, + data, + remainderBufLen, startTime + superTblInfo->timeStampStep * k, superTblInfo, pSamplePos); - } else if (0 == strncasecmp(superTblInfo->dataSource, + } else if (0 == strncasecmp(superTblInfo->dataSource, "rand", strlen("rand"))) { - int rand_num = rand_tinyint() % 100; - if (0 != superTblInfo->disorderRatio - && rand_num < superTblInfo->disorderRatio) { - int64_t d = startTime - + superTblInfo->timeStampStep * k - - taosRandom() % superTblInfo->disorderRange; - retLen = generateRowData( - buffer + len, - superTblInfo->maxSqlLen - len, + + int randTail = superTblInfo->timeStampStep * k; + if (superTblInfo->disorderRatio > 0) { + int rand_num = taosRandom() % 100; + if(rand_num < superTblInfo->disorderRatio) { + randTail = (randTail + (taosRandom() % superTblInfo->disorderRange + 1)) * (-1); + debugPrint("rand data generated, back %d\n", randTail); + } + } + + uint64_t d = startTime + + randTail; + retLen = generateRowData( + data, d, superTblInfo); - } else { - retLen = generateRowData( - buffer + len, - superTblInfo->maxSqlLen - len, - startTime + superTblInfo->timeStampStep * k, - superTblInfo); - } - } + } - if (retLen < 0) { - return -1; - } + if (retLen > remainderBufLen) { + break; + } - len += retLen; - - if (len >= (superTblInfo->maxSqlLen - 256)) { // reserve for overwrite - k++; - break; - } + pstr += snprintf(pstr , retLen + 1, "%s", data); + k++; + len += retLen; + remainderBufLen -= retLen; } else { + char **data_type = g_args.datatype; + int lenOfBinary = g_args.len_of_binary; + int rand_num = taosRandom() % 100; - char data[MAX_DATA_SIZE]; - char **data_type = g_args.datatype; - int lenOfBinary = g_args.len_of_binary; + int randTail; if ((g_args.disorderRatio != 0) - && (rand_num < g_args.disorderRange)) { - - int64_t d = startTime + DEFAULT_TIMESTAMP_STEP * k - - taosRandom() % 1000000 + rand_num; - len = generateData(data, data_type, - ncols_per_record, d, lenOfBinary); + && (rand_num < g_args.disorderRatio)) { + randTail = (DEFAULT_TIMESTAMP_STEP * k + + (taosRandom() % g_args.disorderRange + 1)) * (-1); + debugPrint("rand data generated, back %d\n", randTail); } else { - len = generateData(data, data_type, - ncols_per_record, - startTime + DEFAULT_TIMESTAMP_STEP * k, - lenOfBinary); + randTail = DEFAULT_TIMESTAMP_STEP * k; } - buffer += sprintf(buffer, " %s", data); - if (strlen(buffer) >= (g_args.max_sql_len - 256)) { // too long - k++; - break; - } + retLen = generateData(data, data_type, + ncols_per_record, + startTime + randTail, + lenOfBinary); + + if (len > remainderBufLen) + break; + + pstr += sprintf(pstr, " %s", data); + k++; + len += retLen; + remainderBufLen -= retLen; } verbosePrint("%s() LN%d len=%d k=%d \nbuffer=%s\n", __func__, __LINE__, len, k, buffer); - k++; startFrom ++; if (startFrom >= insertRows) { @@ -4499,9 +4624,14 @@ static int generateDataTail(char *tableName, int32_t tableSeq, } static int generateSQLHead(char *tableName, int32_t tableSeq, - threadInfo* pThreadInfo, SSuperTable* superTblInfo, char *buffer) + threadInfo* pThreadInfo, SSuperTable* superTblInfo, + char *buffer, int remainderBufLen) { int len; + +#define HEAD_BUFF_LEN 1024*24 // 16*1024 + (192+32)*2 + insert into .. + char headBuf[HEAD_BUFF_LEN]; + if (superTblInfo) { if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) { char* tagsValBuf = NULL; @@ -4513,13 +4643,15 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, tableSeq % superTblInfo->tagSampleCount); } if (NULL == tagsValBuf) { - errorPrint("%s() LN%d, tag buf failed to allocate memory\n", __func__, __LINE__); + errorPrint("%s() LN%d, tag buf failed to allocate memory\n", + __func__, __LINE__); return -1; } - len = snprintf(buffer, - superTblInfo->maxSqlLen, - "insert into %s.%s using %s.%s tags %s values", + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s using %s.%s tags %s values", pThreadInfo->db_name, tableName, pThreadInfo->db_name, @@ -4527,34 +4659,101 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, tagsValBuf); tmfree(tagsValBuf); } else if (TBL_ALREADY_EXISTS == superTblInfo->childTblExists) { - len = snprintf(buffer, - superTblInfo->maxSqlLen, - "insert into %s.%s values", + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s values", pThreadInfo->db_name, tableName); } else { - len = snprintf(buffer, - superTblInfo->maxSqlLen, - "insert into %s.%s values", + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s values", pThreadInfo->db_name, tableName); } } else { - len = snprintf(buffer, - g_args.max_sql_len, - "insert into %s.%s values", + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s values", pThreadInfo->db_name, tableName); } + if (len > remainderBufLen) + return -1; + + tstrncpy(buffer, headBuf, len + 1); + return len; } -static int generateProgressiveDataBuffer(char *pTblName, +static int generateInterlaceDataBuffer( + char *tableName, int batchPerTbl, int i, int batchPerTblTimes, int32_t tableSeq, threadInfo *pThreadInfo, char *buffer, int64_t insertRows, - int64_t startFrom, int64_t startTime, int *pSamplePos) + int64_t startTime, + int *pRemainderBufLen) +{ + assert(buffer); + char *pstr = buffer; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + + int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, + superTblInfo, pstr, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + // generate data buffer + verbosePrint("[%d] %s() LN%d i=%d buffer:\n%s\n", + pThreadInfo->threadID, __func__, __LINE__, i, buffer); + + pstr += headLen; + *pRemainderBufLen -= headLen; + + int dataLen = 0; + + verbosePrint("[%d] %s() LN%d i=%d batchPerTblTimes=%d batchPerTbl = %d\n", + pThreadInfo->threadID, __func__, __LINE__, + i, batchPerTblTimes, batchPerTbl); + + if (superTblInfo) { + if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { + startTime = taosGetTimestamp(pThreadInfo->time_precision); + } + } else { + startTime = 1500000000000; + } + + int k = generateDataTail( + superTblInfo, + batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, + startTime, + &(pThreadInfo->samplePos), &dataLen); + + if (k == batchPerTbl) { + pstr += dataLen; + *pRemainderBufLen -= dataLen; + } else { + pstr -= headLen; + pstr[0] = '\0'; + k = 0; + } + + return k; +} + +static int generateProgressiveDataBuffer( + char *tableName, + int32_t tableSeq, + threadInfo *pThreadInfo, char *buffer, + int64_t insertRows, + int64_t startFrom, int64_t startTime, int *pSamplePos, + int *pRemainderBufLen) { SSuperTable* superTblInfo = pThreadInfo->superTblInfo; @@ -4569,21 +4768,27 @@ static int generateProgressiveDataBuffer(char *pTblName, } assert(buffer != NULL); - - memset(buffer, 0, superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len); - char *pstr = buffer; - int headLen = generateSQLHead(pTblName, tableSeq, pThreadInfo, superTblInfo, - buffer); - pstr += headLen; + int k = 0; + + memset(buffer, 0, *pRemainderBufLen); + + int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, superTblInfo, + buffer, *pRemainderBufLen); + + if (headLen <= 0) { + return 0; + } + pstr += headLen; + *pRemainderBufLen -= headLen; - int k; int dataLen; - k = generateDataTail(pTblName, tableSeq, pThreadInfo, superTblInfo, - g_args.num_of_RPR, pstr, insertRows, startFrom, + k = generateDataTail(superTblInfo, + g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, startFrom, startTime, pSamplePos, &dataLen); + return k; } @@ -4592,8 +4797,16 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { pThreadInfo->threadID, __func__, __LINE__); SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + + int64_t insertRows = (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT; int interlaceRows = superTblInfo?superTblInfo->interlaceRows:g_args.interlace_rows; + if (interlaceRows > insertRows) + interlaceRows = insertRows; + + if (interlaceRows > g_args.num_of_RPR) + interlaceRows = g_args.num_of_RPR; + int insertMode; if (interlaceRows > 0) { @@ -4605,21 +4818,21 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { // TODO: prompt tbl count multple interlace rows and batch // - char* buffer = calloc(superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len, 1); + int maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len; + char* buffer = calloc(maxSqlLen, 1); if (NULL == buffer) { - errorPrint( "Failed to alloc %d Bytes, reason:%s\n", - superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len, - strerror(errno)); + errorPrint( "%s() LN%d, Failed to alloc %d Bytes, reason:%s\n", + __func__, __LINE__, maxSqlLen, strerror(errno)); return NULL; } - char tableName[TSDB_TABLE_NAME_LEN]; pThreadInfo->totalInsertRows = 0; pThreadInfo->totalAffectedRows = 0; - int64_t insertRows = (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT; + int nTimeStampStep = superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP; + int insert_interval = superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; uint64_t st = 0; @@ -4637,18 +4850,14 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { int64_t startTime = pThreadInfo->start_time; - int batchPerTblTimes; - int batchPerTbl; - assert(pThreadInfo->ntables > 0); - if (interlaceRows > g_args.num_of_RPR) - interlaceRows = g_args.num_of_RPR; + int batchPerTbl = interlaceRows; - batchPerTbl = interlaceRows; + int batchPerTblTimes; if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) { batchPerTblTimes = - (g_args.num_of_RPR / (interlaceRows * pThreadInfo->ntables)) + 1; + g_args.num_of_RPR / interlaceRows; } else { batchPerTblTimes = 1; } @@ -4656,69 +4865,71 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { int generatedRecPerTbl = 0; bool flagSleep = true; int sleepTimeTotal = 0; + + char *strInsertInto = "insert into "; + int nInsertBufLen = strlen(strInsertInto); + while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { if ((flagSleep) && (insert_interval)) { st = taosGetTimestampUs(); flagSleep = false; } // generate data - memset(buffer, 0, superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len); + memset(buffer, 0, maxSqlLen); + int remainderBufLen = maxSqlLen; char *pstr = buffer; + + int len = snprintf(pstr, nInsertBufLen + 1, "%s", strInsertInto); + pstr += len; + remainderBufLen -= len; + int recOfBatch = 0; for (int i = 0; i < batchPerTblTimes; i ++) { getTableName(tableName, pThreadInfo, tableSeq); - - int headLen; - if (i == 0) { - headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, - superTblInfo, pstr); - } else { - headLen = snprintf(pstr, TSDB_TABLE_NAME_LEN, "%s.%s values", - pThreadInfo->db_name, - tableName); + if (0 == strlen(tableName)) { + errorPrint("[%d] %s() LN%d, getTableName return null\n", + pThreadInfo->threadID, __func__, __LINE__); + free(buffer); + return NULL; } - // generate data buffer - verbosePrint("[%d] %s() LN%d i=%d buffer:\n%s\n", - pThreadInfo->threadID, __func__, __LINE__, i, buffer); - - pstr += headLen; - int dataLen = 0; - - verbosePrint("[%d] %s() LN%d i=%d batchPerTblTimes=%d batchPerTbl = %d\n", - pThreadInfo->threadID, __func__, __LINE__, - i, batchPerTblTimes, batchPerTbl); - - if (superTblInfo) { - if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { - startTime = taosGetTimestamp(pThreadInfo->time_precision); - } - } else { - startTime = 1500000000000; - } - generateDataTail( - tableName, tableSeq, pThreadInfo, superTblInfo, - batchPerTbl, pstr, insertRows, 0, + int oldRemainderLen = remainderBufLen; + int generated = generateInterlaceDataBuffer( + tableName, batchPerTbl, i, batchPerTblTimes, + tableSeq, + pThreadInfo, pstr, + insertRows, startTime, - &(pThreadInfo->samplePos), &dataLen); + &remainderBufLen); - pstr += dataLen; + if (generated < 0) { + debugPrint("[%d] %s() LN%d, generated data is %d\n", + pThreadInfo->threadID, __func__, __LINE__, generated); + goto free_and_statistics_interlace; + } else if (generated == 0) { + break; + } + + tableSeq ++; recOfBatch += batchPerTbl; - startTime += batchPerTbl * superTblInfo->timeStampStep; + pstr += (oldRemainderLen - remainderBufLen); +// startTime += batchPerTbl * superTblInfo->timeStampStep; pThreadInfo->totalInsertRows += batchPerTbl; verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", pThreadInfo->threadID, __func__, __LINE__, batchPerTbl, recOfBatch); - tableSeq ++; if (insertMode == INTERLACE_INSERT_MODE) { if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { // turn to first table - startTime += batchPerTbl * superTblInfo->timeStampStep; tableSeq = pThreadInfo->start_table_from; generatedRecPerTbl += batchPerTbl; + + startTime = pThreadInfo->start_time + + generatedRecPerTbl * nTimeStampStep; + flagSleep = true; if (generatedRecPerTbl >= insertRows) break; @@ -4796,9 +5007,9 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { free_and_statistics_interlace: tmfree(buffer); - printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, + printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, pThreadInfo->totalAffectedRows); return NULL; } @@ -4815,11 +5026,12 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { debugPrint("%s() LN%d: ### progressive write\n", __func__, __LINE__); SSuperTable* superTblInfo = pThreadInfo->superTblInfo; + int maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len; - char* buffer = calloc(superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len, 1); + char* buffer = calloc(maxSqlLen, 1); if (NULL == buffer) { errorPrint( "Failed to alloc %d Bytes, reason:%s\n", - superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len, + maxSqlLen, strerror(errno)); return NULL; } @@ -4862,10 +5074,20 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { __func__, __LINE__, pThreadInfo->threadID, tableSeq, tableName); + int remainderBufLen = maxSqlLen; + char *pstr = buffer; + int nInsertBufLen = strlen("insert into "); + + int len = snprintf(pstr, nInsertBufLen + 1, "%s", "insert into "); + + pstr += len; + remainderBufLen -= len; + int generated = generateProgressiveDataBuffer( - tableName, tableSeq, pThreadInfo, buffer, insertRows, + tableName, tableSeq, pThreadInfo, pstr, insertRows, i, start_time, - &(pThreadInfo->samplePos)); + &(pThreadInfo->samplePos), + &remainderBufLen); if (generated > 0) i += generated; else @@ -4918,116 +5140,114 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { */ } // num_of_DPT - if ((tableSeq == pThreadInfo->ntables - 1) && superTblInfo && + if (g_args.verbose_print) { + if ((tableSeq == pThreadInfo->ntables - 1) && superTblInfo && (0 == strncasecmp( superTblInfo->dataSource, "sample", strlen("sample")))) { - printf("%s() LN%d samplePos=%d\n", + verbosePrint("%s() LN%d samplePos=%d\n", __func__, __LINE__, pThreadInfo->samplePos); + } } } // tableSeq free_and_statistics_2: tmfree(buffer); - printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, + printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, pThreadInfo->totalAffectedRows); return NULL; } static void* syncWrite(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; - SSuperTable* superTblInfo = winfo->superTblInfo; + threadInfo *pThreadInfo = (threadInfo *)sarg; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; int interlaceRows = superTblInfo?superTblInfo->interlaceRows:g_args.interlace_rows; if (interlaceRows > 0) { // interlace mode - return syncWriteInterlace(winfo); + return syncWriteInterlace(pThreadInfo); } else { // progressive mode - return syncWriteProgressive(winfo); + return syncWriteProgressive(pThreadInfo); } } static void callBack(void *param, TAOS_RES *res, int code) { - threadInfo* winfo = (threadInfo*)param; - SSuperTable* superTblInfo = winfo->superTblInfo; + threadInfo* pThreadInfo = (threadInfo*)param; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; int insert_interval = superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; if (insert_interval) { - winfo->et = taosGetTimestampUs(); - if (((winfo->et - winfo->st)/1000) < insert_interval) { - taosMsleep(insert_interval - (winfo->et - winfo->st)/1000); // ms + pThreadInfo->et = taosGetTimestampUs(); + if (((pThreadInfo->et - pThreadInfo->st)/1000) < insert_interval) { + taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)/1000); // ms } } - char *buffer = calloc(1, winfo->superTblInfo->maxSqlLen); - char *data = calloc(1, MAX_DATA_SIZE); + char *buffer = calloc(1, pThreadInfo->superTblInfo->maxSqlLen); + char data[MAX_DATA_SIZE]; char *pstr = buffer; - pstr += sprintf(pstr, "insert into %s.%s%d values", winfo->db_name, winfo->tb_prefix, - winfo->start_table_from); -// if (winfo->counter >= winfo->superTblInfo->insertRows) { - if (winfo->counter >= g_args.num_of_RPR) { - winfo->start_table_from++; - winfo->counter = 0; + pstr += sprintf(pstr, "insert into %s.%s%d values", pThreadInfo->db_name, pThreadInfo->tb_prefix, + pThreadInfo->start_table_from); +// if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) { + if (pThreadInfo->counter >= g_args.num_of_RPR) { + pThreadInfo->start_table_from++; + pThreadInfo->counter = 0; } - if (winfo->start_table_from > winfo->end_table_to) { - tsem_post(&winfo->lock_sem); + if (pThreadInfo->start_table_from > pThreadInfo->end_table_to) { + tsem_post(&pThreadInfo->lock_sem); free(buffer); - free(data); taos_free_result(res); return; } for (int i = 0; i < g_args.num_of_RPR; i++) { int rand_num = taosRandom() % 100; - if (0 != winfo->superTblInfo->disorderRatio - && rand_num < winfo->superTblInfo->disorderRatio) { - int64_t d = winfo->lastTs - taosRandom() % 1000000 + rand_num; - //generateData(data, datatype, ncols_per_record, d, len_of_binary); - generateRowData(data, MAX_DATA_SIZE, d, winfo->superTblInfo); + if (0 != pThreadInfo->superTblInfo->disorderRatio + && rand_num < pThreadInfo->superTblInfo->disorderRatio) { + int64_t d = pThreadInfo->lastTs - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1); + generateRowData(data, d, pThreadInfo->superTblInfo); } else { - //generateData(data, datatype, ncols_per_record, start_time += 1000, len_of_binary); - generateRowData(data, MAX_DATA_SIZE, winfo->lastTs += 1000, winfo->superTblInfo); + generateRowData(data, pThreadInfo->lastTs += 1000, pThreadInfo->superTblInfo); } pstr += sprintf(pstr, "%s", data); - winfo->counter++; + pThreadInfo->counter++; - if (winfo->counter >= winfo->superTblInfo->insertRows) { + if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) { break; } } if (insert_interval) { - winfo->st = taosGetTimestampUs(); + pThreadInfo->st = taosGetTimestampUs(); } - taos_query_a(winfo->taos, buffer, callBack, winfo); + taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo); free(buffer); - free(data); taos_free_result(res); } static void *asyncWrite(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; - SSuperTable* superTblInfo = winfo->superTblInfo; + threadInfo *pThreadInfo = (threadInfo *)sarg; + SSuperTable* superTblInfo = pThreadInfo->superTblInfo; - winfo->st = 0; - winfo->et = 0; - winfo->lastTs = winfo->start_time; + pThreadInfo->st = 0; + pThreadInfo->et = 0; + pThreadInfo->lastTs = pThreadInfo->start_time; int insert_interval = superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; if (insert_interval) { - winfo->st = taosGetTimestampUs(); + pThreadInfo->st = taosGetTimestampUs(); } - taos_query_a(winfo->taos, "show databases", callBack, winfo); + taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo); - tsem_wait(&(winfo->lock_sem)); + tsem_wait(&(pThreadInfo->lock_sem)); return NULL; } @@ -5082,7 +5302,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, start_time = 1500000000000; } - double start = getCurrentTime(); + double start = getCurrentTimeUs(); // read sample data from file first if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource, @@ -5119,16 +5339,16 @@ static void startMultiThreadInsertData(int threads, char* db_name, if (superTblInfo) { int limit, offset; - if (superTblInfo->childTblOffset >= superTblInfo->childTblCount) { - printf("WARNING: specified offset >= child table count! \n"); - if (!g_args.answer_yes) { - printf(" Press enter key to continue or Ctrl-C to stop\n\n"); - (void)getchar(); - } + if ((superTblInfo->childTblExists == TBL_NO_EXISTS) && + ((superTblInfo->childTblOffset != 0) || (superTblInfo->childTblLimit >= 0))) { + printf("WARNING: offset and limit will not be used since the child tables are not exists!\n"); } - if (superTblInfo->childTblOffset >= 0) { - if (superTblInfo->childTblLimit <= 0) { + if ((superTblInfo->childTblExists == TBL_ALREADY_EXISTS) + && (superTblInfo->childTblOffset >= 0)) { + if ((superTblInfo->childTblLimit < 0) + || ((superTblInfo->childTblOffset + superTblInfo->childTblLimit) + > (superTblInfo->childTblCount))) { superTblInfo->childTblLimit = superTblInfo->childTblCount - superTblInfo->childTblOffset; } @@ -5136,13 +5356,32 @@ static void startMultiThreadInsertData(int threads, char* db_name, offset = superTblInfo->childTblOffset; limit = superTblInfo->childTblLimit; } else { - limit = superTblInfo->childTblCount; - offset = 0; + limit = superTblInfo->childTblCount; + offset = 0; } ntables = limit; startFrom = offset; + if ((superTblInfo->childTblExists != TBL_NO_EXISTS) + && ((superTblInfo->childTblOffset + superTblInfo->childTblLimit ) + > superTblInfo->childTblCount)) { + printf("WARNING: specified offset + limit > child table count!\n"); + if (!g_args.answer_yes) { + printf(" Press enter key to continue or Ctrl-C to stop\n\n"); + (void)getchar(); + } + } + + if ((superTblInfo->childTblExists != TBL_NO_EXISTS) + && (0 == superTblInfo->childTblLimit)) { + printf("WARNING: specified limit = 0, which cannot find table name to insert or query! \n"); + if (!g_args.answer_yes) { + printf(" Press enter key to continue or Ctrl-C to stop\n\n"); + (void)getchar(); + } + } + superTblInfo->childTblName = (char*)calloc(1, limit * TSDB_TABLE_NAME_LEN); if (superTblInfo->childTblName == NULL) { @@ -5260,7 +5499,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, if (cntDelay == 0) cntDelay = 1; avgDelay = (double)totalDelay / cntDelay; - double end = getCurrentTime(); + double end = getCurrentTimeUs(); double t = end - start; if (superTblInfo) { @@ -5339,7 +5578,7 @@ static void *readTable(void *sarg) { sprintf(command, "select %s from %s%d where ts>= %" PRId64, aggreFunc[j], tb_prefix, i, sTime); - double t = getCurrentTime(); + double t = getCurrentTimeUs(); TAOS_RES *pSql = taos_query(taos, command); int32_t code = taos_errno(pSql); @@ -5351,11 +5590,11 @@ static void *readTable(void *sarg) { return NULL; } - while (taos_fetch_row(pSql) != NULL) { + while(taos_fetch_row(pSql) != NULL) { count++; } - t = getCurrentTime() - t; + t = getCurrentTimeUs() - t; totalT += t; taos_free_result(pSql); @@ -5373,7 +5612,7 @@ static void *readTable(void *sarg) { } static void *readMetric(void *sarg) { -#if 1 +#if 1 threadInfo *rinfo = (threadInfo *)sarg; TAOS *taos = rinfo->taos; char command[BUFFER_SIZE] = "\0"; @@ -5414,7 +5653,7 @@ static void *readMetric(void *sarg) { printf("Where condition: %s\n", condition); fprintf(fp, "%s\n", command); - double t = getCurrentTime(); + double t = getCurrentTimeUs(); TAOS_RES *pSql = taos_query(taos, command); int32_t code = taos_errno(pSql); @@ -5427,10 +5666,10 @@ static void *readMetric(void *sarg) { return NULL; } int count = 0; - while (taos_fetch_row(pSql) != NULL) { + while(taos_fetch_row(pSql) != NULL) { count++; } - t = getCurrentTime() - t; + t = getCurrentTimeUs() - t; fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n", num_of_tables * num_of_DPT / t, t * 1000); @@ -5472,7 +5711,7 @@ static int insertTestProcess() { init_rand_data(); // create database and super tables - if(createDatabases() != 0) { + if(createDatabasesAndStables() != 0) { fclose(g_fpOfInsertResult); return -1; } @@ -5484,9 +5723,9 @@ static int insertTestProcess() { double end; // create child tables - start = getCurrentTime(); + start = getCurrentTimeUs(); createChildTables(); - end = getCurrentTime(); + end = getCurrentTimeUs(); if (g_totalChildTables > 0) { printf("Spent %.4f seconds to create %d tables with %d thread(s)\n\n", @@ -5498,20 +5737,23 @@ static int insertTestProcess() { taosMsleep(1000); // create sub threads for inserting data - //start = getCurrentTime(); + //start = getCurrentTimeUs(); for (int i = 0; i < g_Dbs.dbCount; i++) { - if (g_Dbs.db[i].superTblCount > 0) { - for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { - SSuperTable* superTblInfo = &g_Dbs.db[i].superTbls[j]; - if (0 == g_Dbs.db[i].superTbls[j].insertRows) { - continue; - } - startMultiThreadInsertData( - g_Dbs.threadCount, - g_Dbs.db[i].dbName, - g_Dbs.db[i].dbCfg.precision, - superTblInfo); + if (g_Dbs.use_metric) { + if (g_Dbs.db[i].superTblCount > 0) { + for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { + + SSuperTable* superTblInfo = &g_Dbs.db[i].superTbls[j]; + + if (superTblInfo && (superTblInfo->insertRows > 0)) { + startMultiThreadInsertData( + g_Dbs.threadCount, + g_Dbs.db[i].dbName, + g_Dbs.db[i].dbCfg.precision, + superTblInfo); + } } + } } else { startMultiThreadInsertData( g_Dbs.threadCount, @@ -5520,11 +5762,11 @@ static int insertTestProcess() { NULL); } } - //end = getCurrentTime(); + //end = getCurrentTimeUs(); //int64_t totalInsertRows = 0; //int64_t totalAffectedRows = 0; - //for (int i = 0; i < g_Dbs.dbCount; i++) { + //for (int i = 0; i < g_Dbs.dbCount; i++) { // for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) { // totalInsertRows+= g_Dbs.db[i].superTbls[j].totalInsertRows; // totalAffectedRows += g_Dbs.db[i].superTbls[j].totalAffectedRows; @@ -5535,10 +5777,10 @@ static int insertTestProcess() { return 0; } -static void *superQueryProcess(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; +static void *specifiedTableQuery(void *sarg) { + threadInfo *pThreadInfo = (threadInfo *)sarg; - if (winfo->taos == NULL) { + if (pThreadInfo->taos == NULL) { TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, g_queryInfo.user, @@ -5547,17 +5789,17 @@ static void *superQueryProcess(void *sarg) { g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - winfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { - winfo->taos = taos; + pThreadInfo->taos = taos; } } char sqlStr[MAX_DB_NAME_SIZE + 5]; sprintf(sqlStr, "use %s", g_queryInfo.dbName); - if (0 != queryDbExec(winfo->taos, sqlStr, NO_INSERT_TYPE, false)) { - taos_close(winfo->taos); + if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { + taos_close(pThreadInfo->taos); errorPrint( "use database %s failed!\n\n", g_queryInfo.dbName); return NULL; @@ -5568,48 +5810,67 @@ static void *superQueryProcess(void *sarg) { int queryTimes = g_queryInfo.specifiedQueryInfo.queryTimes; + int totalQueried = 0; + int64_t lastPrintTime = taosGetTimestampMs(); + int64_t startTs = taosGetTimestampMs(); + while(queryTimes --) { if (g_queryInfo.specifiedQueryInfo.rate && (et - st) < (int64_t)g_queryInfo.specifiedQueryInfo.rate*1000) { taosMsleep(g_queryInfo.specifiedQueryInfo.rate*1000 - (et - st)); // ms - //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, winfo->start_table_from, winfo->end_table_to); + //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); } st = taosGetTimestampUs(); - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { - int64_t t1 = taosGetTimestampUs(); - char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; - if (g_queryInfo.specifiedQueryInfo.result[i][0] != 0) { - sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[i], winfo->threadID); - } - selectAndGetResult(winfo->taos, g_queryInfo.specifiedQueryInfo.sql[i], tmpFile); - int64_t t2 = taosGetTimestampUs(); - printf("=[taosc] thread[%"PRId64"] complete one sql, Spent %f s\n", - taosGetSelfPthreadId(), (t2 - t1)/1000000.0); - } else { - int64_t t1 = taosGetTimestampUs(); - int retCode = postProceSql(g_queryInfo.host, - g_queryInfo.port, g_queryInfo.specifiedQueryInfo.sql[i]); - int64_t t2 = taosGetTimestampUs(); - printf("=[restful] thread[%"PRId64"] complete one sql, Spent %f s\n", - taosGetSelfPthreadId(), (t2 - t1)/1000000.0); - if (0 != retCode) { - printf("====restful return fail, threadID[%d]\n", winfo->threadID); - return NULL; - } + if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { + int64_t t1 = taosGetTimestampUs(); + char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; + if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) { + sprintf(tmpFile, "%s-%d", + g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], + pThreadInfo->threadID); } + selectAndGetResult(pThreadInfo->taos, + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], tmpFile); + int64_t t2 = taosGetTimestampUs(); + printf("=[taosc] thread[%"PRId64"] complete one sql, Spent %f s\n", + taosGetSelfPthreadId(), (t2 - t1)/1000000.0); + } else { + int64_t t1 = taosGetTimestampUs(); + int retCode = postProceSql(g_queryInfo.host, + g_queryInfo.port, + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]); + if (0 != retCode) { + printf("====restful return fail, threadID[%d]\n", pThreadInfo->threadID); + return NULL; + } + int64_t t2 = taosGetTimestampUs(); + printf("=[restful] thread[%"PRId64"] complete one sql, Spent %f s\n", + taosGetSelfPthreadId(), (t2 - t1)/1000000.0); + } + totalQueried ++; + g_queryInfo.specifiedQueryInfo.totalQueried ++; + et = taosGetTimestampUs(); printf("==thread[%"PRId64"] complete all sqls to specify tables once queries duration:%.6fs\n\n", taosGetSelfPthreadId(), (double)(et - st)/1000.0); + + int64_t currentPrintTime = taosGetTimestampMs(); + int64_t endTs = taosGetTimestampMs(); + if (currentPrintTime - lastPrintTime > 30*1000) { + printf("thread[%d] has currently completed queries: %d, QPS: %10.2f\n", + pThreadInfo->threadID, + totalQueried, + totalQueried/((endTs-startTs)/1000.0)); + } + lastPrintTime = currentPrintTime; } return NULL; } -static void replaceSubTblName(char* inSql, char* outSql, int tblIndex) { +static void replaceChildTblName(char* inSql, char* outSql, int tblIndex) { char sourceString[32] = "xxxx"; char subTblName[MAX_TB_NAME_SIZE*3]; sprintf(subTblName, "%s.%s", @@ -5631,11 +5892,11 @@ static void replaceSubTblName(char* inSql, char* outSql, int tblIndex) { //printf("3: %s\n", outSql); } -static void *subQueryProcess(void *sarg) { +static void *superTableQuery(void *sarg) { char sqlstr[1024]; - threadInfo *winfo = (threadInfo *)sarg; + threadInfo *pThreadInfo = (threadInfo *)sarg; - if (winfo->taos == NULL) { + if (pThreadInfo->taos == NULL) { TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, g_queryInfo.user, @@ -5644,10 +5905,10 @@ static void *subQueryProcess(void *sarg) { g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - winfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { - winfo->taos = taos; + pThreadInfo->taos = taos; } } @@ -5655,33 +5916,49 @@ static void *subQueryProcess(void *sarg) { int64_t et = (int64_t)g_queryInfo.superQueryInfo.rate*1000; int queryTimes = g_queryInfo.superQueryInfo.queryTimes; + int totalQueried = 0; + int64_t startTs = taosGetTimestampMs(); + int64_t lastPrintTime = taosGetTimestampMs(); while(queryTimes --) { if (g_queryInfo.superQueryInfo.rate && (et - st) < (int64_t)g_queryInfo.superQueryInfo.rate*1000) { taosMsleep(g_queryInfo.superQueryInfo.rate*1000 - (et - st)); // ms - //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, winfo->start_table_from, winfo->end_table_to); + //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); } st = taosGetTimestampUs(); - for (int i = winfo->start_table_from; i <= winfo->end_table_to; i++) { + for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) { for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) { memset(sqlstr,0,sizeof(sqlstr)); - replaceSubTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i); + replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i); char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; if (g_queryInfo.superQueryInfo.result[j][0] != 0) { sprintf(tmpFile, "%s-%d", g_queryInfo.superQueryInfo.result[j], - winfo->threadID); + pThreadInfo->threadID); } - selectAndGetResult(winfo->taos, sqlstr, tmpFile); + selectAndGetResult(pThreadInfo->taos, sqlstr, tmpFile); + + totalQueried++; + g_queryInfo.superQueryInfo.totalQueried ++; + + int64_t currentPrintTime = taosGetTimestampMs(); + int64_t endTs = taosGetTimestampMs(); + if (currentPrintTime - lastPrintTime > 30*1000) { + printf("thread[%d] has currently completed queries: %d, QPS: %10.2f\n", + pThreadInfo->threadID, + totalQueried, + totalQueried/((endTs-startTs)/1000.0)); + } + lastPrintTime = currentPrintTime; } } et = taosGetTimestampUs(); printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%d - %d] once queries duration:%.4fs\n\n", taosGetSelfPthreadId(), - winfo->start_table_from, - winfo->end_table_to, + pThreadInfo->start_table_from, + pThreadInfo->end_table_to, (double)(et - st)/1000000.0); } @@ -5724,43 +6001,47 @@ static int queryTestProcess() { pthread_t *pids = NULL; threadInfo *infos = NULL; //==== create sub threads for query from specify table - if (g_queryInfo.specifiedQueryInfo.sqlCount > 0 - && g_queryInfo.specifiedQueryInfo.concurrent > 0) { + int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent; + int nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount; - pids = malloc(g_queryInfo.specifiedQueryInfo.concurrent * sizeof(pthread_t)); - if (NULL == pids) { - taos_close(taos); - ERROR_EXIT("memory allocation failed\n"); - } - infos = malloc(g_queryInfo.specifiedQueryInfo.concurrent * sizeof(threadInfo)); - if (NULL == infos) { + int64_t startTs = taosGetTimestampMs(); + + if ((nSqlCount > 0) && (nConcurrent > 0)) { + + pids = malloc(nConcurrent * nSqlCount * sizeof(pthread_t)); + infos = malloc(nConcurrent * nSqlCount * sizeof(threadInfo)); + + if ((NULL == pids) || (NULL == infos)) { taos_close(taos); - free(pids); ERROR_EXIT("memory allocation failed for create threads\n"); } - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.concurrent; i++) { - threadInfo *t_info = infos + i; - t_info->threadID = i; + for (int i = 0; i < nConcurrent; i++) { + for (int j = 0; j < nSqlCount; j++) { + threadInfo *t_info = infos + i * nSqlCount + j; + t_info->threadID = i * nSqlCount + j; + t_info->querySeq = j; - if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { + if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { - char sqlStr[MAX_TB_NAME_SIZE*2]; - sprintf(sqlStr, "use %s", g_queryInfo.dbName); - verbosePrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr); - if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) { + char sqlStr[MAX_TB_NAME_SIZE*2]; + sprintf(sqlStr, "use %s", g_queryInfo.dbName); + verbosePrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr); + if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) { taos_close(taos); free(infos); free(pids); errorPrint( "use database %s failed!\n\n", g_queryInfo.dbName); return -1; + } } + + t_info->taos = NULL;// TODO: workaround to use separate taos connection; + + pthread_create(pids + i * nSqlCount + j, NULL, specifiedTableQuery, + t_info); } - - t_info->taos = NULL;// TODO: workaround to use separate taos connection; - - pthread_create(pids + i, NULL, superQueryProcess, t_info); } } else { g_queryInfo.specifiedQueryInfo.concurrent = 0; @@ -5774,18 +6055,12 @@ static int queryTestProcess() { if ((g_queryInfo.superQueryInfo.sqlCount > 0) && (g_queryInfo.superQueryInfo.threadCnt > 0)) { pidsOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t)); - if (NULL == pidsOfSub) { - free(infos); - free(pids); - - ERROR_EXIT("memory allocation failed for create threads\n"); - } - infosOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo)); - if (NULL == infosOfSub) { - free(pidsOfSub); + + if ((NULL == pidsOfSub) || (NULL == infosOfSub)) { free(infos); free(pids); + ERROR_EXIT("memory allocation failed for create threads\n"); } @@ -5813,7 +6088,7 @@ static int queryTestProcess() { t_info->end_table_to = i < b ? startFrom + a : startFrom + a - 1; startFrom = t_info->end_table_to + 1; t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pidsOfSub + i, NULL, subQueryProcess, t_info); + pthread_create(pidsOfSub + i, NULL, superTableQuery, t_info); } g_queryInfo.superQueryInfo.threadCnt = threads; @@ -5821,8 +6096,12 @@ static int queryTestProcess() { g_queryInfo.superQueryInfo.threadCnt = 0; } - for (int i = 0; i < g_queryInfo.specifiedQueryInfo.concurrent; i++) { - pthread_join(pids[i], NULL); + if ((nSqlCount > 0) && (nConcurrent > 0)) { + for (int i = 0; i < nConcurrent; i++) { + for (int j = 0; j < nSqlCount; j++) { + pthread_join(pids[i * nSqlCount + j], NULL); + } + } } tmfree((char*)pids); @@ -5836,6 +6115,14 @@ static int queryTestProcess() { tmfree((char*)infosOfSub); // taos_close(taos);// TODO: workaround to use separate taos connection; + int64_t endTs = taosGetTimestampMs(); + + int totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried + + g_queryInfo.superQueryInfo.totalQueried; + + printf("==== completed total queries: %d, the QPS of all threads: %10.2f====\n", + totalQueried, + totalQueried/((endTs-startTs)/1000.0)); return 0; } @@ -5853,7 +6140,7 @@ static void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int c static TAOS_SUB* subscribeImpl(TAOS *taos, char *sql, char* topic, char* resultFileName) { TAOS_SUB* tsub = NULL; - if (g_queryInfo.specifiedQueryInfo.subscribeMode) { + if (g_queryInfo.specifiedQueryInfo.mode) { tsub = taos_subscribe(taos, g_queryInfo.specifiedQueryInfo.subscribeRestart, topic, sql, subscribe_callback, (void*)resultFileName, @@ -5872,12 +6159,12 @@ static TAOS_SUB* subscribeImpl(TAOS *taos, char *sql, char* topic, char* resultF return tsub; } -static void *subSubscribeProcess(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; +static void *superSubscribe(void *sarg) { + threadInfo *pThreadInfo = (threadInfo *)sarg; char subSqlstr[1024]; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT] = {0}; - if (winfo->taos == NULL) { + if (pThreadInfo->taos == NULL) { TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, g_queryInfo.user, @@ -5886,17 +6173,17 @@ static void *subSubscribeProcess(void *sarg) { g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - winfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { - winfo->taos = taos; + pThreadInfo->taos = taos; } } char sqlStr[MAX_TB_NAME_SIZE*2]; sprintf(sqlStr, "use %s", g_queryInfo.dbName); - if (0 != queryDbExec(winfo->taos, sqlStr, NO_INSERT_TYPE, false)) { - taos_close(winfo->taos); + if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { + taos_close(pThreadInfo->taos); errorPrint( "use database %s failed!\n\n", g_queryInfo.dbName); return NULL; @@ -5907,7 +6194,7 @@ static void *subSubscribeProcess(void *sarg) { do { //if (g_queryInfo.specifiedQueryInfo.rate && (et - st) < g_queryInfo.specifiedQueryInfo.rate*1000) { // taosMsleep(g_queryInfo.specifiedQueryInfo.rate*1000 - (et - st)); // ms - // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, winfo->start_table_from, winfo->end_table_to); + // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); //} //st = taosGetTimestampMs(); @@ -5915,27 +6202,27 @@ static void *subSubscribeProcess(void *sarg) { for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { sprintf(topic, "taosdemo-subscribe-%d", i); memset(subSqlstr,0,sizeof(subSqlstr)); - replaceSubTblName(g_queryInfo.superQueryInfo.sql[i], subSqlstr, i); + replaceChildTblName(g_queryInfo.superQueryInfo.sql[i], subSqlstr, i); char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; if (g_queryInfo.superQueryInfo.result[i][0] != 0) { sprintf(tmpFile, "%s-%d", - g_queryInfo.superQueryInfo.result[i], winfo->threadID); + g_queryInfo.superQueryInfo.result[i], pThreadInfo->threadID); } - tsub[i] = subscribeImpl(winfo->taos, subSqlstr, topic, tmpFile); + tsub[i] = subscribeImpl(pThreadInfo->taos, subSqlstr, topic, tmpFile); if (NULL == tsub[i]) { - taos_close(winfo->taos); + taos_close(pThreadInfo->taos); return NULL; } } //et = taosGetTimestampMs(); //printf("========thread[%"PRId64"] complete all sqls to super table once queries duration:%.4fs\n", taosGetSelfPthreadId(), (double)(et - st)/1000.0); - } while (0); + } while(0); // start loop to consume result TAOS_RES* res = NULL; - while (1) { + while(1) { for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { - if (1 == g_queryInfo.superQueryInfo.subscribeMode) { + if (1 == g_queryInfo.superQueryInfo.mode) { continue; } @@ -5945,7 +6232,7 @@ static void *subSubscribeProcess(void *sarg) { if (g_queryInfo.superQueryInfo.result[i][0] != 0) { sprintf(tmpFile, "%s-%d", g_queryInfo.superQueryInfo.result[i], - winfo->threadID); + pThreadInfo->threadID); } getResult(res, tmpFile); } @@ -5957,15 +6244,15 @@ static void *subSubscribeProcess(void *sarg) { taos_unsubscribe(tsub[i], g_queryInfo.superQueryInfo.subscribeKeepProgress); } - taos_close(winfo->taos); + taos_close(pThreadInfo->taos); return NULL; } -static void *superSubscribeProcess(void *sarg) { - threadInfo *winfo = (threadInfo *)sarg; +static void *specifiedSubscribe(void *sarg) { + threadInfo *pThreadInfo = (threadInfo *)sarg; TAOS_SUB* tsub[MAX_QUERY_SQL_COUNT] = {0}; - if (winfo->taos == NULL) { + if (pThreadInfo->taos == NULL) { TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, g_queryInfo.user, @@ -5974,18 +6261,18 @@ static void *superSubscribeProcess(void *sarg) { g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - winfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { - winfo->taos = taos; + pThreadInfo->taos = taos; } } char sqlStr[MAX_TB_NAME_SIZE*2]; sprintf(sqlStr, "use %s", g_queryInfo.dbName); debugPrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr); - if (0 != queryDbExec(winfo->taos, sqlStr, NO_INSERT_TYPE, false)) { - taos_close(winfo->taos); + if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { + taos_close(pThreadInfo->taos); return NULL; } @@ -5994,7 +6281,7 @@ static void *superSubscribeProcess(void *sarg) { do { //if (g_queryInfo.specifiedQueryInfo.rate && (et - st) < g_queryInfo.specifiedQueryInfo.rate*1000) { // taosMsleep(g_queryInfo.specifiedQueryInfo.rate*1000 - (et - st)); // ms - // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, winfo->start_table_from, winfo->end_table_to); + // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); //} //st = taosGetTimestampMs(); @@ -6004,23 +6291,24 @@ static void *superSubscribeProcess(void *sarg) { char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; if (g_queryInfo.superQueryInfo.result[i][0] != 0) { sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[i], winfo->threadID); + g_queryInfo.specifiedQueryInfo.result[i], pThreadInfo->threadID); } - tsub[i] = subscribeImpl(winfo->taos, g_queryInfo.specifiedQueryInfo.sql[i], topic, tmpFile); + tsub[i] = subscribeImpl(pThreadInfo->taos, + g_queryInfo.specifiedQueryInfo.sql[i], topic, tmpFile); if (NULL == g_queryInfo.specifiedQueryInfo.tsub[i]) { - taos_close(winfo->taos); + taos_close(pThreadInfo->taos); return NULL; } } //et = taosGetTimestampMs(); //printf("========thread[%"PRId64"] complete all sqls to super table once queries duration:%.4fs\n", taosGetSelfPthreadId(), (double)(et - st)/1000.0); - } while (0); + } while(0); // start loop to consume result TAOS_RES* res = NULL; - while (1) { + while(1) { for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - if (1 == g_queryInfo.specifiedQueryInfo.subscribeMode) { + if (SYNC_QUERY_MODE == g_queryInfo.specifiedQueryInfo.mode) { continue; } @@ -6029,7 +6317,7 @@ static void *superSubscribeProcess(void *sarg) { char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; if (g_queryInfo.specifiedQueryInfo.result[i][0] != 0) { sprintf(tmpFile, "%s-%d", - g_queryInfo.specifiedQueryInfo.result[i], winfo->threadID); + g_queryInfo.specifiedQueryInfo.result[i], pThreadInfo->threadID); } getResult(res, tmpFile); } @@ -6038,10 +6326,11 @@ static void *superSubscribeProcess(void *sarg) { taos_free_result(res); for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { - taos_unsubscribe(tsub[i], g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); + taos_unsubscribe(tsub[i], + g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); } - taos_close(winfo->taos); + taos_close(pThreadInfo->taos); return NULL; } @@ -6099,7 +6388,7 @@ static int subscribeTestProcess() { threadInfo *t_info = infos + i; t_info->threadID = i; t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pids + i, NULL, superSubscribeProcess, t_info); + pthread_create(pids + i, NULL, specifiedSubscribe, t_info); } //==== create sub threads for query from sub table @@ -6109,7 +6398,7 @@ static int subscribeTestProcess() { && (g_queryInfo.superQueryInfo.threadCnt > 0)) { pidsOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t)); - infosOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * + infosOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo)); if ((NULL == pidsOfSub) || (NULL == infosOfSub)) { errorPrint("%s() LN%d, malloc failed for create threads\n", @@ -6142,7 +6431,7 @@ static int subscribeTestProcess() { t_info->end_table_to = i < b ? startFrom + a : startFrom + a - 1; startFrom = t_info->end_table_to + 1; t_info->taos = NULL; // TODO: workaround to use separate taos connection; - pthread_create(pidsOfSub + i, NULL, subSubscribeProcess, t_info); + pthread_create(pidsOfSub + i, NULL, superSubscribe, t_info); } g_queryInfo.superQueryInfo.threadCnt = threads; @@ -6241,7 +6530,7 @@ static void setParaFromArg(){ g_Dbs.db[0].superTbls[0].childTblCount = g_args.num_of_tables; g_Dbs.threadCount = g_args.num_of_threads; g_Dbs.threadCountByCreateTbl = g_args.num_of_threads; - g_Dbs.queryMode = g_args.mode; + g_Dbs.queryMode = g_args.query_mode; g_Dbs.db[0].superTbls[0].autoCreateTable = PRE_CREATE_SUBTBL; g_Dbs.db[0].superTbls[0].childTblExists = TBL_NO_EXISTS; @@ -6256,7 +6545,7 @@ static void setParaFromArg(){ g_Dbs.db[0].superTbls[0].timeStampStep = DEFAULT_TIMESTAMP_STEP; g_Dbs.db[0].superTbls[0].insertRows = g_args.num_of_DPT; - g_Dbs.db[0].superTbls[0].maxSqlLen = TSDB_PAYLOAD_SIZE; + g_Dbs.db[0].superTbls[0].maxSqlLen = g_args.max_sql_len; g_Dbs.db[0].superTbls[0].columnCount = 0; for (int i = 0; i < MAX_NUM_DATATYPE; i++) { @@ -6341,9 +6630,9 @@ static void querySqlFile(TAOS* taos, char* sqlFile) char * line = NULL; size_t line_len = 0; - double t = getCurrentTime(); + double t = getCurrentTimeUs(); - while ((read_len = tgetline(&line, &line_len, fp)) != -1) { + while((read_len = tgetline(&line, &line_len, fp)) != -1) { if (read_len >= MAX_SQL_SIZE) continue; line[--read_len] = '\0'; @@ -6372,7 +6661,7 @@ static void querySqlFile(TAOS* taos, char* sqlFile) cmd_len = 0; } - t = getCurrentTime() - t; + t = getCurrentTimeUs() - t; printf("run %s took %.6f second(s)\n\n", sqlFile, t); tmfree(cmd); @@ -6406,62 +6695,68 @@ static void testMetaFile() { } static void queryResult() { - // select - if (false == g_Dbs.insert_only) { - // query data + // query data - pthread_t read_id; - threadInfo *rInfo = malloc(sizeof(threadInfo)); - rInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000 - rInfo->start_table_from = 0; + pthread_t read_id; + threadInfo *rInfo = malloc(sizeof(threadInfo)); + assert(rInfo); + rInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000 + rInfo->start_table_from = 0; - //rInfo->do_aggreFunc = g_Dbs.do_aggreFunc; - if (g_args.use_metric) { - rInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; - rInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; - rInfo->superTblInfo = &g_Dbs.db[0].superTbls[0]; - tstrncpy(rInfo->tb_prefix, - g_Dbs.db[0].superTbls[0].childTblPrefix, MAX_TB_NAME_SIZE); - } else { - rInfo->ntables = g_args.num_of_tables; - rInfo->end_table_to = g_args.num_of_tables -1; - tstrncpy(rInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE); - } + //rInfo->do_aggreFunc = g_Dbs.do_aggreFunc; + if (g_args.use_metric) { + rInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; + rInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; + rInfo->superTblInfo = &g_Dbs.db[0].superTbls[0]; + tstrncpy(rInfo->tb_prefix, + g_Dbs.db[0].superTbls[0].childTblPrefix, MAX_TB_NAME_SIZE); + } else { + rInfo->ntables = g_args.num_of_tables; + rInfo->end_table_to = g_args.num_of_tables -1; + tstrncpy(rInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE); + } - rInfo->taos = taos_connect( - g_Dbs.host, - g_Dbs.user, - g_Dbs.password, - g_Dbs.db[0].dbName, - g_Dbs.port); - if (rInfo->taos == NULL) { - errorPrint( "Failed to connect to TDengine, reason:%s\n", - taos_errstr(NULL)); - free(rInfo); - exit(-1); - } + rInfo->taos = taos_connect( + g_Dbs.host, + g_Dbs.user, + g_Dbs.password, + g_Dbs.db[0].dbName, + g_Dbs.port); + if (rInfo->taos == NULL) { + errorPrint( "Failed to connect to TDengine, reason:%s\n", + taos_errstr(NULL)); + free(rInfo); + exit(-1); + } - tstrncpy(rInfo->fp, g_Dbs.resultFile, MAX_FILE_NAME_LEN); + tstrncpy(rInfo->fp, g_Dbs.resultFile, MAX_FILE_NAME_LEN); - if (!g_Dbs.use_metric) { - pthread_create(&read_id, NULL, readTable, rInfo); - } else { - pthread_create(&read_id, NULL, readMetric, rInfo); - } - pthread_join(read_id, NULL); - taos_close(rInfo->taos); - free(rInfo); - } + if (!g_Dbs.use_metric) { + pthread_create(&read_id, NULL, readTable, rInfo); + } else { + pthread_create(&read_id, NULL, readMetric, rInfo); + } + pthread_join(read_id, NULL); + taos_close(rInfo->taos); + free(rInfo); } static void testCmdLine() { + if (strlen(configDir)) { + wordexp_t full_path; + if (wordexp(configDir, &full_path, 0) != 0) { + errorPrint( "Invalid path %s\n", configDir); + return; + } + taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]); + wordfree(&full_path); + } + g_args.test_mode = INSERT_TEST; insertTestProcess(); - if (g_Dbs.insert_only) - return; - else + if (false == g_Dbs.insert_only) queryResult(); } diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index 3cee5f1b1d..fd6ee9f2fc 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -39,6 +39,22 @@ typedef struct { int8_t type; } SOColInfo; +#define debugPrint(fmt, ...) \ + do { if (g_args.debug_print || g_args.verbose_print) \ + fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0) + +#define verbosePrint(fmt, ...) \ + do { if (g_args.verbose_print) \ + fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0) + +#define performancePrint(fmt, ...) \ + do { if (g_args.performance_print) \ + fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0) + +#define errorPrint(fmt, ...) \ + do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0) + + // -------------------------- SHOW DATABASE INTERFACE----------------------- enum _show_db_index { TSDB_SHOW_DB_NAME_INDEX, @@ -46,7 +62,7 @@ enum _show_db_index { TSDB_SHOW_DB_NTABLES_INDEX, TSDB_SHOW_DB_VGROUPS_INDEX, TSDB_SHOW_DB_REPLICA_INDEX, - TSDB_SHOW_DB_QUORUM_INDEX, + TSDB_SHOW_DB_QUORUM_INDEX, TSDB_SHOW_DB_DAYS_INDEX, TSDB_SHOW_DB_KEEP_INDEX, TSDB_SHOW_DB_CACHE_INDEX, @@ -101,10 +117,10 @@ typedef struct { char name[TSDB_DB_NAME_LEN + 1]; char create_time[32]; int32_t ntables; - int32_t vgroups; + int32_t vgroups; int16_t replica; int16_t quorum; - int16_t days; + int16_t days; char keeplist[32]; //int16_t daysToKeep; //int16_t daysToKeep1; @@ -172,48 +188,50 @@ static char args_doc[] = "dbname [tbname ...]\n--databases dbname ...\n--all-dat /* The options we understand. */ static struct argp_option options[] = { // connection option - {"host", 'h', "HOST", 0, "Server host dumping data from. Default is localhost.", 0}, - {"user", 'u', "USER", 0, "User name used to connect to server. Default is root.", 0}, + {"host", 'h', "HOST", 0, "Server host dumping data from. Default is localhost.", 0}, + {"user", 'u', "USER", 0, "User name used to connect to server. Default is root.", 0}, #ifdef _TD_POWER_ - {"password", 'p', "PASSWORD", 0, "User password to connect to server. Default is powerdb.", 0}, + {"password", 'p', "PASSWORD", 0, "User password to connect to server. Default is powerdb.", 0}, #else - {"password", 'p', "PASSWORD", 0, "User password to connect to server. Default is taosdata.", 0}, + {"password", 'p', "PASSWORD", 0, "User password to connect to server. Default is taosdata.", 0}, #endif - {"port", 'P', "PORT", 0, "Port to connect", 0}, - {"cversion", 'v', "CVERION", 0, "client version", 0}, - {"mysqlFlag", 'q', "MYSQLFLAG", 0, "mysqlFlag, Default is 0", 0}, + {"port", 'P', "PORT", 0, "Port to connect", 0}, + {"cversion", 'v', "CVERION", 0, "client version", 0}, + {"mysqlFlag", 'q', "MYSQLFLAG", 0, "mysqlFlag, Default is 0", 0}, // input/output file - {"outpath", 'o', "OUTPATH", 0, "Output file path.", 1}, - {"inpath", 'i', "INPATH", 0, "Input file path.", 1}, - {"resultFile", 'r', "RESULTFILE", 0, "DumpOut/In Result file path and name.", 1}, + {"outpath", 'o', "OUTPATH", 0, "Output file path.", 1}, + {"inpath", 'i', "INPATH", 0, "Input file path.", 1}, + {"resultFile", 'r', "RESULTFILE", 0, "DumpOut/In Result file path and name.", 1}, #ifdef _TD_POWER_ - {"config", 'c', "CONFIG_DIR", 0, "Configure directory. Default is /etc/power/taos.cfg.", 1}, + {"config", 'c', "CONFIG_DIR", 0, "Configure directory. Default is /etc/power/taos.cfg.", 1}, #else - {"config", 'c', "CONFIG_DIR", 0, "Configure directory. Default is /etc/taos/taos.cfg.", 1}, + {"config", 'c', "CONFIG_DIR", 0, "Configure directory. Default is /etc/taos/taos.cfg.", 1}, #endif - {"encode", 'e', "ENCODE", 0, "Input file encoding.", 1}, + {"encode", 'e', "ENCODE", 0, "Input file encoding.", 1}, // dump unit options - {"all-databases", 'A', 0, 0, "Dump all databases.", 2}, - {"databases", 'B', 0, 0, "Dump assigned databases", 2}, + {"all-databases", 'A', 0, 0, "Dump all databases.", 2}, + {"databases", 'B', 0, 0, "Dump assigned databases", 2}, // dump format options - {"schemaonly", 's', 0, 0, "Only dump schema.", 3}, - {"with-property", 'M', 0, 0, "Dump schema with properties.", 3}, - {"start-time", 'S', "START_TIME", 0, "Start time to dump.", 3}, - {"end-time", 'E', "END_TIME", 0, "End time to dump.", 3}, - {"data-batch", 'N', "DATA_BATCH", 0, "Number of data point per insert statement. Default is 1.", 3}, - {"max-sql-len", 'L', "SQL_LEN", 0, "Max length of one sql. Default is 65480.", 3}, - {"table-batch", 't', "TABLE_BATCH", 0, "Number of table dumpout into one output file. Default is 1.", 3}, - {"thread_num", 'T', "THREAD_NUM", 0, "Number of thread for dump in file. Default is 5.", 3}, - {"allow-sys", 'a', 0, 0, "Allow to dump sys database", 3}, + {"schemaonly", 's', 0, 0, "Only dump schema.", 3}, + {"with-property", 'M', 0, 0, "Dump schema with properties.", 3}, + {"start-time", 'S', "START_TIME", 0, "Start time to dump.", 3}, + {"end-time", 'E', "END_TIME", 0, "End time to dump. Epoch or ISO8601/RFC3339 format is acceptable. For example: 2017-10-01T18:00:00+0800", 3}, + {"data-batch", 'N', "DATA_BATCH", 0, "Number of data point per insert statement. Default is 1.", 3}, + {"max-sql-len", 'L', "SQL_LEN", 0, "Max length of one sql. Default is 65480.", 3}, + {"table-batch", 't', "TABLE_BATCH", 0, "Number of table dumpout into one output file. Default is 1.", 3}, + {"thread_num", 'T', "THREAD_NUM", 0, "Number of thread for dump in file. Default is 5.", 3}, + {"allow-sys", 'a', 0, 0, "Allow to dump sys database", 3}, + {"debug", 'g', 0, 0, "Print debug info.", 1}, + {"verbose", 'v', 0, 0, "Print verbose debug info.", 1}, {0}}; /* Used by main to communicate with parse_opt. */ -struct arguments { +typedef struct arguments { // connection option char *host; char *user; char *password; - uint16_t port; + uint16_t port; char cversion[12]; uint16_t mysqlFlag; // output file @@ -238,9 +256,12 @@ struct arguments { int32_t thread_num; int abort; char **arg_list; - int arg_list_len; - bool isDumpIn; -}; + int arg_list_len; + bool isDumpIn; + bool debug_print; + bool verbose_print; + bool performance_print; +} SArguments; /* Parse a single option. */ static error_t parse_opt(int key, char *arg, struct argp_state *state) { @@ -286,6 +307,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { tstrncpy(arguments->outpath, full_path.we_wordv[0], TSDB_FILENAME_LEN); wordfree(&full_path); break; + case 'g': + arguments->debug_print = true; + break; case 'i': arguments->isDumpIn = true; if (wordexp(arg, &full_path, 0) != 0) { @@ -387,7 +411,7 @@ int taosCheckParam(struct arguments *arguments); void taosFreeDbInfos(); static void taosStartDumpOutWorkThreads(void* taosCon, struct arguments* args, int32_t numOfThread, char *dbName); -struct arguments tsArguments = { +struct arguments g_args = { // connection option NULL, "root", @@ -400,18 +424,18 @@ struct arguments tsArguments = { "", 0, // outpath and inpath - "", + "", "", "./dump_result.txt", NULL, // dump unit option - false, + false, false, // dump format option - false, - false, - 0, - INT64_MAX, + false, + false, + 0, + INT64_MAX, 1, TSDB_MAX_SQL_LEN, 1, @@ -419,11 +443,14 @@ struct arguments tsArguments = { // other options 5, 0, - NULL, - 0, - false + NULL, + 0, + false, + false, // debug_print + false, // verbose_print + false // performance_print }; - + static int queryDbImpl(TAOS *taos, char *command) { int i; TAOS_RES *res = NULL; @@ -434,7 +461,7 @@ static int queryDbImpl(TAOS *taos, char *command) { taos_free_result(res); res = NULL; } - + res = taos_query(taos, command); code = taos_errno(res); if (0 == code) { @@ -453,13 +480,48 @@ static int queryDbImpl(TAOS *taos, char *command) { return 0; } +static void parse_args(int argc, char *argv[], SArguments *arguments) { + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-E") == 0) { + char *tmp = strdup(argv[++i]); + + if (tmp) { + int64_t tmpEpoch; + if (strchr(tmp, ':') && strchr(tmp, '-')) { + if (TSDB_CODE_SUCCESS != taosParseTime( + tmp, &tmpEpoch, strlen(tmp), TSDB_TIME_PRECISION_MILLI, 0)) { + fprintf(stderr, "Input end time error!\n"); + free(tmp); + return; + } + } else { + tmpEpoch = atoll(tmp); + } + + sprintf(argv[i], "%"PRId64"", tmpEpoch); + debugPrint("%s() LN%d, tmp is: %s, argv[%d]: %s\n", + __func__, __LINE__, tmp, i, argv[i]); + + free(tmp); + } else { + errorPrint("%s() LN%d, strdup() cannot allocate memory\n", __func__, __LINE__); + exit(-1); + } + } else if (strcmp(argv[i], "-g") == 0) { + arguments->debug_print = true; + } + } +} + int main(int argc, char *argv[]) { /* Parse our arguments; every option seen by parse_opt will be reflected in arguments. */ - argp_parse(&argp, argc, argv, 0, 0, &tsArguments); + parse_args(argc, argv, &g_args); - if (tsArguments.abort) { + argp_parse(&argp, argc, argv, 0, 0, &g_args); + + if (g_args.abort) { #ifndef _ALPINE error(10, 0, "ABORTED"); #else @@ -469,81 +531,82 @@ int main(int argc, char *argv[]) { printf("====== arguments config ======\n"); { - printf("host: %s\n", tsArguments.host); - printf("user: %s\n", tsArguments.user); - printf("password: %s\n", tsArguments.password); - printf("port: %u\n", tsArguments.port); - printf("cversion: %s\n", tsArguments.cversion); - printf("mysqlFlag: %d\n", tsArguments.mysqlFlag); - printf("outpath: %s\n", tsArguments.outpath); - printf("inpath: %s\n", tsArguments.inpath); - printf("resultFile: %s\n", tsArguments.resultFile); - printf("encode: %s\n", tsArguments.encode); - printf("all_databases: %d\n", tsArguments.all_databases); - printf("databases: %d\n", tsArguments.databases); - printf("schemaonly: %d\n", tsArguments.schemaonly); - printf("with_property: %d\n", tsArguments.with_property); - printf("start_time: %" PRId64 "\n", tsArguments.start_time); - printf("end_time: %" PRId64 "\n", tsArguments.end_time); - printf("data_batch: %d\n", tsArguments.data_batch); - printf("max_sql_len: %d\n", tsArguments.max_sql_len); - printf("table_batch: %d\n", tsArguments.table_batch); - printf("thread_num: %d\n", tsArguments.thread_num); - printf("allow_sys: %d\n", tsArguments.allow_sys); - printf("abort: %d\n", tsArguments.abort); - printf("isDumpIn: %d\n", tsArguments.isDumpIn); - printf("arg_list_len: %d\n", tsArguments.arg_list_len); + printf("host: %s\n", g_args.host); + printf("user: %s\n", g_args.user); + printf("password: %s\n", g_args.password); + printf("port: %u\n", g_args.port); + printf("cversion: %s\n", g_args.cversion); + printf("mysqlFlag: %d\n", g_args.mysqlFlag); + printf("outpath: %s\n", g_args.outpath); + printf("inpath: %s\n", g_args.inpath); + printf("resultFile: %s\n", g_args.resultFile); + printf("encode: %s\n", g_args.encode); + printf("all_databases: %d\n", g_args.all_databases); + printf("databases: %d\n", g_args.databases); + printf("schemaonly: %d\n", g_args.schemaonly); + printf("with_property: %d\n", g_args.with_property); + printf("start_time: %" PRId64 "\n", g_args.start_time); + printf("end_time: %" PRId64 "\n", g_args.end_time); + printf("data_batch: %d\n", g_args.data_batch); + printf("max_sql_len: %d\n", g_args.max_sql_len); + printf("table_batch: %d\n", g_args.table_batch); + printf("thread_num: %d\n", g_args.thread_num); + printf("allow_sys: %d\n", g_args.allow_sys); + printf("abort: %d\n", g_args.abort); + printf("isDumpIn: %d\n", g_args.isDumpIn); + printf("arg_list_len: %d\n", g_args.arg_list_len); + printf("debug_print: %d\n", g_args.debug_print); - for (int32_t i = 0; i < tsArguments.arg_list_len; i++) { - printf("arg_list[%d]: %s\n", i, tsArguments.arg_list[i]); + for (int32_t i = 0; i < g_args.arg_list_len; i++) { + printf("arg_list[%d]: %s\n", i, g_args.arg_list[i]); } - } + } printf("==============================\n"); - if (tsArguments.cversion[0] != 0){ - tstrncpy(version, tsArguments.cversion, 11); + if (g_args.cversion[0] != 0){ + tstrncpy(version, g_args.cversion, 11); } - if (taosCheckParam(&tsArguments) < 0) { + if (taosCheckParam(&g_args) < 0) { exit(EXIT_FAILURE); } - - g_fpOfResult = fopen(tsArguments.resultFile, "a"); + + g_fpOfResult = fopen(g_args.resultFile, "a"); if (NULL == g_fpOfResult) { - fprintf(stderr, "Failed to open %s for save result\n", tsArguments.resultFile); + fprintf(stderr, "Failed to open %s for save result\n", g_args.resultFile); return 1; }; fprintf(g_fpOfResult, "#############################################################################\n"); fprintf(g_fpOfResult, "============================== arguments config =============================\n"); { - fprintf(g_fpOfResult, "host: %s\n", tsArguments.host); - fprintf(g_fpOfResult, "user: %s\n", tsArguments.user); - fprintf(g_fpOfResult, "password: %s\n", tsArguments.password); - fprintf(g_fpOfResult, "port: %u\n", tsArguments.port); - fprintf(g_fpOfResult, "cversion: %s\n", tsArguments.cversion); - fprintf(g_fpOfResult, "mysqlFlag: %d\n", tsArguments.mysqlFlag); - fprintf(g_fpOfResult, "outpath: %s\n", tsArguments.outpath); - fprintf(g_fpOfResult, "inpath: %s\n", tsArguments.inpath); - fprintf(g_fpOfResult, "resultFile: %s\n", tsArguments.resultFile); - fprintf(g_fpOfResult, "encode: %s\n", tsArguments.encode); - fprintf(g_fpOfResult, "all_databases: %d\n", tsArguments.all_databases); - fprintf(g_fpOfResult, "databases: %d\n", tsArguments.databases); - fprintf(g_fpOfResult, "schemaonly: %d\n", tsArguments.schemaonly); - fprintf(g_fpOfResult, "with_property: %d\n", tsArguments.with_property); - fprintf(g_fpOfResult, "start_time: %" PRId64 "\n", tsArguments.start_time); - fprintf(g_fpOfResult, "end_time: %" PRId64 "\n", tsArguments.end_time); - fprintf(g_fpOfResult, "data_batch: %d\n", tsArguments.data_batch); - fprintf(g_fpOfResult, "max_sql_len: %d\n", tsArguments.max_sql_len); - fprintf(g_fpOfResult, "table_batch: %d\n", tsArguments.table_batch); - fprintf(g_fpOfResult, "thread_num: %d\n", tsArguments.thread_num); - fprintf(g_fpOfResult, "allow_sys: %d\n", tsArguments.allow_sys); - fprintf(g_fpOfResult, "abort: %d\n", tsArguments.abort); - fprintf(g_fpOfResult, "isDumpIn: %d\n", tsArguments.isDumpIn); - fprintf(g_fpOfResult, "arg_list_len: %d\n", tsArguments.arg_list_len); + fprintf(g_fpOfResult, "host: %s\n", g_args.host); + fprintf(g_fpOfResult, "user: %s\n", g_args.user); + fprintf(g_fpOfResult, "password: %s\n", g_args.password); + fprintf(g_fpOfResult, "port: %u\n", g_args.port); + fprintf(g_fpOfResult, "cversion: %s\n", g_args.cversion); + fprintf(g_fpOfResult, "mysqlFlag: %d\n", g_args.mysqlFlag); + fprintf(g_fpOfResult, "outpath: %s\n", g_args.outpath); + fprintf(g_fpOfResult, "inpath: %s\n", g_args.inpath); + fprintf(g_fpOfResult, "resultFile: %s\n", g_args.resultFile); + fprintf(g_fpOfResult, "encode: %s\n", g_args.encode); + fprintf(g_fpOfResult, "all_databases: %d\n", g_args.all_databases); + fprintf(g_fpOfResult, "databases: %d\n", g_args.databases); + fprintf(g_fpOfResult, "schemaonly: %d\n", g_args.schemaonly); + fprintf(g_fpOfResult, "with_property: %d\n", g_args.with_property); + fprintf(g_fpOfResult, "start_time: %" PRId64 "\n", g_args.start_time); + fprintf(g_fpOfResult, "end_time: %" PRId64 "\n", g_args.end_time); + fprintf(g_fpOfResult, "data_batch: %d\n", g_args.data_batch); + fprintf(g_fpOfResult, "max_sql_len: %d\n", g_args.max_sql_len); + fprintf(g_fpOfResult, "table_batch: %d\n", g_args.table_batch); + fprintf(g_fpOfResult, "thread_num: %d\n", g_args.thread_num); + fprintf(g_fpOfResult, "allow_sys: %d\n", g_args.allow_sys); + fprintf(g_fpOfResult, "abort: %d\n", g_args.abort); + fprintf(g_fpOfResult, "isDumpIn: %d\n", g_args.isDumpIn); + fprintf(g_fpOfResult, "arg_list_len: %d\n", g_args.arg_list_len); - for (int32_t i = 0; i < tsArguments.arg_list_len; i++) { - fprintf(g_fpOfResult, "arg_list[%d]: %s\n", i, tsArguments.arg_list[i]); + for (int32_t i = 0; i < g_args.arg_list_len; i++) { + fprintf(g_fpOfResult, "arg_list[%d]: %s\n", i, g_args.arg_list[i]); } } @@ -552,11 +615,11 @@ int main(int argc, char *argv[]) { time_t tTime = time(NULL); struct tm tm = *localtime(&tTime); - if (tsArguments.isDumpIn) { + if (g_args.isDumpIn) { fprintf(g_fpOfResult, "============================== DUMP IN ============================== \n"); fprintf(g_fpOfResult, "# DumpIn start time: %d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - if (taosDumpIn(&tsArguments) < 0) { + if (taosDumpIn(&g_args) < 0) { fprintf(g_fpOfResult, "\n"); fclose(g_fpOfResult); return -1; @@ -565,7 +628,7 @@ int main(int argc, char *argv[]) { fprintf(g_fpOfResult, "============================== DUMP OUT ============================== \n"); fprintf(g_fpOfResult, "# DumpOut start time: %d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - if (taosDumpOut(&tsArguments) < 0) { + if (taosDumpOut(&g_args) < 0) { fprintf(g_fpOfResult, "\n"); fclose(g_fpOfResult); return -1; @@ -573,9 +636,9 @@ int main(int argc, char *argv[]) { fprintf(g_fpOfResult, "\n============================== TOTAL STATISTICS ============================== \n"); fprintf(g_fpOfResult, "# total database count: %d\n", g_resultStatistics.totalDatabasesOfDumpOut); - fprintf(g_fpOfResult, "# total super table count: %d\n", g_resultStatistics.totalSuperTblsOfDumpOut); - fprintf(g_fpOfResult, "# total child table count: %"PRId64"\n", g_resultStatistics.totalChildTblsOfDumpOut); - fprintf(g_fpOfResult, "# total row count: %"PRId64"\n", g_resultStatistics.totalRowsOfDumpOut); + fprintf(g_fpOfResult, "# total super table count: %d\n", g_resultStatistics.totalSuperTblsOfDumpOut); + fprintf(g_fpOfResult, "# total child table count: %"PRId64"\n", g_resultStatistics.totalChildTblsOfDumpOut); + fprintf(g_fpOfResult, "# total row count: %"PRId64"\n", g_resultStatistics.totalRowsOfDumpOut); } fprintf(g_fpOfResult, "\n"); @@ -1236,8 +1299,8 @@ void* taosDumpOutWorkThreadFp(void *arg) FILE *fp = NULL; memset(tmpBuf, 0, TSDB_FILENAME_LEN + 128); - if (tsArguments.outpath[0] != 0) { - sprintf(tmpBuf, "%s/%s.tables.%d.sql", tsArguments.outpath, pThread->dbName, pThread->threadIndex); + if (g_args.outpath[0] != 0) { + sprintf(tmpBuf, "%s/%s.tables.%d.sql", g_args.outpath, pThread->dbName, pThread->threadIndex); } else { sprintf(tmpBuf, "%s.tables.%d.sql", pThread->dbName, pThread->threadIndex); } @@ -1270,7 +1333,7 @@ void* taosDumpOutWorkThreadFp(void *arg) ssize_t readLen = read(fd, &tableRecord, sizeof(STableRecord)); if (readLen <= 0) break; - int ret = taosDumpTable(tableRecord.name, tableRecord.metric, &tsArguments, fp, pThread->taosCon, pThread->dbName); + int ret = taosDumpTable(tableRecord.name, tableRecord.metric, &g_args, fp, pThread->taosCon, pThread->dbName); if (ret >= 0) { // TODO: sum table count and table rows by self pThread->tablesOfDumpOut++; @@ -1282,13 +1345,13 @@ void* taosDumpOutWorkThreadFp(void *arg) } tablesInOneFile++; - if (tablesInOneFile >= tsArguments.table_batch) { + if (tablesInOneFile >= g_args.table_batch) { fclose(fp); tablesInOneFile = 0; memset(tmpBuf, 0, TSDB_FILENAME_LEN + 128); - if (tsArguments.outpath[0] != 0) { - sprintf(tmpBuf, "%s/%s.tables.%d-%d.sql", tsArguments.outpath, pThread->dbName, pThread->threadIndex, fileNameIndex); + if (g_args.outpath[0] != 0) { + sprintf(tmpBuf, "%s/%s.tables.%d-%d.sql", g_args.outpath, pThread->dbName, pThread->threadIndex, fileNameIndex); } else { sprintf(tmpBuf, "%s.tables.%d-%d.sql", pThread->dbName, pThread->threadIndex, fileNameIndex); } @@ -1491,14 +1554,14 @@ int taosDumpDb(SDbInfo *dbInfo, struct arguments *arguments, FILE *fp, TAOS *tao taos_free_result(res); lseek(fd, 0, SEEK_SET); - int maxThreads = tsArguments.thread_num; + int maxThreads = g_args.thread_num; int tableOfPerFile ; - if (numOfTable <= tsArguments.thread_num) { + if (numOfTable <= g_args.thread_num) { tableOfPerFile = 1; maxThreads = numOfTable; } else { - tableOfPerFile = numOfTable / tsArguments.thread_num; - if (0 != numOfTable % tsArguments.thread_num) { + tableOfPerFile = numOfTable / g_args.thread_num; + if (0 != numOfTable % g_args.thread_num) { tableOfPerFile += 1; } } @@ -1806,9 +1869,9 @@ int taosDumpTableData(FILE *fp, char *tbname, struct arguments *arguments, TAOS* //} } - fprintf(fp, "\n"); + fprintf(fp, "\n"); atomic_add_fetch_64(&totalDumpOutRows, totalRows); - + taos_free_result(tmpResult); free(tmpBuffer); return totalRows; @@ -1824,7 +1887,7 @@ int taosCheckParam(struct arguments *arguments) { fprintf(stderr, "start time is larger than end time\n"); return -1; } - + if (arguments->arg_list_len == 0) { if ((!arguments->all_databases) && (!arguments->isDumpIn)) { fprintf(stderr, "taosdump requires parameters\n"); @@ -2214,7 +2277,7 @@ void* taosDumpInWorkThreadFp(void *arg) continue; } fprintf(stderr, "Success Open input file: %s\n", SQLFileName); - taosDumpInOneFile(pThread->taosCon, fp, tsfCharset, tsArguments.encode, SQLFileName); + taosDumpInOneFile(pThread->taosCon, fp, tsfCharset, g_args.encode, SQLFileName); } } diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index db03da4fe1..85d9f94b88 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -437,14 +437,14 @@ static int32_t mnodeCheckClusterCfgPara(const SClusterCfg *clusterCfg) { return TAOS_DN_OFF_TIME_ZONE_NOT_MATCH; } - if (0 != strncasecmp(clusterCfg->locale, tsLocale, strlen(tsLocale))) { - mError("\"locale\"[%s - %s] cfg parameters inconsistent", clusterCfg->locale, tsLocale); - return TAOS_DN_OFF_LOCALE_NOT_MATCH; - } - if (0 != strncasecmp(clusterCfg->charset, tsCharset, strlen(tsCharset))) { - mError("\"charset\"[%s - %s] cfg parameters inconsistent.", clusterCfg->charset, tsCharset); - return TAOS_DN_OFF_CHARSET_NOT_MATCH; - } + // if (0 != strncasecmp(clusterCfg->locale, tsLocale, strlen(tsLocale))) { + // mError("\"locale\"[%s - %s] cfg parameters inconsistent", clusterCfg->locale, tsLocale); + // return TAOS_DN_OFF_LOCALE_NOT_MATCH; + // } + // if (0 != strncasecmp(clusterCfg->charset, tsCharset, strlen(tsCharset))) { + // mError("\"charset\"[%s - %s] cfg parameters inconsistent.", clusterCfg->charset, tsCharset); + // return TAOS_DN_OFF_CHARSET_NOT_MATCH; + // } if (clusterCfg->enableBalance != tsEnableBalance) { mError("\"balance\"[%d - %d] cfg parameters inconsistent", clusterCfg->enableBalance, tsEnableBalance); @@ -628,6 +628,11 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) { bnNotify(); } + if (!tsEnableBalance) { + int32_t numOfMnodes = mnodeGetMnodesNum(); + if (numOfMnodes < tsNumOfMnodes) bnNotify(); + } + if (openVnodes != pDnode->openVnodes) { mnodeCheckUnCreatedVgroup(pDnode, pStatus->load, openVnodes); } diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c index 49473d3e06..ca6d6400ae 100644 --- a/src/mnode/src/mnodeMnode.c +++ b/src/mnode/src/mnodeMnode.c @@ -381,6 +381,8 @@ static bool mnodeAllOnline() { void *pIter = NULL; bool allOnline = true; + sdbUpdateMnodeRoles(); + while (1) { SMnodeObj *pMnode = NULL; pIter = mnodeGetNextMnode(pIter, &pMnode); diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 381cb11952..505d3c519c 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -315,6 +315,10 @@ void sdbUpdateAsync() { taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsSdbTmr); } +static int node_cmp(const void *l, const void *r) { + return ((SNodeInfo *)l)->nodeId - ((SNodeInfo *)r)->nodeId; +} + int32_t sdbUpdateSync(void *pMnodes) { SMInfos *pMinfos = pMnodes; if (!mnodeIsRunning()) { @@ -382,6 +386,8 @@ int32_t sdbUpdateSync(void *pMnodes) { return TSDB_CODE_SUCCESS; } + qsort(syncCfg.nodeInfo, syncCfg.replica, sizeof(syncCfg.nodeInfo[0]), node_cmp); + sdbInfo("vgId:1, work as mnode, replica:%d", syncCfg.replica); for (int32_t i = 0; i < syncCfg.replica; ++i) { sdbInfo("vgId:1, mnode:%d, %s:%d", syncCfg.nodeInfo[i].nodeId, syncCfg.nodeInfo[i].nodeFqdn, @@ -1019,7 +1025,7 @@ static int32_t sdbWriteToQueue(SSdbRow *pRow, int32_t qtype) { int32_t queued = atomic_add_fetch_32(&tsSdbMgmt.queuedMsg, 1); if (queued > MAX_QUEUED_MSG_NUM) { - sdbDebug("vgId:1, too many msg:%d in sdb queue, flow control", queued); + sdbInfo("vgId:1, too many msg:%d in sdb queue, flow control", queued); taosMsleep(1); } @@ -1131,4 +1137,4 @@ static void *sdbWorkerFp(void *pWorker) { int32_t sdbGetReplicaNum() { return tsSdbMgmt.cfg.replica; -} \ No newline at end of file +} diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 39eca8819d..2a8e941fcb 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -1037,6 +1037,19 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { SCreateTableMsg* pCreate = (SCreateTableMsg*)((char*)pCreate1 + sizeof(SCMCreateTableMsg)); + int16_t numOfTags = htons(pCreate->numOfTags); + if (numOfTags > TSDB_MAX_TAGS) { + mError("msg:%p, app:%p table:%s, failed to create, too many tags", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableName); + return TSDB_CODE_MND_TOO_MANY_TAGS; + } + + int16_t numOfColumns = htons(pCreate->numOfColumns); + int32_t numOfCols = numOfColumns + numOfTags; + if (numOfCols > TSDB_MAX_COLUMNS) { + mError("msg:%p, app:%p table:%s, failed to create, too many columns", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableName); + return TSDB_CODE_MND_TOO_MANY_COLUMNS; + } + SSTableObj * pStable = calloc(1, sizeof(SSTableObj)); if (pStable == NULL) { mError("msg:%p, app:%p table:%s, failed to create, no enough memory", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableName); @@ -1050,10 +1063,9 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { pStable->uid = (us << 24) + ((sdbGetVersion() & ((1ul << 16) - 1ul)) << 8) + (taosRand() & ((1ul << 8) - 1ul)); pStable->sversion = 0; pStable->tversion = 0; - pStable->numOfColumns = htons(pCreate->numOfColumns); - pStable->numOfTags = htons(pCreate->numOfTags); + pStable->numOfColumns = numOfColumns; + pStable->numOfTags = numOfTags; - int32_t numOfCols = pStable->numOfColumns + pStable->numOfTags; int32_t schemaSize = numOfCols * sizeof(SSchema); pStable->schema = (SSchema *)calloc(1, schemaSize); if (pStable->schema == NULL) { @@ -1064,11 +1076,6 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); - if (pStable->numOfColumns > TSDB_MAX_COLUMNS || pStable->numOfTags > TSDB_MAX_TAGS) { - mError("msg:%p, app:%p table:%s, failed to create, too many columns", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableName); - return TSDB_CODE_MND_INVALID_TABLE_NAME; - } - pStable->nextColId = 0; for (int32_t col = 0; col < numOfCols; col++) { @@ -1340,6 +1347,11 @@ static int32_t mnodeAddSuperTableColumn(SMnodeMsg *pMsg, SSchema schema[], int32 return TSDB_CODE_MND_APP_ERROR; } + if (pStable->numOfColumns + ncols + pStable->numOfTags > TSDB_MAX_COLUMNS) { + mError("msg:%p, app:%p stable:%s, add column, too many columns", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId); + return TSDB_CODE_MND_TOO_MANY_COLUMNS; + } + for (int32_t i = 0; i < ncols; i++) { if (mnodeFindSuperTableColumnIndex(pStable, schema[i].name) > 0) { mError("msg:%p, app:%p stable:%s, add column, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle, diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c index 7eb3122d83..7222c8d1a0 100644 --- a/src/mnode/src/mnodeVgroup.c +++ b/src/mnode/src/mnodeVgroup.c @@ -994,6 +994,7 @@ void mnodeSendSyncVgroupMsg(SVgObj *pVgroup) { mDebug("vgId:%d, send sync all vnodes msg, numOfVnodes:%d db:%s", pVgroup->vgId, pVgroup->numOfVnodes, pVgroup->dbName); for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { + if (pVgroup->vnodeGid[i].role != TAOS_SYNC_ROLE_SLAVE) continue; SRpcEpSet epSet = mnodeGetEpSetFromIp(pVgroup->vnodeGid[i].pDnode->dnodeEp); mDebug("vgId:%d, index:%d, send sync vnode msg to dnode %s", pVgroup->vgId, i, pVgroup->vnodeGid[i].pDnode->dnodeEp); diff --git a/src/os/inc/osArm32.h b/src/os/inc/osArm32.h index 24ff95522e..54835a1ca8 100644 --- a/src/os/inc/osArm32.h +++ b/src/os/inc/osArm32.h @@ -77,6 +77,7 @@ extern "C" { #include #include #include +#include #define TAOS_OS_FUNC_LZ4 #define BUILDIN_CLZL(val) __builtin_clzll(val) diff --git a/src/os/inc/osArm64.h b/src/os/inc/osArm64.h index 22f0000e96..76098f6846 100644 --- a/src/os/inc/osArm64.h +++ b/src/os/inc/osArm64.h @@ -78,6 +78,7 @@ extern "C" { #include #include #include +#include #ifdef __cplusplus } diff --git a/src/os/inc/osLinux32.h b/src/os/inc/osLinux32.h index cfef05368f..eee4999399 100644 --- a/src/os/inc/osLinux32.h +++ b/src/os/inc/osLinux32.h @@ -77,6 +77,7 @@ extern "C" { #include #include #include +#include #define TAOS_OS_FUNC_LZ4 #define BUILDIN_CLZL(val) __builtin_clzll(val) diff --git a/src/os/inc/osLinux64.h b/src/os/inc/osLinux64.h index a2febd51b7..0dfc819da3 100644 --- a/src/os/inc/osLinux64.h +++ b/src/os/inc/osLinux64.h @@ -75,6 +75,7 @@ extern "C" { #include #include #include +#include #ifndef _ALPINE #include #endif diff --git a/src/os/inc/osSocket.h b/src/os/inc/osSocket.h index 111fca712c..cf75b74a9a 100644 --- a/src/os/inc/osSocket.h +++ b/src/os/inc/osSocket.h @@ -68,6 +68,8 @@ void taosSetMaskSIGPIPE(); // TAOS_OS_FUNC_SOCKET_SETSOCKETOPT int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen); +int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen); + // TAOS_OS_FUNC_SOCKET_INET uint32_t taosInetAddr(char *ipAddr); const char *taosInetNtoa(struct in_addr ipInt); diff --git a/src/os/src/detail/osSocket.c b/src/os/src/detail/osSocket.c index 1186a6dd0a..db976acccd 100644 --- a/src/os/src/detail/osSocket.c +++ b/src/os/src/detail/osSocket.c @@ -71,6 +71,9 @@ int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *op return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen); } +int32_t taosGetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t* optlen) { + return getsockopt(socketfd, level, optname, optval, (socklen_t *)optlen); +} #endif #ifndef TAOS_OS_FUNC_SOCKET_INET diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 5ff574ec67..31ac70d6cd 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -86,7 +86,8 @@ typedef struct SResultRow { bool closed; // this result status: closed or opened uint32_t numOfRows; // number of rows of current time window SResultRowCellInfo* pCellInfo; // For each result column, there is a resultInfo - union {STimeWindow win; char* key;}; // start key of current result row + STimeWindow win; + char* key; // start key of current result row } SResultRow; typedef struct SGroupResInfo { @@ -189,6 +190,8 @@ typedef struct SQuery { bool stabledev; // super table stddev query int32_t interBufSize; // intermediate buffer sizse + int32_t havingNum; // having expr number + SOrderVal order; int16_t numOfCols; int16_t numOfTags; @@ -284,6 +287,7 @@ enum OPERATOR_TYPE_E { OP_Fill = 13, OP_MultiTableAggregate = 14, OP_MultiTableTimeInterval = 15, + OP_Having = 16, }; typedef struct SOperatorInfo { @@ -401,6 +405,11 @@ typedef struct SOffsetOperatorInfo { int64_t offset; } SOffsetOperatorInfo; +typedef struct SHavingOperatorInfo { + SArray* fp; +} SHavingOperatorInfo; + + typedef struct SFillOperatorInfo { SFillInfo *pFillInfo; SSDataBlock *pRes; diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index 3ce81787f0..c5ee172c40 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -98,6 +98,7 @@ typedef struct SQuerySqlNode { SLimitVal limit; // limit offset [optional] SLimitVal slimit; // group limit offset [optional] SStrToken sqlstr; // sql string in select clause + struct tSqlExpr *pHaving; // having clause [optional] } SQuerySqlNode; typedef struct STableNamePair { @@ -253,6 +254,11 @@ SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder); SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t index); SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder); +tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType); + +int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right); + +tSqlExpr *tSqlExprClone(tSqlExpr *pSrc); SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias); SFromInfo *setSubquery(SFromInfo* pFromInfo, SQuerySqlNode *pSqlNode); void *destroyFromInfo(SFromInfo* pFromInfo); @@ -272,7 +278,7 @@ void tSqlExprListDestroy(SArray *pList); SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, - SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit); + SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving); SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SQuerySqlNode *pSelect, int32_t type); diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index cdd8b0707a..cb8c9679ec 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -52,11 +52,20 @@ static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int return pResultRowInfo->pResult[slot]; } -static FORCE_INLINE char *getPosInResultPage(SQuery *pQuery, tFilePage* page, int32_t rowOffset, int16_t offset) { - assert(rowOffset >= 0 && pQuery != NULL); +static FORCE_INLINE char* getPosInResultPage(SQueryRuntimeEnv* pRuntimeEnv, tFilePage* page, int32_t rowOffset, + int16_t offset, int32_t size) { + assert(rowOffset >= 0 && pRuntimeEnv != NULL); + + SQuery* pQuery = pRuntimeEnv->pQuery; + int64_t pageSize = pRuntimeEnv->pResultBuf->pageSize; int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery); - return ((char *)page->data) + rowOffset + offset * numOfRows; + + // buffer overflow check + int64_t bufEnd = (rowOffset + offset * numOfRows + size); + assert(page->num <= pageSize && bufEnd <= page->num); + + return ((char*)page->data) + rowOffset + offset * numOfRows; } bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type); diff --git a/src/query/inc/sql.y b/src/query/inc/sql.y index 174b31a9c6..f9a4f1b51d 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -453,7 +453,7 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). { %type select {SQuerySqlNode*} %destructor select {destroyQuerySqlNode($$);} select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). { - A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G); + A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G, N); } select(A) ::= LP select(B) RP. {A = B;} @@ -471,7 +471,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); } // select client_version() // select server_state() select(A) ::= SELECT(T) selcollist(W). { - A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } // selcollist is a list of expressions that are to become the return @@ -842,4 +842,4 @@ cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); s %fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL - NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES. \ No newline at end of file + NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES. diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index f18d093b89..505057ef33 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2482,6 +2482,29 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) { } } + +/* + * keep the intermediate results during scan data blocks in the format of: + * +-----------------------------------+-------------one value pair-----------+------------next value pair-----------+ + * |-------------pointer area----------|----ts---+-----+-----n tags-----------|----ts---+-----+-----n tags-----------| + * +..[Value Pointer1][Value Pointer2].|timestamp|value|tags1|tags2|....|tagsn|timestamp|value|tags1|tags2|....|tagsn+ + */ +static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { + char *tmp = (char *)pTopBotInfo + sizeof(STopBotInfo); + pTopBotInfo->res = (tValuePair**) tmp; + tmp += POINTER_BYTES * pCtx->param[0].i64; + + size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen; +// assert(pCtx->param[0].i64 > 0); + + for (int32_t i = 0; i < pCtx->param[0].i64; ++i) { + pTopBotInfo->res[i] = (tValuePair*) tmp; + pTopBotInfo->res[i]->pTags = tmp + sizeof(tValuePair); + tmp += size; + } +} + + bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); if (pResInfo == NULL) { @@ -2495,6 +2518,10 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha return true; } + if ((void *)pTopBotInfo->res[0] != (void *)((char *)pTopBotInfo + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i64)) { + buildTopBotStruct(pTopBotInfo, pCtx); + } + tValuePair **pRes = (tValuePair**) pTopBotInfo->res; if (pCtx->functionId == TSDB_FUNC_TOP) { @@ -2534,27 +2561,6 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha } } -/* - * keep the intermediate results during scan data blocks in the format of: - * +-----------------------------------+-------------one value pair-----------+------------next value pair-----------+ - * |-------------pointer area----------|----ts---+-----+-----n tags-----------|----ts---+-----+-----n tags-----------| - * +..[Value Pointer1][Value Pointer2].|timestamp|value|tags1|tags2|....|tagsn|timestamp|value|tags1|tags2|....|tagsn+ - */ -static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { - char *tmp = (char *)pTopBotInfo + sizeof(STopBotInfo); - pTopBotInfo->res = (tValuePair**) tmp; - tmp += POINTER_BYTES * pCtx->param[0].i64; - - size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen; -// assert(pCtx->param[0].i64 > 0); - - for (int32_t i = 0; i < pCtx->param[0].i64; ++i) { - pTopBotInfo->res[i] = (tValuePair*) tmp; - pTopBotInfo->res[i]->pTags = tmp + sizeof(tValuePair); - tmp += size; - } -} - static bool top_bottom_function_setup(SQLFunctionCtx *pCtx) { if (!function_setup(pCtx)) { return false; @@ -2771,14 +2777,16 @@ static void percentile_function(SQLFunctionCtx *pCtx) { SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) { + pInfo->stage += 1; + // all data are null, set it completed if (pInfo->numOfElems == 0) { pResInfo->complete = true; + + return; } else { pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval); } - - pInfo->stage += 1; } // the first stage, only acquire the min/max value @@ -2857,14 +2865,16 @@ static void percentile_function_f(SQLFunctionCtx *pCtx, int32_t index) { SPercentileInfo *pInfo = (SPercentileInfo *)GET_ROWCELL_INTERBUF(pResInfo); if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) { + pInfo->stage += 1; + // all data are null, set it completed if (pInfo->numOfElems == 0) { pResInfo->complete = true; + + return; } else { pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval); } - - pInfo->stage += 1; } if (pInfo->stage == 0) { diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index e6f5eabd1c..2b6416786e 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -105,6 +105,30 @@ int32_t getMaximumIdleDurationSec() { return tsShellActivityTimer * 2; } + +int64_t genQueryId(void) { + int64_t uid = 0; + int64_t did = tsDnodeId; + + uid = did << 54; + + int64_t pid = ((int64_t)taosGetPId()) & 0x3FF; + + uid |= pid << 44; + + int64_t ts = taosGetTimestampMs() & 0x1FFFFFFFF; + + uid |= ts << 11; + + int64_t sid = atomic_add_fetch_64(&queryHandleId, 1) & 0x7FF; + + uid |= sid; + + return uid; +} + + + static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); if (pQuery->interval.intervalUnit != 'n' && pQuery->interval.intervalUnit != 'y') { @@ -181,6 +205,7 @@ static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntime static SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); static SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); static SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); +static SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); static void destroySFillOperatorInfo(void* param, int32_t numOfOutput); @@ -200,6 +225,7 @@ static bool isPointInterpoQuery(SQuery *pQuery); static void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo); static void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable); static void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr); +static void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes); static void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, SQLFunctionCtx* pCtx, int32_t* rowCellInfoOffset, int32_t numOfOutput, int32_t groupIndex); @@ -1330,6 +1356,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); int16_t bytes = pColInfoData->info.bytes; int16_t type = pColInfoData->info.type; + SQuery *pQuery = pRuntimeEnv->pQuery; if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) { qError("QInfo:%"PRIu64" group by not supported on double/float columns, abort", GET_QID(pRuntimeEnv)); @@ -1350,6 +1377,10 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn memcpy(pInfo->prevData, val, bytes); + if (pQuery->stableQuery && pQuery->stabledev && (pRuntimeEnv->prevResult != NULL)) { + setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, val, bytes); + } + int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, pInfo, pOperator->numOfOutput, val, type, bytes, item->groupIndex); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code @@ -1813,6 +1844,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf } } + if (pQuery->havingNum > 0) { + pRuntimeEnv->proot = createHavingOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr1, pQuery->numOfOutput); + } + if (pQuery->limit.offset > 0) { pRuntimeEnv->proot = createOffsetOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); } @@ -1843,6 +1878,19 @@ static void doFreeQueryHandle(SQueryRuntimeEnv* pRuntimeEnv) { assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL); } +static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQuery *pQuery) { + if (isTsCompQuery(pQuery) && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock && taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) { + SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); + if (pColInfoData) { + FILE *f = *(FILE **)pColInfoData->pData; // TODO refactor + if (f) { + fclose(f); + *(FILE **)pColInfoData->pData = NULL; + } + } + } +} + static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; SQInfo* pQInfo = (SQInfo*) pRuntimeEnv->qinfo; @@ -1861,6 +1909,8 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { destroyResultBuf(pRuntimeEnv->pResultBuf); doFreeQueryHandle(pRuntimeEnv); + destroyTsComp(pRuntimeEnv, pQuery); + pRuntimeEnv->pTsBuf = tsBufDestroy(pRuntimeEnv->pTsBuf); tfree(pRuntimeEnv->keyBuf); @@ -1870,14 +1920,15 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { taosHashCleanup(pRuntimeEnv->pResultRowHashTable); pRuntimeEnv->pResultRowHashTable = NULL; - pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool); - taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult); - pRuntimeEnv->prevResult = NULL; - taosHashCleanup(pRuntimeEnv->pTableRetrieveTsMap); pRuntimeEnv->pTableRetrieveTsMap = NULL; destroyOperatorInfo(pRuntimeEnv->proot); + + pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool); + taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult); + pRuntimeEnv->prevResult = NULL; + } static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) { @@ -2101,6 +2152,40 @@ static bool onlyFirstQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSD static bool onlyLastQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } +static int32_t updateBlockLoadStatus(SQuery *pQuery, int32_t status) { + bool hasFirstLastFunc = false; + bool hasOtherFunc = false; + + if (status == BLK_DATA_ALL_NEEDED || status == BLK_DATA_DISCARD) { + return status; + } + + for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { + int32_t functionId = pQuery->pExpr1[i].base.functionId; + + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG || + functionId == TSDB_FUNC_TAG_DUMMY) { + continue; + } + + if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) { + hasFirstLastFunc = true; + } else { + hasOtherFunc = true; + } + } + + if (hasFirstLastFunc && status == BLK_DATA_NO_NEEDED) { + if(!hasOtherFunc) { + return BLK_DATA_DISCARD; + } else{ + return BLK_DATA_ALL_NEEDED; + } + } + + return status; +} + static void doExchangeTimeWindow(SQInfo* pQInfo, STimeWindow* win) { SQuery* pQuery = &pQInfo->query; size_t t = taosArrayGetSize(pQuery->tableGroupInfo.pGroupList); @@ -2542,11 +2627,12 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa pBlock->pDataBlock = NULL; pBlock->pBlockStatis = NULL; + SQInfo* pQInfo = pRuntimeEnv->qinfo; SQuery* pQuery = pRuntimeEnv->pQuery; + int64_t groupId = pQuery->current->groupIndex; bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); - SQInfo* pQInfo = pRuntimeEnv->qinfo; SQueryCostInfo* pCost = &pQInfo->summary; if (pRuntimeEnv->pTsBuf != NULL) { @@ -2603,7 +2689,9 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa } SDataBlockInfo* pBlockInfo = &pBlock->info; - if ((*status) == BLK_DATA_NO_NEEDED) { + *status = updateBlockLoadStatus(pRuntimeEnv->pQuery, *status); + + if ((*status) == BLK_DATA_NO_NEEDED || (*status) == BLK_DATA_DISCARD) { qDebug("QInfo:%"PRIu64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows); pCost->discardBlocks += 1; @@ -3236,7 +3324,7 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe continue; } - pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQuery, bufPage, pResult->offset, offset); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv, bufPage, pResult->offset, offset, pCtx[i].outputBytes); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; @@ -3294,7 +3382,7 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF int16_t offset = 0; for (int32_t i = 0; i < numOfCols; ++i) { - pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQuery, page, pResult->offset, offset); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv, page, pResult->offset, offset, pCtx[i].outputBytes); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; @@ -3411,6 +3499,42 @@ void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx } +void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr, char* val, int16_t bytes) { + SQuery* pQuery = pRuntimeEnv->pQuery; + + int32_t numOfExprs = pQuery->numOfOutput; + for(int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExprInfo = &(pExpr[i]); + if (pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) { + continue; + } + + SSqlFuncMsg* pFuncMsg = &pExprInfo->base; + + pCtx[i].param[0].arr = NULL; + pCtx[i].param[0].nType = TSDB_DATA_TYPE_INT; // avoid freeing the memory by setting the type to be int + + // TODO use hash to speedup this loop + int32_t numOfGroup = (int32_t)taosArrayGetSize(pRuntimeEnv->prevResult); + for (int32_t j = 0; j < numOfGroup; ++j) { + SInterResult* p = taosArrayGet(pRuntimeEnv->prevResult, j); + if (bytes == 0 || memcmp(p->tags, val, bytes) == 0) { + int32_t numOfCols = (int32_t)taosArrayGetSize(p->pResult); + for (int32_t k = 0; k < numOfCols; ++k) { + SStddevInterResult* pres = taosArrayGet(p->pResult, k); + if (pres->colId == pFuncMsg->colInfo.colId) { + pCtx[i].param[0].arr = pres->pResult; + break; + } + } + } + } + } + +} + + + /* * There are two cases to handle: * @@ -3466,8 +3590,6 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { */ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock) { - SQuery *pQuery = pRuntimeEnv->pQuery; - int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows @@ -3502,7 +3624,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* int32_t bytes = pColInfoData->info.bytes; char *out = pColInfoData->pData + numOfResult * bytes; - char *in = getPosInResultPage(pQuery, page, pRow->offset, offset); + char *in = getPosInResultPage(pRuntimeEnv, page, pRow->offset, offset, bytes); memcpy(out, in, bytes * numOfRowsToCopy); offset += bytes; @@ -3972,7 +4094,7 @@ static SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, in return pFillCol; } -int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *tsdb, int32_t vgId, bool isSTableQuery) { +int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery *pQuery = pQInfo->runtimeEnv.pQuery; @@ -3983,8 +4105,6 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts pQuery->timeWindowInterpo = timeWindowInterpoRequired(pQuery); pQuery->stabledev = isStabledev(pQuery); - pRuntimeEnv->prevResult = prevResult; - setScanLimitationByResultBuffer(pQuery); int32_t code = setupQueryHandle(tsdb, pQInfo, isSTableQuery); @@ -4626,6 +4746,111 @@ static SSDataBlock* doOffset(void* param) { } } + +bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem, __filter_func_t fp) { + char* input = p->pData + p->info.bytes * rid; + bool isnull = isNull(input, p->info.type); + if (isnull) { + return (fp == isNullOperator) ? true : false; + } else { + if (fp == notNullOperator) { + return true; + } else if (fp == isNullOperator) { + return false; + } + } + + if (fp(filterElem, input, input, p->info.type)) { + return true; + } + + return false; +} + + +void doHavingImpl(SOperatorInfo *pOperator, SSDataBlock *pBlock) { + SHavingOperatorInfo* pInfo = pOperator->info; + int32_t f = 0; + int32_t allQualified = 1; + int32_t exprQualified = 0; + + for (int32_t r = 0; r < pBlock->info.rows; ++r) { + allQualified = 1; + + for (int32_t i = 0; i < pOperator->numOfOutput; ++i) { + SExprInfo* pExprInfo = &(pOperator->pExpr[i]); + if (pExprInfo->pFilter == NULL) { + continue; + } + + SArray* es = taosArrayGetP(pInfo->fp, i); + assert(es); + + size_t fpNum = taosArrayGetSize(es); + + exprQualified = 0; + for (int32_t m = 0; m < fpNum; ++m) { + __filter_func_t fp = taosArrayGetP(es, m); + + assert(fp); + + //SColIndex* colIdx = &pExprInfo->base.colInfo; + SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, i); + + SColumnFilterElem filterElem = {.filterInfo = pExprInfo->pFilter[m]}; + + if (doFilterData(p, r, &filterElem, fp)) { + exprQualified = 1; + break; + } + } + + if (exprQualified == 0) { + allQualified = 0; + break; + } + } + + if (allQualified == 0) { + continue; + } + + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData *pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + + int16_t bytes = pColInfoData->info.bytes; + memmove(pColInfoData->pData + f * bytes, pColInfoData->pData + bytes * r, bytes); + } + + ++f; + } + + pBlock->info.rows = f; +} + +static SSDataBlock* doHaving(void* param) { + SOperatorInfo *pOperator = (SOperatorInfo *)param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + + while (1) { + SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); + if (pBlock == NULL) { + setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + doHavingImpl(pOperator, pBlock); + + return pBlock; + } +} + + static SSDataBlock* doIntervalAgg(void* param) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { @@ -4976,6 +5201,13 @@ static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) { pInfo->pRes = destroyOutputBuf(pInfo->pRes); } +static void destroyHavingOperatorInfo(void* param, int32_t numOfOutput) { + SHavingOperatorInfo* pInfo = (SHavingOperatorInfo*) param; + if (pInfo->fp) { + taosArrayDestroy(pInfo->fp); + } +} + SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); @@ -5032,6 +5264,83 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } + +int32_t initFilterFp(SExprInfo* pExpr, int32_t numOfOutput, SArray** fps) { + __filter_func_t fp = NULL; + + *fps = taosArrayInit(numOfOutput, sizeof(SArray*)); + if (*fps == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < numOfOutput; ++i) { + SExprInfo* pExprInfo = &(pExpr[i]); + SColIndex* colIdx = &pExprInfo->base.colInfo; + + if (pExprInfo->pFilter == NULL || !TSDB_COL_IS_NORMAL_COL(colIdx->flag)) { + taosArrayPush(*fps, &fp); + + continue; + } + + int32_t filterNum = pExprInfo->base.filterNum; + SColumnFilterInfo *filterInfo = pExprInfo->pFilter; + + SArray* es = taosArrayInit(filterNum, sizeof(__filter_func_t)); + + for (int32_t j = 0; j < filterNum; ++j) { + int32_t lower = filterInfo->lowerRelOptr; + int32_t upper = filterInfo->upperRelOptr; + if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) { + qError("invalid rel optr"); + taosArrayDestroy(es); + return TSDB_CODE_QRY_APP_ERROR; + } + + __filter_func_t ffp = getFilterOperator(lower, upper); + if (ffp == NULL) { + qError("invalid filter info"); + taosArrayDestroy(es); + return TSDB_CODE_QRY_APP_ERROR; + } + + taosArrayPush(es, &ffp); + + filterInfo += 1; + } + + taosArrayPush(*fps, &es); + } + + return TSDB_CODE_SUCCESS; +} + +SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { + SHavingOperatorInfo* pInfo = calloc(1, sizeof(SHavingOperatorInfo)); + + initFilterFp(pExpr, numOfOutput, &pInfo->fp); + + assert(pInfo->fp); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + + pOperator->name = "HavingOperator"; + pOperator->operatorType = OP_Having; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->numOfOutput = numOfOutput; + pOperator->pExpr = pExpr; + pOperator->upstream = upstream; + pOperator->exec = doHaving; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->cleanup = destroyHavingOperatorInfo; + + return pOperator; +} + + + SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { SLimitOperatorInfo* pInfo = calloc(1, sizeof(SLimitOperatorInfo)); pInfo->limit = pRuntimeEnv->pQuery->limit.limit; @@ -5603,9 +5912,35 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pExprMsg->functionId = htons(pExprMsg->functionId); pExprMsg->numOfParams = htons(pExprMsg->numOfParams); pExprMsg->resColId = htons(pExprMsg->resColId); + pExprMsg->filterNum = htonl(pExprMsg->filterNum); pMsg += sizeof(SSqlFuncMsg); + SColumnFilterInfo* pExprFilterInfo = pExprMsg->filterInfo; + + pMsg += sizeof(SColumnFilterInfo) * pExprMsg->filterNum; + + for (int32_t f = 0; f < pExprMsg->filterNum; ++f) { + SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pExprFilterInfo; + + pFilterMsg->filterstr = htons(pFilterMsg->filterstr); + + if (pFilterMsg->filterstr) { + pFilterMsg->len = htobe64(pFilterMsg->len); + + pFilterMsg->pz = (int64_t)pMsg; + pMsg += (pFilterMsg->len + 1); + } else { + pFilterMsg->lowerBndi = htobe64(pFilterMsg->lowerBndi); + pFilterMsg->upperBndi = htobe64(pFilterMsg->upperBndi); + } + + pFilterMsg->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); + pFilterMsg->upperRelOptr = htons(pFilterMsg->upperRelOptr); + + pExprFilterInfo++; + } + for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { pExprMsg->arg[j].argType = htons(pExprMsg->arg[j].argType); pExprMsg->arg[j].argBytes = htons(pExprMsg->arg[j].argBytes); @@ -5790,6 +6125,42 @@ _cleanup: return code; } +int32_t cloneExprFilterInfo(SColumnFilterInfo **dst, SColumnFilterInfo* src, int32_t filterNum) { + if (filterNum <= 0) { + return TSDB_CODE_SUCCESS; + } + + *dst = calloc(filterNum, sizeof(*src)); + if (*dst == NULL) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy(*dst, src, sizeof(*src) * filterNum); + + for (int32_t i = 0; i < filterNum; i++) { + if ((*dst)[i].filterstr && dst[i]->len > 0) { + void *pz = calloc(1, (size_t)(*dst)[i].len + 1); + + if (pz == NULL) { + if (i == 0) { + free(*dst); + } else { + freeColumnFilterInfo(*dst, i); + } + + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy(pz, (void *)src->pz, (size_t)src->len + 1); + + (*dst)[i].pz = (int64_t)pz; + } + } + + return TSDB_CODE_SUCCESS; +} + + static int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTableMsg *pQueryMsg) { qDebug("qmsg:%p create arithmetic expr from binary", pQueryMsg); @@ -5903,6 +6274,13 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu type = s->type; bytes = s->bytes; } + + if (pExprs[i].base.filterNum > 0) { + int32_t ret = cloneExprFilterInfo(&pExprs[i].pFilter, pExprMsg[i]->filterInfo, pExprMsg[i]->filterNum); + if (ret) { + return ret; + } + } } int32_t param = (int32_t)pExprs[i].base.arg[0].argValue.i64; @@ -6143,6 +6521,8 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr goto _cleanup_qinfo; } + pQInfo->qId = *qId; + // to make sure third party won't overwrite this structure pQInfo->signature = pQInfo; SQuery* pQuery = &pQInfo->query; @@ -6192,6 +6572,10 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { pQuery->tagLen += pExprs[col].bytes; } + + if (pExprs[col].pFilter) { + ++pQuery->havingNum; + } } doUpdateExprColumnIndex(pQuery); @@ -6275,8 +6659,6 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr // todo refactor pQInfo->query.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); - pQInfo->qId = atomic_add_fetch_64(&queryHandleId, 1); - *qId = pQInfo->qId; qDebug("qmsg:%p QInfo:%" PRIu64 "-%p created", pQueryMsg, pQInfo->qId, pQInfo); return pQInfo; @@ -6295,6 +6677,10 @@ _cleanup_qinfo: tExprTreeDestroy(pExprInfo->pExpr, NULL); pExprInfo->pExpr = NULL; } + + if (pExprInfo->pFilter) { + freeColumnFilterInfo(pExprInfo->pFilter, pExprInfo->base.filterNum); + } } tfree(pExprs); @@ -6340,6 +6726,8 @@ int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *p SArray* prevResult = NULL; if (pQueryMsg->prevResultLen > 0) { prevResult = interResFromBinary(param->prevResult, pQueryMsg->prevResultLen); + + pRuntimeEnv->prevResult = prevResult; } pQuery->precision = tsdbGetCfg(tsdb)->precision; @@ -6361,7 +6749,7 @@ int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *p } // filter the qualified - if ((code = doInitQInfo(pQInfo, pTsBuf, prevResult, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) { + if ((code = doInitQInfo(pQInfo, pTsBuf, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) { goto _error; } @@ -6379,7 +6767,7 @@ void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) { } for (int32_t i = 0; i < numOfFilters; i++) { - if (pFilter[i].filterstr) { + if (pFilter[i].filterstr && pFilter[i].pz) { free((void*)(pFilter[i].pz)); } } @@ -6421,6 +6809,10 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { if (pExprInfo[i].pExpr != NULL) { tExprTreeDestroy(pExprInfo[i].pExpr, NULL); } + + if (pExprInfo[i].pFilter) { + freeColumnFilterInfo(pExprInfo[i].pFilter, pExprInfo[i].base.filterNum); + } } tfree(pExprInfo); @@ -6436,6 +6828,9 @@ void freeQInfo(SQInfo *pQInfo) { SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; releaseQueryBuf(pRuntimeEnv->tableqinfoGroupInfo.numOfTables); + + doDestroyTableQueryInfo(&pRuntimeEnv->tableqinfoGroupInfo); + teardownQueryRuntimeEnv(&pQInfo->runtimeEnv); SQuery *pQuery = pQInfo->runtimeEnv.pQuery; @@ -6471,7 +6866,6 @@ void freeQInfo(SQInfo *pQInfo) { } } - doDestroyTableQueryInfo(&pRuntimeEnv->tableqinfoGroupInfo); tfree(pQInfo->pBuf); tfree(pQInfo->sql); @@ -6521,6 +6915,7 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { } fclose(f); + *(FILE **)pColInfoData->pData = NULL; } // all data returned, set query over diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index a73f385282..73b5b81e52 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -266,6 +266,7 @@ int32_t tExtMemBufferFlush(tExtMemBuffer *pMemBuffer) { size_t retVal = fwrite((char *)&(first->item), pMemBuffer->pageSize, 1, pMemBuffer->file); if (retVal <= 0) { // failed to write to buffer, may be not enough space ret = TAOS_SYSTEM_ERROR(errno); + pMemBuffer->pHead = first; return ret; } diff --git a/src/query/src/qFilterfunc.c b/src/query/src/qFilterfunc.c index 884f7e653f..dabce88423 100644 --- a/src/query/src/qFilterfunc.c +++ b/src/query/src/qFilterfunc.c @@ -124,7 +124,7 @@ bool greaterEqualOperator(SColumnFilterElem *pFilter, const char *minval, const bool equalOperator(SColumnFilterElem *pFilter, const char *minval, const char *maxval, int16_t type) { SColumnFilterInfo *pFilterInfo = &pFilter->filterInfo; - if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { + if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TIMESTAMP) { int64_t minv = -1, maxv = -1; GET_TYPED_DATA(minv, int64_t, type, minval); GET_TYPED_DATA(maxv, int64_t, type, maxval); @@ -202,7 +202,7 @@ bool likeOperator(SColumnFilterElem *pFilter, const char *minval, const char *ma bool notEqualOperator(SColumnFilterElem *pFilter, const char *minval, const char *maxval, int16_t type) { SColumnFilterInfo *pFilterInfo = &pFilter->filterInfo; - if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { + if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_TIMESTAMP) { int64_t minv = -1, maxv = -1; GET_TYPED_DATA(minv, int64_t, type, minval); GET_TYPED_DATA(maxv, int64_t, type, maxval); diff --git a/src/query/src/qResultbuf.c b/src/query/src/qResultbuf.c index c5dd6b3cac..f83caf2d8f 100644 --- a/src/query/src/qResultbuf.c +++ b/src/query/src/qResultbuf.c @@ -287,6 +287,10 @@ static void lruListMoveToFront(SList *pList, SPageInfo* pi) { tdListPrependNode(pList, pi->pn); } +static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { + return pageSize + POINTER_BYTES + 2 + sizeof(tFilePage); +} + tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) { pResultBuf->statis.getPages += 1; @@ -311,7 +315,7 @@ tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32 // allocate buf if (availablePage == NULL) { - pi->pData = calloc(1, pResultBuf->pageSize + POINTER_BYTES + 2); // add extract bytes in case of zipped buffer increased. + pi->pData = calloc(1, getAllocPageSize(pResultBuf->pageSize)); // add extract bytes in case of zipped buffer increased. } else { pi->pData = availablePage; } @@ -355,7 +359,7 @@ tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) { } if (availablePage == NULL) { - (*pi)->pData = calloc(1, pResultBuf->pageSize + POINTER_BYTES); + (*pi)->pData = calloc(1, getAllocPageSize(pResultBuf->pageSize)); } else { (*pi)->pData = availablePage; } diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index dc1be4fe01..b75032967a 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -310,6 +310,77 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { return pExpr; } +static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right) { + return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1; +} + + +int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { + if ((left == NULL && right) || (left && right == NULL)) { + return 1; + } + + if (left->type != right->type) { + return 1; + } + + if (left->tokenId != right->tokenId) { + return 1; + } + + if (left->functionId != right->functionId) { + return 1; + } + + if ((left->pLeft && right->pLeft == NULL) + || (left->pLeft == NULL && right->pLeft) + || (left->pRight && right->pRight == NULL) + || (left->pRight == NULL && right->pRight) + || (left->pParam && right->pParam == NULL) + || (left->pParam == NULL && right->pParam)) { + return 1; + } + + if (tVariantCompare(&left->value, &right->value)) { + return 1; + } + + if (tStrTokenCompare(&left->colInfo, &right->colInfo)) { + return 1; + } + + + if (right->pParam && left->pParam) { + size_t size = taosArrayGetSize(right->pParam); + if (left->pParam && taosArrayGetSize(left->pParam) != size) { + return 1; + } + + for (int32_t i = 0; i < size; i++) { + tSqlExprItem* pLeftElem = taosArrayGet(left->pParam, i); + tSqlExpr* pSubLeft = pLeftElem->pNode; + tSqlExprItem* pRightElem = taosArrayGet(left->pParam, i); + tSqlExpr* pSubRight = pRightElem->pNode; + + if (tSqlExprCompare(pSubLeft, pSubRight)) { + return 1; + } + } + } + + if (left->pLeft && tSqlExprCompare(left->pLeft, right->pLeft)) { + return 1; + } + + if (left->pRight && tSqlExprCompare(left->pRight, right->pRight)) { + return 1; + } + + return 0; +} + + + tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) { tSqlExpr *pExpr = calloc(1, sizeof(tSqlExpr)); @@ -640,7 +711,7 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) { SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, - SLimitVal *psLimit) { + SLimitVal *psLimit, tSqlExpr *pHaving) { assert(pSelectList != NULL); SQuerySqlNode *pSqlNode = calloc(1, sizeof(SQuerySqlNode)); @@ -655,6 +726,7 @@ SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SF pSqlNode->pSortOrder = pSortOrder; pSqlNode->pWhere = pWhere; pSqlNode->fillType = pFill; + pSqlNode->pHaving = pHaving; if (pLimit != NULL) { pSqlNode->limit = *pLimit; @@ -717,6 +789,9 @@ void destroyQuerySqlNode(SQuerySqlNode *pQuerySql) { tSqlExprDestroy(pQuerySql->pWhere); pQuerySql->pWhere = NULL; + + tSqlExprDestroy(pQuerySql->pHaving); + pQuerySql->pHaving = NULL; taosArrayDestroyEx(pQuerySql->pSortOrder, freeVariant); pQuerySql->pSortOrder = NULL; diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index da7dbcd501..aa793add84 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -66,8 +66,8 @@ void cleanupResultRowInfo(SResultRowInfo *pResultRowInfo) { return; } - if (pResultRowInfo->type == TSDB_DATA_TYPE_BINARY || pResultRowInfo->type == TSDB_DATA_TYPE_NCHAR) { - for(int32_t i = 0; i < pResultRowInfo->size; ++i) { + for(int32_t i = 0; i < pResultRowInfo->size; ++i) { + if (pResultRowInfo->pResult[i]) { tfree(pResultRowInfo->pResult[i]->key); } } @@ -140,7 +140,7 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 SResultRowCellInfo *pResultInfo = &pResultRow->pCellInfo[i]; int16_t size = pRuntimeEnv->pQuery->pExpr1[i].bytes; - char * s = getPosInResultPage(pRuntimeEnv->pQuery, page, pResultRow->offset, offset); + char * s = getPosInResultPage(pRuntimeEnv, page, pResultRow->offset, offset, size); memset(s, 0, size); offset += size; @@ -153,11 +153,8 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 pResultRow->offset = -1; pResultRow->closed = false; - if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - tfree(pResultRow->key); - } else { - pResultRow->win = TSWINDOW_INITIALIZER; - } + tfree(pResultRow->key); + pResultRow->win = TSWINDOW_INITIALIZER; } // TODO refactor: use macro diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index 2ff0c9676e..84cd7fe93b 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -197,6 +197,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi return code; } + bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { SQInfo *pQInfo = (SQInfo *)qinfo; assert(pQInfo && pQInfo->signature == pQInfo); @@ -475,7 +476,7 @@ void qCleanupQueryMgmt(void* pQMgmt) { qDebug("vgId:%d, queryMgmt cleanup completed", vgId); } -void** qRegisterQInfo(void* pMgmt, uint64_t qId, uint64_t qInfo) { +void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo) { if (pMgmt == NULL) { terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; @@ -516,8 +517,7 @@ void** qAcquireQInfo(void* pMgmt, uint64_t _key) { return NULL; } - TSDB_CACHE_PTR_TYPE key = (TSDB_CACHE_PTR_TYPE)_key; - void** handle = taosCacheAcquireByKey(pQueryMgmt->qinfoPool, &key, sizeof(TSDB_CACHE_PTR_TYPE)); + void** handle = taosCacheAcquireByKey(pQueryMgmt->qinfoPool, &_key, sizeof(_key)); if (handle == NULL || *handle == NULL) { terrno = TSDB_CODE_QRY_INVALID_QHANDLE; return NULL; diff --git a/src/query/src/sql.c b/src/query/src/sql.c index 28208e532a..3c22bd85cc 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -23,6 +23,7 @@ ** input grammar file: */ #include +#include /************ Begin %include sections from the grammar ************************/ #include @@ -76,8 +77,10 @@ ** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_PARAM Code to pass %extra_argument as a subroutine parameter ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser +** ParseCTX_* As ParseARG_ except for %extra_context ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. @@ -97,39 +100,46 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 264 +#define YYNOCODE 262 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SCreateTableSql* yy14; - int yy20; - tSqlExpr* yy118; - SArray* yy159; - SIntervalVal yy184; - SCreatedTableInfo yy206; - SSessionWindowVal yy249; - SQuerySqlNode* yy272; - int64_t yy317; - SCreateDbInfo yy322; - SCreateAcctInfo yy351; - SSubclauseInfo* yy391; - TAOS_FIELD yy407; - SLimitVal yy440; - tVariant yy488; - SFromInfo* yy514; + SLimitVal yy18; + SFromInfo* yy70; + SSessionWindowVal yy87; + SCreateDbInfo yy94; + int yy116; + SSubclauseInfo* yy141; + tSqlExpr* yy170; + SCreateTableSql* yy194; + tVariant yy218; + SIntervalVal yy220; + SCreatedTableInfo yy252; + SQuerySqlNode* yy254; + SCreateAcctInfo yy419; + SArray* yy429; + TAOS_FIELD yy451; + int64_t yy481; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define ParseARG_SDECL SSqlInfo* pInfo; #define ParseARG_PDECL ,SSqlInfo* pInfo -#define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo -#define ParseARG_STORE yypParser->pInfo = pInfo +#define ParseARG_PARAM ,pInfo +#define ParseARG_FETCH SSqlInfo* pInfo=yypParser->pInfo; +#define ParseARG_STORE yypParser->pInfo=pInfo; +#define ParseCTX_SDECL +#define ParseCTX_PDECL +#define ParseCTX_PARAM +#define ParseCTX_FETCH +#define ParseCTX_STORE #define YYFALLBACK 1 #define YYNSTATE 315 #define YYNRULE 267 +#define YYNRULE_WITH_ACTION 267 #define YYNTOKEN 187 #define YY_MAX_SHIFT 314 #define YY_MIN_SHIFTREDUCE 506 @@ -140,6 +150,7 @@ typedef union { #define YY_MIN_REDUCE 776 #define YY_MAX_REDUCE 1042 /************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -204,225 +215,226 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (680) +#define YY_ACTTAB_COUNT (681) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 133, 553, 202, 312, 206, 140, 943, 226, 140, 554, - /* 10 */ 774, 314, 17, 47, 48, 140, 51, 52, 30, 181, + /* 0 */ 133, 553, 202, 312, 206, 140, 943, 17, 85, 554, + /* 10 */ 774, 314, 179, 47, 48, 140, 51, 52, 30, 181, /* 20 */ 214, 41, 181, 50, 262, 55, 53, 57, 54, 1023, - /* 30 */ 922, 209, 1024, 46, 45, 179, 181, 44, 43, 42, - /* 40 */ 47, 48, 920, 51, 52, 208, 1024, 214, 41, 553, - /* 50 */ 50, 262, 55, 53, 57, 54, 934, 554, 185, 203, + /* 30 */ 922, 209, 1024, 46, 45, 185, 181, 44, 43, 42, + /* 40 */ 47, 48, 910, 51, 52, 208, 1024, 214, 41, 553, + /* 50 */ 50, 262, 55, 53, 57, 54, 934, 554, 1020, 203, /* 60 */ 46, 45, 919, 247, 44, 43, 42, 48, 940, 51, - /* 70 */ 52, 242, 974, 214, 41, 79, 50, 262, 55, 53, - /* 80 */ 57, 54, 975, 632, 257, 30, 46, 45, 278, 225, + /* 70 */ 52, 242, 974, 214, 41, 553, 50, 262, 55, 53, + /* 80 */ 57, 54, 975, 554, 257, 278, 46, 45, 298, 225, /* 90 */ 44, 43, 42, 507, 508, 509, 510, 511, 512, 513, - /* 100 */ 514, 515, 516, 517, 518, 519, 313, 553, 85, 231, - /* 110 */ 70, 288, 287, 47, 48, 554, 51, 52, 298, 219, - /* 120 */ 214, 41, 553, 50, 262, 55, 53, 57, 54, 918, - /* 130 */ 554, 105, 718, 46, 45, 1020, 298, 44, 43, 42, - /* 140 */ 47, 49, 910, 51, 52, 922, 140, 214, 41, 234, - /* 150 */ 50, 262, 55, 53, 57, 54, 1019, 238, 237, 227, + /* 100 */ 514, 515, 516, 517, 518, 519, 313, 632, 1019, 231, + /* 110 */ 70, 553, 30, 47, 48, 1018, 51, 52, 821, 554, + /* 120 */ 214, 41, 166, 50, 262, 55, 53, 57, 54, 44, + /* 130 */ 43, 42, 718, 46, 45, 288, 287, 44, 43, 42, + /* 140 */ 47, 49, 830, 51, 52, 198, 166, 214, 41, 234, + /* 150 */ 50, 262, 55, 53, 57, 54, 918, 238, 237, 227, /* 160 */ 46, 45, 285, 284, 44, 43, 42, 23, 276, 307, /* 170 */ 306, 275, 274, 273, 305, 272, 304, 303, 302, 271, - /* 180 */ 301, 300, 882, 30, 870, 871, 872, 873, 874, 875, + /* 180 */ 301, 300, 882, 140, 870, 871, 872, 873, 874, 875, /* 190 */ 876, 877, 878, 879, 880, 881, 883, 884, 51, 52, - /* 200 */ 821, 1018, 214, 41, 166, 50, 262, 55, 53, 57, - /* 210 */ 54, 259, 18, 78, 82, 46, 45, 198, 223, 44, - /* 220 */ 43, 42, 213, 731, 217, 25, 722, 919, 725, 190, - /* 230 */ 728, 221, 213, 731, 199, 191, 722, 724, 725, 727, - /* 240 */ 728, 118, 117, 189, 263, 905, 906, 29, 909, 44, - /* 250 */ 43, 42, 30, 74, 210, 211, 308, 922, 261, 30, - /* 260 */ 23, 36, 307, 306, 210, 211, 934, 305, 30, 304, - /* 270 */ 303, 302, 74, 301, 300, 890, 908, 183, 888, 889, - /* 280 */ 36, 204, 922, 891, 916, 893, 894, 892, 224, 895, - /* 290 */ 896, 280, 656, 218, 830, 653, 919, 654, 166, 655, - /* 300 */ 281, 69, 241, 919, 68, 55, 53, 57, 54, 282, - /* 310 */ 197, 671, 919, 46, 45, 30, 822, 44, 43, 42, - /* 320 */ 166, 103, 108, 228, 229, 56, 220, 97, 107, 113, - /* 330 */ 116, 106, 732, 907, 723, 56, 726, 110, 730, 30, - /* 340 */ 735, 12, 732, 5, 156, 84, 184, 81, 730, 33, - /* 350 */ 155, 92, 87, 91, 729, 278, 286, 1, 154, 919, - /* 360 */ 174, 170, 186, 212, 729, 80, 172, 169, 121, 120, - /* 370 */ 119, 46, 45, 3, 167, 44, 43, 42, 71, 720, - /* 380 */ 290, 699, 700, 919, 311, 310, 126, 243, 668, 675, - /* 390 */ 678, 31, 684, 690, 180, 24, 135, 60, 245, 691, - /* 400 */ 752, 657, 733, 20, 19, 61, 19, 6, 64, 642, - /* 410 */ 265, 1034, 644, 31, 31, 721, 60, 267, 643, 187, - /* 420 */ 28, 83, 60, 268, 96, 95, 188, 62, 65, 14, - /* 430 */ 13, 102, 101, 660, 67, 661, 631, 194, 16, 15, - /* 440 */ 658, 195, 659, 115, 114, 131, 129, 193, 178, 192, - /* 450 */ 182, 921, 985, 984, 215, 981, 239, 980, 132, 942, - /* 460 */ 216, 289, 39, 950, 952, 967, 134, 966, 138, 935, - /* 470 */ 246, 130, 248, 917, 151, 915, 150, 205, 683, 250, - /* 480 */ 152, 886, 299, 153, 291, 148, 146, 260, 142, 932, - /* 490 */ 141, 58, 833, 270, 66, 255, 143, 37, 63, 176, - /* 500 */ 34, 279, 829, 258, 144, 1039, 93, 256, 1038, 1036, - /* 510 */ 157, 254, 283, 1033, 99, 1032, 1030, 158, 851, 35, - /* 520 */ 252, 145, 32, 38, 177, 818, 109, 816, 111, 40, - /* 530 */ 112, 814, 813, 230, 168, 811, 810, 809, 808, 807, - /* 540 */ 806, 171, 173, 803, 801, 799, 797, 795, 175, 249, - /* 550 */ 244, 72, 75, 104, 251, 968, 292, 293, 294, 295, - /* 560 */ 296, 297, 309, 200, 222, 269, 772, 232, 201, 233, - /* 570 */ 771, 88, 89, 196, 235, 236, 770, 758, 757, 240, - /* 580 */ 245, 8, 264, 73, 812, 663, 805, 161, 852, 159, - /* 590 */ 160, 163, 162, 164, 165, 122, 123, 124, 804, 76, - /* 600 */ 125, 796, 4, 2, 685, 136, 137, 688, 77, 149, - /* 610 */ 147, 207, 253, 86, 692, 898, 139, 9, 10, 26, - /* 620 */ 27, 734, 7, 11, 736, 21, 22, 266, 595, 591, - /* 630 */ 589, 84, 588, 587, 584, 557, 277, 94, 90, 31, - /* 640 */ 634, 633, 59, 630, 579, 577, 98, 569, 575, 571, - /* 650 */ 573, 567, 565, 100, 598, 597, 596, 594, 593, 592, - /* 660 */ 590, 586, 585, 60, 555, 523, 521, 776, 775, 127, - /* 670 */ 775, 775, 775, 775, 775, 775, 775, 775, 775, 128, + /* 200 */ 822, 219, 214, 41, 166, 50, 262, 55, 53, 57, + /* 210 */ 54, 223, 18, 82, 25, 46, 45, 199, 226, 44, + /* 220 */ 43, 42, 213, 731, 934, 221, 722, 922, 725, 190, + /* 230 */ 728, 183, 213, 731, 140, 191, 722, 908, 725, 204, + /* 240 */ 728, 118, 117, 189, 905, 906, 29, 909, 259, 74, + /* 250 */ 78, 922, 30, 920, 210, 211, 308, 36, 261, 69, + /* 260 */ 23, 916, 307, 306, 210, 211, 61, 305, 30, 304, + /* 270 */ 303, 302, 74, 301, 300, 890, 3, 167, 888, 889, + /* 280 */ 36, 224, 922, 891, 280, 893, 894, 892, 62, 895, + /* 290 */ 896, 907, 656, 217, 12, 653, 919, 654, 84, 655, + /* 300 */ 81, 79, 241, 220, 68, 55, 53, 57, 54, 218, + /* 310 */ 197, 184, 919, 46, 45, 30, 278, 44, 43, 42, + /* 320 */ 80, 103, 108, 228, 229, 56, 263, 97, 107, 113, + /* 330 */ 116, 106, 732, 71, 671, 56, 186, 110, 730, 30, + /* 340 */ 180, 30, 732, 5, 156, 30, 699, 700, 730, 33, + /* 350 */ 155, 92, 87, 91, 729, 668, 281, 678, 105, 919, + /* 360 */ 174, 170, 24, 298, 729, 245, 172, 169, 121, 120, + /* 370 */ 119, 46, 45, 1, 154, 44, 43, 42, 720, 724, + /* 380 */ 282, 727, 286, 919, 243, 919, 290, 187, 31, 919, + /* 390 */ 311, 310, 126, 684, 212, 64, 690, 135, 691, 752, + /* 400 */ 60, 657, 20, 19, 733, 723, 642, 726, 19, 265, + /* 410 */ 31, 188, 675, 31, 721, 65, 96, 95, 194, 644, + /* 420 */ 267, 643, 735, 60, 83, 60, 28, 14, 13, 268, + /* 430 */ 102, 101, 67, 660, 631, 661, 195, 658, 6, 659, + /* 440 */ 16, 15, 115, 114, 131, 129, 193, 178, 192, 182, + /* 450 */ 1034, 921, 985, 984, 215, 981, 980, 239, 216, 289, + /* 460 */ 132, 942, 39, 950, 952, 134, 138, 935, 246, 967, + /* 470 */ 130, 966, 917, 150, 151, 915, 299, 152, 683, 248, + /* 480 */ 886, 104, 291, 149, 147, 153, 833, 142, 932, 141, + /* 490 */ 270, 66, 205, 37, 250, 176, 34, 279, 829, 1039, + /* 500 */ 93, 255, 1038, 1036, 143, 63, 58, 157, 283, 1033, + /* 510 */ 99, 1032, 260, 1030, 158, 851, 256, 35, 258, 32, + /* 520 */ 38, 177, 818, 109, 254, 816, 111, 112, 252, 814, + /* 530 */ 813, 230, 168, 811, 810, 809, 808, 807, 806, 171, + /* 540 */ 173, 803, 801, 799, 797, 795, 175, 249, 244, 72, + /* 550 */ 75, 251, 40, 968, 292, 293, 294, 295, 296, 200, + /* 560 */ 297, 222, 269, 309, 772, 233, 232, 771, 88, 201, + /* 570 */ 235, 196, 89, 236, 770, 758, 757, 240, 245, 8, + /* 580 */ 264, 73, 663, 136, 812, 161, 165, 685, 852, 159, + /* 590 */ 160, 162, 164, 163, 122, 123, 805, 76, 124, 804, + /* 600 */ 4, 688, 137, 125, 796, 77, 146, 144, 148, 145, + /* 610 */ 207, 2, 898, 253, 26, 692, 139, 9, 10, 734, + /* 620 */ 27, 7, 11, 21, 736, 22, 86, 266, 595, 591, + /* 630 */ 84, 589, 588, 587, 584, 557, 277, 90, 94, 31, + /* 640 */ 634, 59, 633, 630, 579, 98, 100, 577, 569, 575, + /* 650 */ 571, 573, 567, 565, 598, 597, 596, 594, 593, 592, + /* 660 */ 590, 586, 585, 60, 555, 523, 521, 776, 775, 775, + /* 670 */ 775, 775, 775, 775, 775, 775, 775, 775, 775, 127, + /* 680 */ 128, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 191, 1, 190, 191, 210, 191, 191, 191, 191, 9, - /* 10 */ 188, 189, 252, 13, 14, 191, 16, 17, 191, 252, - /* 20 */ 20, 21, 252, 23, 24, 25, 26, 27, 28, 262, - /* 30 */ 236, 261, 262, 33, 34, 252, 252, 37, 38, 39, - /* 40 */ 13, 14, 226, 16, 17, 261, 262, 20, 21, 1, - /* 50 */ 23, 24, 25, 26, 27, 28, 234, 9, 252, 232, - /* 60 */ 33, 34, 235, 254, 37, 38, 39, 14, 253, 16, - /* 70 */ 17, 249, 258, 20, 21, 258, 23, 24, 25, 26, - /* 80 */ 27, 28, 258, 5, 260, 191, 33, 34, 79, 67, + /* 0 */ 190, 1, 189, 190, 209, 190, 190, 251, 196, 9, + /* 10 */ 187, 188, 251, 13, 14, 190, 16, 17, 190, 251, + /* 20 */ 20, 21, 251, 23, 24, 25, 26, 27, 28, 261, + /* 30 */ 235, 260, 261, 33, 34, 251, 251, 37, 38, 39, + /* 40 */ 13, 14, 230, 16, 17, 260, 261, 20, 21, 1, + /* 50 */ 23, 24, 25, 26, 27, 28, 233, 9, 251, 231, + /* 60 */ 33, 34, 234, 253, 37, 38, 39, 14, 252, 16, + /* 70 */ 17, 248, 257, 20, 21, 1, 23, 24, 25, 26, + /* 80 */ 27, 28, 257, 9, 259, 79, 33, 34, 81, 67, /* 90 */ 37, 38, 39, 45, 46, 47, 48, 49, 50, 51, - /* 100 */ 52, 53, 54, 55, 56, 57, 58, 1, 197, 61, - /* 110 */ 110, 33, 34, 13, 14, 9, 16, 17, 81, 210, - /* 120 */ 20, 21, 1, 23, 24, 25, 26, 27, 28, 235, - /* 130 */ 9, 76, 105, 33, 34, 252, 81, 37, 38, 39, - /* 140 */ 13, 14, 231, 16, 17, 236, 191, 20, 21, 135, - /* 150 */ 23, 24, 25, 26, 27, 28, 252, 143, 144, 137, + /* 100 */ 52, 53, 54, 55, 56, 57, 58, 5, 251, 61, + /* 110 */ 110, 1, 190, 13, 14, 251, 16, 17, 195, 9, + /* 120 */ 20, 21, 199, 23, 24, 25, 26, 27, 28, 37, + /* 130 */ 38, 39, 105, 33, 34, 33, 34, 37, 38, 39, + /* 140 */ 13, 14, 195, 16, 17, 251, 199, 20, 21, 135, + /* 150 */ 23, 24, 25, 26, 27, 28, 234, 143, 144, 137, /* 160 */ 33, 34, 140, 141, 37, 38, 39, 88, 89, 90, /* 170 */ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - /* 180 */ 101, 102, 209, 191, 211, 212, 213, 214, 215, 216, - /* 190 */ 217, 218, 219, 220, 221, 222, 223, 224, 16, 17, - /* 200 */ 196, 252, 20, 21, 200, 23, 24, 25, 26, 27, - /* 210 */ 28, 256, 44, 258, 197, 33, 34, 252, 67, 37, - /* 220 */ 38, 39, 1, 2, 232, 104, 5, 235, 7, 61, - /* 230 */ 9, 210, 1, 2, 252, 67, 5, 5, 7, 7, - /* 240 */ 9, 73, 74, 75, 15, 228, 229, 230, 231, 37, - /* 250 */ 38, 39, 191, 104, 33, 34, 210, 236, 37, 191, - /* 260 */ 88, 112, 90, 91, 33, 34, 234, 95, 191, 97, - /* 270 */ 98, 99, 104, 101, 102, 209, 0, 252, 212, 213, - /* 280 */ 112, 249, 236, 217, 191, 219, 220, 221, 137, 223, - /* 290 */ 224, 140, 2, 232, 196, 5, 235, 7, 200, 9, - /* 300 */ 232, 197, 134, 235, 136, 25, 26, 27, 28, 232, - /* 310 */ 142, 37, 235, 33, 34, 191, 196, 37, 38, 39, - /* 320 */ 200, 62, 63, 33, 34, 104, 233, 68, 69, 70, - /* 330 */ 71, 72, 111, 229, 5, 104, 7, 78, 117, 191, - /* 340 */ 111, 104, 111, 62, 63, 108, 252, 110, 117, 68, - /* 350 */ 69, 70, 71, 72, 133, 79, 232, 198, 199, 235, - /* 360 */ 62, 63, 252, 60, 133, 237, 68, 69, 70, 71, - /* 370 */ 72, 33, 34, 194, 195, 37, 38, 39, 250, 1, - /* 380 */ 232, 124, 125, 235, 64, 65, 66, 105, 109, 115, - /* 390 */ 105, 109, 105, 105, 252, 116, 109, 109, 113, 105, - /* 400 */ 105, 111, 105, 109, 109, 109, 109, 104, 109, 105, - /* 410 */ 105, 236, 105, 109, 109, 37, 109, 105, 105, 252, - /* 420 */ 104, 109, 109, 107, 138, 139, 252, 131, 129, 138, - /* 430 */ 139, 138, 139, 5, 104, 7, 106, 252, 138, 139, - /* 440 */ 5, 252, 7, 76, 77, 62, 63, 252, 252, 252, - /* 450 */ 252, 236, 227, 227, 227, 227, 191, 227, 191, 191, - /* 460 */ 227, 227, 251, 191, 191, 259, 191, 259, 191, 234, - /* 470 */ 234, 60, 255, 234, 191, 191, 238, 255, 117, 255, - /* 480 */ 191, 225, 103, 191, 86, 240, 242, 122, 246, 248, - /* 490 */ 247, 127, 191, 191, 128, 255, 245, 191, 130, 191, - /* 500 */ 191, 191, 191, 126, 244, 191, 191, 121, 191, 191, - /* 510 */ 191, 120, 191, 191, 191, 191, 191, 191, 191, 191, - /* 520 */ 119, 243, 191, 191, 191, 191, 191, 191, 191, 132, - /* 530 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - /* 540 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 118, - /* 550 */ 192, 192, 192, 87, 192, 192, 50, 83, 85, 54, - /* 560 */ 84, 82, 79, 192, 192, 192, 5, 145, 192, 5, - /* 570 */ 5, 197, 197, 192, 145, 5, 5, 90, 89, 135, - /* 580 */ 113, 104, 107, 114, 192, 105, 192, 202, 208, 207, - /* 590 */ 206, 203, 205, 204, 201, 193, 193, 193, 192, 109, - /* 600 */ 193, 192, 194, 198, 105, 104, 109, 105, 104, 239, - /* 610 */ 241, 1, 104, 76, 105, 225, 104, 123, 123, 109, - /* 620 */ 109, 105, 104, 104, 111, 104, 104, 107, 9, 5, - /* 630 */ 5, 108, 5, 5, 5, 80, 15, 139, 76, 109, - /* 640 */ 5, 5, 16, 105, 5, 5, 139, 5, 5, 5, - /* 650 */ 5, 5, 5, 139, 5, 5, 5, 5, 5, 5, - /* 660 */ 5, 5, 5, 109, 80, 60, 59, 0, 263, 21, - /* 670 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 21, - /* 680 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 690 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 700 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 710 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 720 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 730 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 740 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 750 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 760 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 770 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 780 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 790 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 800 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 810 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 820 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 830 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 840 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 850 */ 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - /* 860 */ 263, 263, 263, 263, 263, 263, 263, + /* 180 */ 101, 102, 208, 190, 210, 211, 212, 213, 214, 215, + /* 190 */ 216, 217, 218, 219, 220, 221, 222, 223, 16, 17, + /* 200 */ 195, 209, 20, 21, 199, 23, 24, 25, 26, 27, + /* 210 */ 28, 67, 44, 196, 104, 33, 34, 251, 190, 37, + /* 220 */ 38, 39, 1, 2, 233, 209, 5, 235, 7, 61, + /* 230 */ 9, 251, 1, 2, 190, 67, 5, 0, 7, 248, + /* 240 */ 9, 73, 74, 75, 227, 228, 229, 230, 255, 104, + /* 250 */ 257, 235, 190, 225, 33, 34, 209, 112, 37, 196, + /* 260 */ 88, 190, 90, 91, 33, 34, 109, 95, 190, 97, + /* 270 */ 98, 99, 104, 101, 102, 208, 193, 194, 211, 212, + /* 280 */ 112, 137, 235, 216, 140, 218, 219, 220, 131, 222, + /* 290 */ 223, 228, 2, 231, 104, 5, 234, 7, 108, 9, + /* 300 */ 110, 257, 134, 232, 136, 25, 26, 27, 28, 231, + /* 310 */ 142, 251, 234, 33, 34, 190, 79, 37, 38, 39, + /* 320 */ 236, 62, 63, 33, 34, 104, 15, 68, 69, 70, + /* 330 */ 71, 72, 111, 249, 37, 104, 251, 78, 117, 190, + /* 340 */ 251, 190, 111, 62, 63, 190, 124, 125, 117, 68, + /* 350 */ 69, 70, 71, 72, 133, 109, 231, 105, 76, 234, + /* 360 */ 62, 63, 116, 81, 133, 113, 68, 69, 70, 71, + /* 370 */ 72, 33, 34, 197, 198, 37, 38, 39, 1, 5, + /* 380 */ 231, 7, 231, 234, 105, 234, 231, 251, 109, 234, + /* 390 */ 64, 65, 66, 105, 60, 109, 105, 109, 105, 105, + /* 400 */ 109, 111, 109, 109, 105, 5, 105, 7, 109, 105, + /* 410 */ 109, 251, 115, 109, 37, 129, 138, 139, 251, 105, + /* 420 */ 105, 105, 111, 109, 109, 109, 104, 138, 139, 107, + /* 430 */ 138, 139, 104, 5, 106, 7, 251, 5, 104, 7, + /* 440 */ 138, 139, 76, 77, 62, 63, 251, 251, 251, 251, + /* 450 */ 235, 235, 226, 226, 226, 226, 226, 190, 226, 226, + /* 460 */ 190, 190, 250, 190, 190, 190, 190, 233, 233, 258, + /* 470 */ 60, 258, 233, 237, 190, 190, 103, 190, 117, 254, + /* 480 */ 224, 87, 86, 238, 240, 190, 190, 245, 247, 246, + /* 490 */ 190, 128, 254, 190, 254, 190, 190, 190, 190, 190, + /* 500 */ 190, 254, 190, 190, 244, 130, 127, 190, 190, 190, + /* 510 */ 190, 190, 122, 190, 190, 190, 121, 190, 126, 190, + /* 520 */ 190, 190, 190, 190, 120, 190, 190, 190, 119, 190, + /* 530 */ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + /* 540 */ 190, 190, 190, 190, 190, 190, 190, 118, 191, 191, + /* 550 */ 191, 191, 132, 191, 50, 83, 85, 54, 84, 191, + /* 560 */ 82, 191, 191, 79, 5, 5, 145, 5, 196, 191, + /* 570 */ 145, 191, 196, 5, 5, 90, 89, 135, 113, 104, + /* 580 */ 107, 114, 105, 104, 191, 201, 200, 105, 207, 206, + /* 590 */ 205, 204, 203, 202, 192, 192, 191, 109, 192, 191, + /* 600 */ 193, 105, 109, 192, 191, 104, 241, 243, 239, 242, + /* 610 */ 1, 197, 224, 104, 109, 105, 104, 123, 123, 105, + /* 620 */ 109, 104, 104, 104, 111, 104, 76, 107, 9, 5, + /* 630 */ 108, 5, 5, 5, 5, 80, 15, 76, 139, 109, + /* 640 */ 5, 16, 5, 105, 5, 139, 139, 5, 5, 5, + /* 650 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 660 */ 5, 5, 5, 109, 80, 60, 59, 0, 262, 262, + /* 670 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 21, + /* 680 */ 21, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 690 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 700 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 710 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 720 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 730 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 740 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 750 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 760 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 770 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 780 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 790 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 800 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 810 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 820 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 830 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 840 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 850 */ 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + /* 860 */ 262, 262, 262, 262, 262, 262, 262, 262, }; #define YY_SHIFT_COUNT (314) #define YY_SHIFT_MIN (0) #define YY_SHIFT_MAX (667) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 168, 79, 79, 172, 172, 9, 221, 231, 106, 106, - /* 10 */ 106, 106, 106, 106, 106, 106, 106, 0, 48, 231, - /* 20 */ 290, 290, 290, 290, 121, 149, 106, 106, 106, 276, - /* 30 */ 106, 106, 55, 9, 37, 37, 680, 680, 680, 231, + /* 0 */ 168, 79, 79, 172, 172, 6, 221, 231, 74, 74, + /* 10 */ 74, 74, 74, 74, 74, 74, 74, 0, 48, 231, + /* 20 */ 290, 290, 290, 290, 110, 145, 74, 74, 74, 237, + /* 30 */ 74, 74, 282, 6, 7, 7, 681, 681, 681, 231, /* 40 */ 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, /* 50 */ 231, 231, 231, 231, 231, 231, 231, 231, 231, 290, - /* 60 */ 290, 78, 78, 78, 78, 78, 78, 78, 106, 106, - /* 70 */ 106, 274, 106, 149, 149, 106, 106, 106, 257, 257, - /* 80 */ 279, 149, 106, 106, 106, 106, 106, 106, 106, 106, - /* 90 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - /* 100 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - /* 110 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - /* 120 */ 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - /* 130 */ 106, 106, 411, 411, 411, 361, 361, 361, 411, 361, - /* 140 */ 411, 366, 368, 364, 365, 377, 386, 391, 401, 431, - /* 150 */ 397, 411, 411, 411, 379, 9, 9, 411, 411, 466, - /* 160 */ 398, 506, 474, 473, 505, 476, 479, 379, 411, 483, - /* 170 */ 483, 411, 483, 411, 483, 411, 680, 680, 27, 100, + /* 60 */ 290, 102, 102, 102, 102, 102, 102, 102, 74, 74, + /* 70 */ 74, 297, 74, 145, 145, 74, 74, 74, 222, 222, + /* 80 */ 246, 145, 74, 74, 74, 74, 74, 74, 74, 74, + /* 90 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + /* 100 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + /* 110 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + /* 120 */ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + /* 130 */ 74, 74, 410, 410, 410, 361, 361, 361, 410, 361, + /* 140 */ 410, 363, 375, 379, 390, 392, 395, 404, 409, 429, + /* 150 */ 420, 410, 410, 410, 373, 6, 6, 410, 410, 394, + /* 160 */ 396, 504, 472, 471, 503, 474, 478, 373, 410, 484, + /* 170 */ 484, 410, 484, 410, 484, 410, 681, 681, 27, 100, /* 180 */ 127, 100, 100, 53, 182, 280, 280, 280, 280, 259, - /* 190 */ 281, 298, 338, 338, 338, 338, 22, 14, 212, 212, - /* 200 */ 237, 151, 320, 282, 285, 287, 288, 294, 295, 297, - /* 210 */ 232, 329, 378, 303, 229, 296, 299, 304, 305, 307, - /* 220 */ 312, 313, 316, 286, 291, 293, 330, 300, 428, 435, - /* 230 */ 367, 383, 561, 422, 564, 565, 429, 570, 571, 487, - /* 240 */ 489, 444, 467, 475, 477, 469, 480, 490, 499, 501, - /* 250 */ 502, 497, 504, 610, 508, 509, 512, 510, 494, 511, - /* 260 */ 495, 516, 518, 513, 519, 475, 521, 520, 522, 523, - /* 270 */ 537, 619, 624, 625, 627, 628, 629, 555, 621, 562, - /* 280 */ 498, 530, 530, 626, 507, 514, 530, 635, 636, 538, - /* 290 */ 530, 639, 640, 642, 643, 644, 645, 646, 647, 649, + /* 190 */ 281, 298, 338, 338, 338, 338, 22, 14, 92, 92, + /* 200 */ 190, 144, 326, 279, 252, 288, 291, 293, 294, 299, + /* 210 */ 374, 400, 377, 334, 311, 157, 286, 301, 304, 314, + /* 220 */ 315, 316, 322, 278, 289, 292, 328, 302, 428, 432, + /* 230 */ 366, 382, 559, 421, 560, 562, 425, 568, 569, 485, + /* 240 */ 487, 442, 465, 473, 475, 467, 477, 488, 482, 479, + /* 250 */ 496, 493, 501, 609, 509, 510, 512, 505, 494, 511, + /* 260 */ 495, 514, 517, 513, 518, 473, 519, 520, 521, 522, + /* 270 */ 550, 619, 624, 626, 627, 628, 629, 555, 621, 561, + /* 280 */ 499, 530, 530, 625, 506, 507, 530, 635, 637, 538, + /* 290 */ 530, 639, 642, 643, 644, 645, 646, 647, 648, 649, /* 300 */ 650, 651, 652, 653, 654, 655, 656, 657, 554, 584, - /* 310 */ 648, 658, 605, 607, 667, + /* 310 */ 658, 659, 605, 607, 667, }; #define YY_REDUCE_COUNT (177) -#define YY_REDUCE_MIN (-240) -#define YY_REDUCE_MAX (409) +#define YY_REDUCE_MIN (-244) +#define YY_REDUCE_MAX (414) static const short yy_reduce_ofst[] = { - /* 0 */ -178, -27, -27, 66, 66, 17, -230, -216, -173, -176, - /* 10 */ -45, -8, 61, 68, 77, 124, 148, -185, -188, -233, - /* 20 */ -206, -91, 21, 46, -191, 32, -186, -183, 93, -89, - /* 30 */ -184, -106, 4, 104, 98, 120, 128, 159, 179, -240, - /* 40 */ -217, -194, -117, -96, -51, -35, -18, 25, 94, 110, - /* 50 */ 142, 167, 174, 185, 189, 195, 196, 197, 198, 175, - /* 60 */ 215, 225, 226, 227, 228, 230, 233, 234, 265, 267, - /* 70 */ 268, 211, 272, 235, 236, 273, 275, 277, 206, 208, - /* 80 */ 238, 239, 283, 284, 289, 292, 301, 302, 306, 308, - /* 90 */ 309, 310, 311, 314, 315, 317, 318, 319, 321, 322, - /* 100 */ 323, 324, 325, 326, 327, 328, 331, 332, 333, 334, - /* 110 */ 335, 336, 337, 339, 340, 341, 342, 343, 344, 345, - /* 120 */ 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - /* 130 */ 356, 357, 358, 359, 360, 217, 222, 224, 362, 240, - /* 140 */ 363, 241, 243, 242, 251, 260, 278, 244, 369, 245, - /* 150 */ 370, 371, 372, 373, 256, 374, 375, 376, 381, 380, - /* 160 */ 382, 384, 385, 387, 388, 389, 393, 390, 392, 402, - /* 170 */ 403, 394, 404, 406, 407, 409, 405, 408, + /* 0 */ -177, -26, -26, 67, 67, 17, -229, -215, -172, -175, + /* 10 */ -7, 62, 78, 125, 149, 151, 155, -184, -187, -232, + /* 20 */ -205, -8, 16, 47, -190, -9, -185, 44, 71, -188, + /* 30 */ 28, -78, -77, 63, -53, 5, 84, 176, 83, -244, + /* 40 */ -239, -216, -193, -143, -136, -106, -34, -20, 60, 85, + /* 50 */ 89, 136, 160, 167, 185, 195, 196, 197, 198, 215, + /* 60 */ 216, 226, 227, 228, 229, 230, 232, 233, 267, 270, + /* 70 */ 271, 212, 273, 234, 235, 274, 275, 276, 211, 213, + /* 80 */ 236, 239, 284, 285, 287, 295, 296, 300, 303, 305, + /* 90 */ 306, 307, 308, 309, 310, 312, 313, 317, 318, 319, + /* 100 */ 320, 321, 323, 324, 325, 327, 329, 330, 331, 332, + /* 110 */ 333, 335, 336, 337, 339, 340, 341, 342, 343, 344, + /* 120 */ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + /* 130 */ 355, 356, 357, 358, 359, 225, 238, 240, 360, 247, + /* 140 */ 362, 241, 243, 242, 260, 364, 367, 365, 244, 369, + /* 150 */ 245, 368, 370, 371, 256, 372, 376, 378, 380, 381, + /* 160 */ 383, 385, 384, 387, 391, 389, 386, 388, 393, 402, + /* 170 */ 403, 405, 406, 408, 411, 413, 414, 407, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 773, 885, 831, 897, 819, 828, 1026, 1026, 773, 773, @@ -702,6 +714,7 @@ struct yyParser { int yyerrcnt; /* Shifts left before out of the error */ #endif ParseARG_SDECL /* A place to hold %extra_argument */ + ParseCTX_SDECL /* A place to hold %extra_context */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ @@ -936,82 +949,81 @@ static const char *const yyTokenName[] = { /* 184 */ "INSERT", /* 185 */ "INTO", /* 186 */ "VALUES", - /* 187 */ "error", - /* 188 */ "program", - /* 189 */ "cmd", - /* 190 */ "dbPrefix", - /* 191 */ "ids", - /* 192 */ "cpxName", - /* 193 */ "ifexists", - /* 194 */ "alter_db_optr", - /* 195 */ "alter_topic_optr", - /* 196 */ "acct_optr", - /* 197 */ "ifnotexists", - /* 198 */ "db_optr", - /* 199 */ "topic_optr", - /* 200 */ "pps", - /* 201 */ "tseries", - /* 202 */ "dbs", - /* 203 */ "streams", - /* 204 */ "storage", - /* 205 */ "qtime", - /* 206 */ "users", - /* 207 */ "conns", - /* 208 */ "state", - /* 209 */ "keep", - /* 210 */ "tagitemlist", - /* 211 */ "cache", - /* 212 */ "replica", - /* 213 */ "quorum", - /* 214 */ "days", - /* 215 */ "minrows", - /* 216 */ "maxrows", - /* 217 */ "blocks", - /* 218 */ "ctime", - /* 219 */ "wal", - /* 220 */ "fsync", - /* 221 */ "comp", - /* 222 */ "prec", - /* 223 */ "update", - /* 224 */ "cachelast", - /* 225 */ "partitions", - /* 226 */ "typename", - /* 227 */ "signed", - /* 228 */ "create_table_args", - /* 229 */ "create_stable_args", - /* 230 */ "create_table_list", - /* 231 */ "create_from_stable", - /* 232 */ "columnlist", - /* 233 */ "tagNamelist", - /* 234 */ "select", - /* 235 */ "column", - /* 236 */ "tagitem", - /* 237 */ "selcollist", - /* 238 */ "from", - /* 239 */ "where_opt", - /* 240 */ "interval_opt", - /* 241 */ "session_option", - /* 242 */ "fill_opt", - /* 243 */ "sliding_opt", - /* 244 */ "groupby_opt", - /* 245 */ "orderby_opt", - /* 246 */ "having_opt", - /* 247 */ "slimit_opt", - /* 248 */ "limit_opt", - /* 249 */ "union", - /* 250 */ "sclp", - /* 251 */ "distinct", - /* 252 */ "expr", - /* 253 */ "as", - /* 254 */ "tablelist", - /* 255 */ "tmvar", - /* 256 */ "sortlist", - /* 257 */ "sortitem", - /* 258 */ "item", - /* 259 */ "sortorder", - /* 260 */ "grouplist", - /* 261 */ "exprlist", - /* 262 */ "expritem", + /* 187 */ "program", + /* 188 */ "cmd", + /* 189 */ "dbPrefix", + /* 190 */ "ids", + /* 191 */ "cpxName", + /* 192 */ "ifexists", + /* 193 */ "alter_db_optr", + /* 194 */ "alter_topic_optr", + /* 195 */ "acct_optr", + /* 196 */ "ifnotexists", + /* 197 */ "db_optr", + /* 198 */ "topic_optr", + /* 199 */ "pps", + /* 200 */ "tseries", + /* 201 */ "dbs", + /* 202 */ "streams", + /* 203 */ "storage", + /* 204 */ "qtime", + /* 205 */ "users", + /* 206 */ "conns", + /* 207 */ "state", + /* 208 */ "keep", + /* 209 */ "tagitemlist", + /* 210 */ "cache", + /* 211 */ "replica", + /* 212 */ "quorum", + /* 213 */ "days", + /* 214 */ "minrows", + /* 215 */ "maxrows", + /* 216 */ "blocks", + /* 217 */ "ctime", + /* 218 */ "wal", + /* 219 */ "fsync", + /* 220 */ "comp", + /* 221 */ "prec", + /* 222 */ "update", + /* 223 */ "cachelast", + /* 224 */ "partitions", + /* 225 */ "typename", + /* 226 */ "signed", + /* 227 */ "create_table_args", + /* 228 */ "create_stable_args", + /* 229 */ "create_table_list", + /* 230 */ "create_from_stable", + /* 231 */ "columnlist", + /* 232 */ "tagNamelist", + /* 233 */ "select", + /* 234 */ "column", + /* 235 */ "tagitem", + /* 236 */ "selcollist", + /* 237 */ "from", + /* 238 */ "where_opt", + /* 239 */ "interval_opt", + /* 240 */ "session_option", + /* 241 */ "fill_opt", + /* 242 */ "sliding_opt", + /* 243 */ "groupby_opt", + /* 244 */ "orderby_opt", + /* 245 */ "having_opt", + /* 246 */ "slimit_opt", + /* 247 */ "limit_opt", + /* 248 */ "union", + /* 249 */ "sclp", + /* 250 */ "distinct", + /* 251 */ "expr", + /* 252 */ "as", + /* 253 */ "tablelist", + /* 254 */ "tmvar", + /* 255 */ "sortlist", + /* 256 */ "sortitem", + /* 257 */ "item", + /* 258 */ "sortorder", + /* 259 */ "grouplist", + /* 260 */ "exprlist", + /* 261 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1334,28 +1346,29 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -void ParseInit(void *yypParser){ - yyParser *pParser = (yyParser*)yypParser; +void ParseInit(void *yypRawParser ParseCTX_PDECL){ + yyParser *yypParser = (yyParser*)yypRawParser; + ParseCTX_STORE #ifdef YYTRACKMAXSTACKDEPTH - pParser->yyhwm = 0; + yypParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 - pParser->yytos = NULL; - pParser->yystack = NULL; - pParser->yystksz = 0; - if( yyGrowStack(pParser) ){ - pParser->yystack = &pParser->yystk0; - pParser->yystksz = 1; + yypParser->yytos = NULL; + yypParser->yystack = NULL; + yypParser->yystksz = 0; + if( yyGrowStack(yypParser) ){ + yypParser->yystack = &yypParser->yystk0; + yypParser->yystksz = 1; } #endif #ifndef YYNOERRORRECOVERY - pParser->yyerrcnt = -1; + yypParser->yyerrcnt = -1; #endif - pParser->yytos = pParser->yystack; - pParser->yystack[0].stateno = 0; - pParser->yystack[0].major = 0; + yypParser->yytos = yypParser->yystack; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; #if YYSTACKDEPTH>0 - pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; #endif } @@ -1372,11 +1385,14 @@ void ParseInit(void *yypParser){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( pParser ) ParseInit(pParser); - return pParser; +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){ + yyParser *yypParser; + yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( yypParser ){ + ParseCTX_STORE + ParseInit(yypParser ParseCTX_PARAM); + } + return (void*)yypParser; } #endif /* Parse_ENGINEALWAYSONSTACK */ @@ -1393,7 +1409,8 @@ static void yy_destructor( YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -1406,52 +1423,52 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 209: /* keep */ - case 210: /* tagitemlist */ - case 232: /* columnlist */ - case 233: /* tagNamelist */ - case 242: /* fill_opt */ - case 244: /* groupby_opt */ - case 245: /* orderby_opt */ - case 256: /* sortlist */ - case 260: /* grouplist */ + case 208: /* keep */ + case 209: /* tagitemlist */ + case 231: /* columnlist */ + case 232: /* tagNamelist */ + case 241: /* fill_opt */ + case 243: /* groupby_opt */ + case 244: /* orderby_opt */ + case 255: /* sortlist */ + case 259: /* grouplist */ { -taosArrayDestroy((yypminor->yy159)); +taosArrayDestroy((yypminor->yy429)); } break; - case 230: /* create_table_list */ + case 229: /* create_table_list */ { -destroyCreateTableSql((yypminor->yy14)); +destroyCreateTableSql((yypminor->yy194)); } break; - case 234: /* select */ + case 233: /* select */ { -destroyQuerySqlNode((yypminor->yy272)); +destroyQuerySqlNode((yypminor->yy254)); } break; - case 237: /* selcollist */ - case 250: /* sclp */ - case 261: /* exprlist */ + case 236: /* selcollist */ + case 249: /* sclp */ + case 260: /* exprlist */ { -tSqlExprListDestroy((yypminor->yy159)); +tSqlExprListDestroy((yypminor->yy429)); } break; - case 239: /* where_opt */ - case 246: /* having_opt */ - case 252: /* expr */ - case 262: /* expritem */ + case 238: /* where_opt */ + case 245: /* having_opt */ + case 251: /* expr */ + case 261: /* expritem */ { -tSqlExprDestroy((yypminor->yy118)); +tSqlExprDestroy((yypminor->yy170)); } break; - case 249: /* union */ + case 248: /* union */ { -destroyAllSelectClause((yypminor->yy391)); +destroyAllSelectClause((yypminor->yy141)); } break; - case 257: /* sortitem */ + case 256: /* sortitem */ { -tVariantDestroy(&(yypminor->yy488)); +tVariantDestroy(&(yypminor->yy218)); } break; /********* End destructor definitions *****************************************/ @@ -1563,13 +1580,12 @@ int ParseCoverage(FILE *out){ ** Find the appropriate action for a parser given the terminal ** look-ahead token iLookAhead. */ -static unsigned int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ +static YYACTIONTYPE yy_find_shift_action( + YYCODETYPE iLookAhead, /* The look-ahead token */ + YYACTIONTYPE stateno /* Current state number */ ){ int i; - int stateno = pParser->yytos->stateno; - + if( stateno>YY_MAX_SHIFT ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); #if defined(YYCOVERAGE) @@ -1577,15 +1593,19 @@ static unsigned int yy_find_shift_action( #endif do{ i = yy_shift_ofst[stateno]; - assert( i>=0 && i+YYNTOKEN<=sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); + assert( i>=0 ); + assert( i<=YY_ACTTAB_COUNT ); + assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; + assert( i<(int)YY_NLOOKAHEAD ); if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", @@ -1600,15 +1620,8 @@ static unsigned int yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( -#if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && -#endif -#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 - ){ + assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); + if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", @@ -1622,6 +1635,7 @@ static unsigned int yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ + assert( i>=0 && iyytos; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; + yytos->stateno = yyNewState; + yytos->major = yyMajor; yytos->minor.yy0 = yyMinor; yyTraceShift(yypParser, yyNewState, "Shift"); } -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ -} yyRuleInfo[] = { - { 188, -1 }, /* (0) program ::= cmd */ - { 189, -2 }, /* (1) cmd ::= SHOW DATABASES */ - { 189, -2 }, /* (2) cmd ::= SHOW TOPICS */ - { 189, -2 }, /* (3) cmd ::= SHOW MNODES */ - { 189, -2 }, /* (4) cmd ::= SHOW DNODES */ - { 189, -2 }, /* (5) cmd ::= SHOW ACCOUNTS */ - { 189, -2 }, /* (6) cmd ::= SHOW USERS */ - { 189, -2 }, /* (7) cmd ::= SHOW MODULES */ - { 189, -2 }, /* (8) cmd ::= SHOW QUERIES */ - { 189, -2 }, /* (9) cmd ::= SHOW CONNECTIONS */ - { 189, -2 }, /* (10) cmd ::= SHOW STREAMS */ - { 189, -2 }, /* (11) cmd ::= SHOW VARIABLES */ - { 189, -2 }, /* (12) cmd ::= SHOW SCORES */ - { 189, -2 }, /* (13) cmd ::= SHOW GRANTS */ - { 189, -2 }, /* (14) cmd ::= SHOW VNODES */ - { 189, -3 }, /* (15) cmd ::= SHOW VNODES IPTOKEN */ - { 190, 0 }, /* (16) dbPrefix ::= */ - { 190, -2 }, /* (17) dbPrefix ::= ids DOT */ - { 192, 0 }, /* (18) cpxName ::= */ - { 192, -2 }, /* (19) cpxName ::= DOT ids */ - { 189, -5 }, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ - { 189, -4 }, /* (21) cmd ::= SHOW CREATE DATABASE ids */ - { 189, -3 }, /* (22) cmd ::= SHOW dbPrefix TABLES */ - { 189, -5 }, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - { 189, -3 }, /* (24) cmd ::= SHOW dbPrefix STABLES */ - { 189, -5 }, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - { 189, -3 }, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ - { 189, -4 }, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ - { 189, -5 }, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ - { 189, -5 }, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ - { 189, -4 }, /* (30) cmd ::= DROP DATABASE ifexists ids */ - { 189, -4 }, /* (31) cmd ::= DROP TOPIC ifexists ids */ - { 189, -3 }, /* (32) cmd ::= DROP DNODE ids */ - { 189, -3 }, /* (33) cmd ::= DROP USER ids */ - { 189, -3 }, /* (34) cmd ::= DROP ACCOUNT ids */ - { 189, -2 }, /* (35) cmd ::= USE ids */ - { 189, -3 }, /* (36) cmd ::= DESCRIBE ids cpxName */ - { 189, -5 }, /* (37) cmd ::= ALTER USER ids PASS ids */ - { 189, -5 }, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ - { 189, -4 }, /* (39) cmd ::= ALTER DNODE ids ids */ - { 189, -5 }, /* (40) cmd ::= ALTER DNODE ids ids ids */ - { 189, -3 }, /* (41) cmd ::= ALTER LOCAL ids */ - { 189, -4 }, /* (42) cmd ::= ALTER LOCAL ids ids */ - { 189, -4 }, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ - { 189, -4 }, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ - { 189, -4 }, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ - { 189, -6 }, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - { 191, -1 }, /* (47) ids ::= ID */ - { 191, -1 }, /* (48) ids ::= STRING */ - { 193, -2 }, /* (49) ifexists ::= IF EXISTS */ - { 193, 0 }, /* (50) ifexists ::= */ - { 197, -3 }, /* (51) ifnotexists ::= IF NOT EXISTS */ - { 197, 0 }, /* (52) ifnotexists ::= */ - { 189, -3 }, /* (53) cmd ::= CREATE DNODE ids */ - { 189, -6 }, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - { 189, -5 }, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - { 189, -5 }, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - { 189, -5 }, /* (57) cmd ::= CREATE USER ids PASS ids */ - { 200, 0 }, /* (58) pps ::= */ - { 200, -2 }, /* (59) pps ::= PPS INTEGER */ - { 201, 0 }, /* (60) tseries ::= */ - { 201, -2 }, /* (61) tseries ::= TSERIES INTEGER */ - { 202, 0 }, /* (62) dbs ::= */ - { 202, -2 }, /* (63) dbs ::= DBS INTEGER */ - { 203, 0 }, /* (64) streams ::= */ - { 203, -2 }, /* (65) streams ::= STREAMS INTEGER */ - { 204, 0 }, /* (66) storage ::= */ - { 204, -2 }, /* (67) storage ::= STORAGE INTEGER */ - { 205, 0 }, /* (68) qtime ::= */ - { 205, -2 }, /* (69) qtime ::= QTIME INTEGER */ - { 206, 0 }, /* (70) users ::= */ - { 206, -2 }, /* (71) users ::= USERS INTEGER */ - { 207, 0 }, /* (72) conns ::= */ - { 207, -2 }, /* (73) conns ::= CONNS INTEGER */ - { 208, 0 }, /* (74) state ::= */ - { 208, -2 }, /* (75) state ::= STATE ids */ - { 196, -9 }, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - { 209, -2 }, /* (77) keep ::= KEEP tagitemlist */ - { 211, -2 }, /* (78) cache ::= CACHE INTEGER */ - { 212, -2 }, /* (79) replica ::= REPLICA INTEGER */ - { 213, -2 }, /* (80) quorum ::= QUORUM INTEGER */ - { 214, -2 }, /* (81) days ::= DAYS INTEGER */ - { 215, -2 }, /* (82) minrows ::= MINROWS INTEGER */ - { 216, -2 }, /* (83) maxrows ::= MAXROWS INTEGER */ - { 217, -2 }, /* (84) blocks ::= BLOCKS INTEGER */ - { 218, -2 }, /* (85) ctime ::= CTIME INTEGER */ - { 219, -2 }, /* (86) wal ::= WAL INTEGER */ - { 220, -2 }, /* (87) fsync ::= FSYNC INTEGER */ - { 221, -2 }, /* (88) comp ::= COMP INTEGER */ - { 222, -2 }, /* (89) prec ::= PRECISION STRING */ - { 223, -2 }, /* (90) update ::= UPDATE INTEGER */ - { 224, -2 }, /* (91) cachelast ::= CACHELAST INTEGER */ - { 225, -2 }, /* (92) partitions ::= PARTITIONS INTEGER */ - { 198, 0 }, /* (93) db_optr ::= */ - { 198, -2 }, /* (94) db_optr ::= db_optr cache */ - { 198, -2 }, /* (95) db_optr ::= db_optr replica */ - { 198, -2 }, /* (96) db_optr ::= db_optr quorum */ - { 198, -2 }, /* (97) db_optr ::= db_optr days */ - { 198, -2 }, /* (98) db_optr ::= db_optr minrows */ - { 198, -2 }, /* (99) db_optr ::= db_optr maxrows */ - { 198, -2 }, /* (100) db_optr ::= db_optr blocks */ - { 198, -2 }, /* (101) db_optr ::= db_optr ctime */ - { 198, -2 }, /* (102) db_optr ::= db_optr wal */ - { 198, -2 }, /* (103) db_optr ::= db_optr fsync */ - { 198, -2 }, /* (104) db_optr ::= db_optr comp */ - { 198, -2 }, /* (105) db_optr ::= db_optr prec */ - { 198, -2 }, /* (106) db_optr ::= db_optr keep */ - { 198, -2 }, /* (107) db_optr ::= db_optr update */ - { 198, -2 }, /* (108) db_optr ::= db_optr cachelast */ - { 199, -1 }, /* (109) topic_optr ::= db_optr */ - { 199, -2 }, /* (110) topic_optr ::= topic_optr partitions */ - { 194, 0 }, /* (111) alter_db_optr ::= */ - { 194, -2 }, /* (112) alter_db_optr ::= alter_db_optr replica */ - { 194, -2 }, /* (113) alter_db_optr ::= alter_db_optr quorum */ - { 194, -2 }, /* (114) alter_db_optr ::= alter_db_optr keep */ - { 194, -2 }, /* (115) alter_db_optr ::= alter_db_optr blocks */ - { 194, -2 }, /* (116) alter_db_optr ::= alter_db_optr comp */ - { 194, -2 }, /* (117) alter_db_optr ::= alter_db_optr wal */ - { 194, -2 }, /* (118) alter_db_optr ::= alter_db_optr fsync */ - { 194, -2 }, /* (119) alter_db_optr ::= alter_db_optr update */ - { 194, -2 }, /* (120) alter_db_optr ::= alter_db_optr cachelast */ - { 195, -1 }, /* (121) alter_topic_optr ::= alter_db_optr */ - { 195, -2 }, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ - { 226, -1 }, /* (123) typename ::= ids */ - { 226, -4 }, /* (124) typename ::= ids LP signed RP */ - { 226, -2 }, /* (125) typename ::= ids UNSIGNED */ - { 227, -1 }, /* (126) signed ::= INTEGER */ - { 227, -2 }, /* (127) signed ::= PLUS INTEGER */ - { 227, -2 }, /* (128) signed ::= MINUS INTEGER */ - { 189, -3 }, /* (129) cmd ::= CREATE TABLE create_table_args */ - { 189, -3 }, /* (130) cmd ::= CREATE TABLE create_stable_args */ - { 189, -3 }, /* (131) cmd ::= CREATE STABLE create_stable_args */ - { 189, -3 }, /* (132) cmd ::= CREATE TABLE create_table_list */ - { 230, -1 }, /* (133) create_table_list ::= create_from_stable */ - { 230, -2 }, /* (134) create_table_list ::= create_table_list create_from_stable */ - { 228, -6 }, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - { 229, -10 }, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - { 231, -10 }, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - { 231, -13 }, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - { 233, -3 }, /* (139) tagNamelist ::= tagNamelist COMMA ids */ - { 233, -1 }, /* (140) tagNamelist ::= ids */ - { 228, -5 }, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ - { 232, -3 }, /* (142) columnlist ::= columnlist COMMA column */ - { 232, -1 }, /* (143) columnlist ::= column */ - { 235, -2 }, /* (144) column ::= ids typename */ - { 210, -3 }, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ - { 210, -1 }, /* (146) tagitemlist ::= tagitem */ - { 236, -1 }, /* (147) tagitem ::= INTEGER */ - { 236, -1 }, /* (148) tagitem ::= FLOAT */ - { 236, -1 }, /* (149) tagitem ::= STRING */ - { 236, -1 }, /* (150) tagitem ::= BOOL */ - { 236, -1 }, /* (151) tagitem ::= NULL */ - { 236, -2 }, /* (152) tagitem ::= MINUS INTEGER */ - { 236, -2 }, /* (153) tagitem ::= MINUS FLOAT */ - { 236, -2 }, /* (154) tagitem ::= PLUS INTEGER */ - { 236, -2 }, /* (155) tagitem ::= PLUS FLOAT */ - { 234, -13 }, /* (156) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - { 234, -3 }, /* (157) select ::= LP select RP */ - { 249, -1 }, /* (158) union ::= select */ - { 249, -4 }, /* (159) union ::= union UNION ALL select */ - { 189, -1 }, /* (160) cmd ::= union */ - { 234, -2 }, /* (161) select ::= SELECT selcollist */ - { 250, -2 }, /* (162) sclp ::= selcollist COMMA */ - { 250, 0 }, /* (163) sclp ::= */ - { 237, -4 }, /* (164) selcollist ::= sclp distinct expr as */ - { 237, -2 }, /* (165) selcollist ::= sclp STAR */ - { 253, -2 }, /* (166) as ::= AS ids */ - { 253, -1 }, /* (167) as ::= ids */ - { 253, 0 }, /* (168) as ::= */ - { 251, -1 }, /* (169) distinct ::= DISTINCT */ - { 251, 0 }, /* (170) distinct ::= */ - { 238, -2 }, /* (171) from ::= FROM tablelist */ - { 238, -4 }, /* (172) from ::= FROM LP union RP */ - { 254, -2 }, /* (173) tablelist ::= ids cpxName */ - { 254, -3 }, /* (174) tablelist ::= ids cpxName ids */ - { 254, -4 }, /* (175) tablelist ::= tablelist COMMA ids cpxName */ - { 254, -5 }, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ - { 255, -1 }, /* (177) tmvar ::= VARIABLE */ - { 240, -4 }, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ - { 240, -6 }, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - { 240, 0 }, /* (180) interval_opt ::= */ - { 241, 0 }, /* (181) session_option ::= */ - { 241, -7 }, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - { 242, 0 }, /* (183) fill_opt ::= */ - { 242, -6 }, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - { 242, -4 }, /* (185) fill_opt ::= FILL LP ID RP */ - { 243, -4 }, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ - { 243, 0 }, /* (187) sliding_opt ::= */ - { 245, 0 }, /* (188) orderby_opt ::= */ - { 245, -3 }, /* (189) orderby_opt ::= ORDER BY sortlist */ - { 256, -4 }, /* (190) sortlist ::= sortlist COMMA item sortorder */ - { 256, -2 }, /* (191) sortlist ::= item sortorder */ - { 258, -2 }, /* (192) item ::= ids cpxName */ - { 259, -1 }, /* (193) sortorder ::= ASC */ - { 259, -1 }, /* (194) sortorder ::= DESC */ - { 259, 0 }, /* (195) sortorder ::= */ - { 244, 0 }, /* (196) groupby_opt ::= */ - { 244, -3 }, /* (197) groupby_opt ::= GROUP BY grouplist */ - { 260, -3 }, /* (198) grouplist ::= grouplist COMMA item */ - { 260, -1 }, /* (199) grouplist ::= item */ - { 246, 0 }, /* (200) having_opt ::= */ - { 246, -2 }, /* (201) having_opt ::= HAVING expr */ - { 248, 0 }, /* (202) limit_opt ::= */ - { 248, -2 }, /* (203) limit_opt ::= LIMIT signed */ - { 248, -4 }, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ - { 248, -4 }, /* (205) limit_opt ::= LIMIT signed COMMA signed */ - { 247, 0 }, /* (206) slimit_opt ::= */ - { 247, -2 }, /* (207) slimit_opt ::= SLIMIT signed */ - { 247, -4 }, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ - { 247, -4 }, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ - { 239, 0 }, /* (210) where_opt ::= */ - { 239, -2 }, /* (211) where_opt ::= WHERE expr */ - { 252, -3 }, /* (212) expr ::= LP expr RP */ - { 252, -1 }, /* (213) expr ::= ID */ - { 252, -3 }, /* (214) expr ::= ID DOT ID */ - { 252, -3 }, /* (215) expr ::= ID DOT STAR */ - { 252, -1 }, /* (216) expr ::= INTEGER */ - { 252, -2 }, /* (217) expr ::= MINUS INTEGER */ - { 252, -2 }, /* (218) expr ::= PLUS INTEGER */ - { 252, -1 }, /* (219) expr ::= FLOAT */ - { 252, -2 }, /* (220) expr ::= MINUS FLOAT */ - { 252, -2 }, /* (221) expr ::= PLUS FLOAT */ - { 252, -1 }, /* (222) expr ::= STRING */ - { 252, -1 }, /* (223) expr ::= NOW */ - { 252, -1 }, /* (224) expr ::= VARIABLE */ - { 252, -1 }, /* (225) expr ::= BOOL */ - { 252, -1 }, /* (226) expr ::= NULL */ - { 252, -4 }, /* (227) expr ::= ID LP exprlist RP */ - { 252, -4 }, /* (228) expr ::= ID LP STAR RP */ - { 252, -3 }, /* (229) expr ::= expr IS NULL */ - { 252, -4 }, /* (230) expr ::= expr IS NOT NULL */ - { 252, -3 }, /* (231) expr ::= expr LT expr */ - { 252, -3 }, /* (232) expr ::= expr GT expr */ - { 252, -3 }, /* (233) expr ::= expr LE expr */ - { 252, -3 }, /* (234) expr ::= expr GE expr */ - { 252, -3 }, /* (235) expr ::= expr NE expr */ - { 252, -3 }, /* (236) expr ::= expr EQ expr */ - { 252, -5 }, /* (237) expr ::= expr BETWEEN expr AND expr */ - { 252, -3 }, /* (238) expr ::= expr AND expr */ - { 252, -3 }, /* (239) expr ::= expr OR expr */ - { 252, -3 }, /* (240) expr ::= expr PLUS expr */ - { 252, -3 }, /* (241) expr ::= expr MINUS expr */ - { 252, -3 }, /* (242) expr ::= expr STAR expr */ - { 252, -3 }, /* (243) expr ::= expr SLASH expr */ - { 252, -3 }, /* (244) expr ::= expr REM expr */ - { 252, -3 }, /* (245) expr ::= expr LIKE expr */ - { 252, -5 }, /* (246) expr ::= expr IN LP exprlist RP */ - { 261, -3 }, /* (247) exprlist ::= exprlist COMMA expritem */ - { 261, -1 }, /* (248) exprlist ::= expritem */ - { 262, -1 }, /* (249) expritem ::= expr */ - { 262, 0 }, /* (250) expritem ::= */ - { 189, -3 }, /* (251) cmd ::= RESET QUERY CACHE */ - { 189, -3 }, /* (252) cmd ::= SYNCDB ids REPLICA */ - { 189, -7 }, /* (253) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - { 189, -7 }, /* (254) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - { 189, -7 }, /* (255) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - { 189, -7 }, /* (256) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - { 189, -8 }, /* (257) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - { 189, -9 }, /* (258) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - { 189, -7 }, /* (259) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - { 189, -7 }, /* (260) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - { 189, -7 }, /* (261) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - { 189, -7 }, /* (262) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - { 189, -8 }, /* (263) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - { 189, -3 }, /* (264) cmd ::= KILL CONNECTION INTEGER */ - { 189, -5 }, /* (265) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - { 189, -5 }, /* (266) cmd ::= KILL QUERY INTEGER COLON INTEGER */ +/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const YYCODETYPE yyRuleInfoLhs[] = { + 187, /* (0) program ::= cmd */ + 188, /* (1) cmd ::= SHOW DATABASES */ + 188, /* (2) cmd ::= SHOW TOPICS */ + 188, /* (3) cmd ::= SHOW MNODES */ + 188, /* (4) cmd ::= SHOW DNODES */ + 188, /* (5) cmd ::= SHOW ACCOUNTS */ + 188, /* (6) cmd ::= SHOW USERS */ + 188, /* (7) cmd ::= SHOW MODULES */ + 188, /* (8) cmd ::= SHOW QUERIES */ + 188, /* (9) cmd ::= SHOW CONNECTIONS */ + 188, /* (10) cmd ::= SHOW STREAMS */ + 188, /* (11) cmd ::= SHOW VARIABLES */ + 188, /* (12) cmd ::= SHOW SCORES */ + 188, /* (13) cmd ::= SHOW GRANTS */ + 188, /* (14) cmd ::= SHOW VNODES */ + 188, /* (15) cmd ::= SHOW VNODES IPTOKEN */ + 189, /* (16) dbPrefix ::= */ + 189, /* (17) dbPrefix ::= ids DOT */ + 191, /* (18) cpxName ::= */ + 191, /* (19) cpxName ::= DOT ids */ + 188, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ + 188, /* (21) cmd ::= SHOW CREATE DATABASE ids */ + 188, /* (22) cmd ::= SHOW dbPrefix TABLES */ + 188, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + 188, /* (24) cmd ::= SHOW dbPrefix STABLES */ + 188, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + 188, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ + 188, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ + 188, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ + 188, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ + 188, /* (30) cmd ::= DROP DATABASE ifexists ids */ + 188, /* (31) cmd ::= DROP TOPIC ifexists ids */ + 188, /* (32) cmd ::= DROP DNODE ids */ + 188, /* (33) cmd ::= DROP USER ids */ + 188, /* (34) cmd ::= DROP ACCOUNT ids */ + 188, /* (35) cmd ::= USE ids */ + 188, /* (36) cmd ::= DESCRIBE ids cpxName */ + 188, /* (37) cmd ::= ALTER USER ids PASS ids */ + 188, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ + 188, /* (39) cmd ::= ALTER DNODE ids ids */ + 188, /* (40) cmd ::= ALTER DNODE ids ids ids */ + 188, /* (41) cmd ::= ALTER LOCAL ids */ + 188, /* (42) cmd ::= ALTER LOCAL ids ids */ + 188, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ + 188, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ + 188, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ + 188, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + 190, /* (47) ids ::= ID */ + 190, /* (48) ids ::= STRING */ + 192, /* (49) ifexists ::= IF EXISTS */ + 192, /* (50) ifexists ::= */ + 196, /* (51) ifnotexists ::= IF NOT EXISTS */ + 196, /* (52) ifnotexists ::= */ + 188, /* (53) cmd ::= CREATE DNODE ids */ + 188, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + 188, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + 188, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + 188, /* (57) cmd ::= CREATE USER ids PASS ids */ + 199, /* (58) pps ::= */ + 199, /* (59) pps ::= PPS INTEGER */ + 200, /* (60) tseries ::= */ + 200, /* (61) tseries ::= TSERIES INTEGER */ + 201, /* (62) dbs ::= */ + 201, /* (63) dbs ::= DBS INTEGER */ + 202, /* (64) streams ::= */ + 202, /* (65) streams ::= STREAMS INTEGER */ + 203, /* (66) storage ::= */ + 203, /* (67) storage ::= STORAGE INTEGER */ + 204, /* (68) qtime ::= */ + 204, /* (69) qtime ::= QTIME INTEGER */ + 205, /* (70) users ::= */ + 205, /* (71) users ::= USERS INTEGER */ + 206, /* (72) conns ::= */ + 206, /* (73) conns ::= CONNS INTEGER */ + 207, /* (74) state ::= */ + 207, /* (75) state ::= STATE ids */ + 195, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + 208, /* (77) keep ::= KEEP tagitemlist */ + 210, /* (78) cache ::= CACHE INTEGER */ + 211, /* (79) replica ::= REPLICA INTEGER */ + 212, /* (80) quorum ::= QUORUM INTEGER */ + 213, /* (81) days ::= DAYS INTEGER */ + 214, /* (82) minrows ::= MINROWS INTEGER */ + 215, /* (83) maxrows ::= MAXROWS INTEGER */ + 216, /* (84) blocks ::= BLOCKS INTEGER */ + 217, /* (85) ctime ::= CTIME INTEGER */ + 218, /* (86) wal ::= WAL INTEGER */ + 219, /* (87) fsync ::= FSYNC INTEGER */ + 220, /* (88) comp ::= COMP INTEGER */ + 221, /* (89) prec ::= PRECISION STRING */ + 222, /* (90) update ::= UPDATE INTEGER */ + 223, /* (91) cachelast ::= CACHELAST INTEGER */ + 224, /* (92) partitions ::= PARTITIONS INTEGER */ + 197, /* (93) db_optr ::= */ + 197, /* (94) db_optr ::= db_optr cache */ + 197, /* (95) db_optr ::= db_optr replica */ + 197, /* (96) db_optr ::= db_optr quorum */ + 197, /* (97) db_optr ::= db_optr days */ + 197, /* (98) db_optr ::= db_optr minrows */ + 197, /* (99) db_optr ::= db_optr maxrows */ + 197, /* (100) db_optr ::= db_optr blocks */ + 197, /* (101) db_optr ::= db_optr ctime */ + 197, /* (102) db_optr ::= db_optr wal */ + 197, /* (103) db_optr ::= db_optr fsync */ + 197, /* (104) db_optr ::= db_optr comp */ + 197, /* (105) db_optr ::= db_optr prec */ + 197, /* (106) db_optr ::= db_optr keep */ + 197, /* (107) db_optr ::= db_optr update */ + 197, /* (108) db_optr ::= db_optr cachelast */ + 198, /* (109) topic_optr ::= db_optr */ + 198, /* (110) topic_optr ::= topic_optr partitions */ + 193, /* (111) alter_db_optr ::= */ + 193, /* (112) alter_db_optr ::= alter_db_optr replica */ + 193, /* (113) alter_db_optr ::= alter_db_optr quorum */ + 193, /* (114) alter_db_optr ::= alter_db_optr keep */ + 193, /* (115) alter_db_optr ::= alter_db_optr blocks */ + 193, /* (116) alter_db_optr ::= alter_db_optr comp */ + 193, /* (117) alter_db_optr ::= alter_db_optr wal */ + 193, /* (118) alter_db_optr ::= alter_db_optr fsync */ + 193, /* (119) alter_db_optr ::= alter_db_optr update */ + 193, /* (120) alter_db_optr ::= alter_db_optr cachelast */ + 194, /* (121) alter_topic_optr ::= alter_db_optr */ + 194, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ + 225, /* (123) typename ::= ids */ + 225, /* (124) typename ::= ids LP signed RP */ + 225, /* (125) typename ::= ids UNSIGNED */ + 226, /* (126) signed ::= INTEGER */ + 226, /* (127) signed ::= PLUS INTEGER */ + 226, /* (128) signed ::= MINUS INTEGER */ + 188, /* (129) cmd ::= CREATE TABLE create_table_args */ + 188, /* (130) cmd ::= CREATE TABLE create_stable_args */ + 188, /* (131) cmd ::= CREATE STABLE create_stable_args */ + 188, /* (132) cmd ::= CREATE TABLE create_table_list */ + 229, /* (133) create_table_list ::= create_from_stable */ + 229, /* (134) create_table_list ::= create_table_list create_from_stable */ + 227, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + 228, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + 230, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + 230, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + 232, /* (139) tagNamelist ::= tagNamelist COMMA ids */ + 232, /* (140) tagNamelist ::= ids */ + 227, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ + 231, /* (142) columnlist ::= columnlist COMMA column */ + 231, /* (143) columnlist ::= column */ + 234, /* (144) column ::= ids typename */ + 209, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ + 209, /* (146) tagitemlist ::= tagitem */ + 235, /* (147) tagitem ::= INTEGER */ + 235, /* (148) tagitem ::= FLOAT */ + 235, /* (149) tagitem ::= STRING */ + 235, /* (150) tagitem ::= BOOL */ + 235, /* (151) tagitem ::= NULL */ + 235, /* (152) tagitem ::= MINUS INTEGER */ + 235, /* (153) tagitem ::= MINUS FLOAT */ + 235, /* (154) tagitem ::= PLUS INTEGER */ + 235, /* (155) tagitem ::= PLUS FLOAT */ + 233, /* (156) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ + 233, /* (157) select ::= LP select RP */ + 248, /* (158) union ::= select */ + 248, /* (159) union ::= union UNION ALL select */ + 188, /* (160) cmd ::= union */ + 233, /* (161) select ::= SELECT selcollist */ + 249, /* (162) sclp ::= selcollist COMMA */ + 249, /* (163) sclp ::= */ + 236, /* (164) selcollist ::= sclp distinct expr as */ + 236, /* (165) selcollist ::= sclp STAR */ + 252, /* (166) as ::= AS ids */ + 252, /* (167) as ::= ids */ + 252, /* (168) as ::= */ + 250, /* (169) distinct ::= DISTINCT */ + 250, /* (170) distinct ::= */ + 237, /* (171) from ::= FROM tablelist */ + 237, /* (172) from ::= FROM LP union RP */ + 253, /* (173) tablelist ::= ids cpxName */ + 253, /* (174) tablelist ::= ids cpxName ids */ + 253, /* (175) tablelist ::= tablelist COMMA ids cpxName */ + 253, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ + 254, /* (177) tmvar ::= VARIABLE */ + 239, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ + 239, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ + 239, /* (180) interval_opt ::= */ + 240, /* (181) session_option ::= */ + 240, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + 241, /* (183) fill_opt ::= */ + 241, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + 241, /* (185) fill_opt ::= FILL LP ID RP */ + 242, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ + 242, /* (187) sliding_opt ::= */ + 244, /* (188) orderby_opt ::= */ + 244, /* (189) orderby_opt ::= ORDER BY sortlist */ + 255, /* (190) sortlist ::= sortlist COMMA item sortorder */ + 255, /* (191) sortlist ::= item sortorder */ + 257, /* (192) item ::= ids cpxName */ + 258, /* (193) sortorder ::= ASC */ + 258, /* (194) sortorder ::= DESC */ + 258, /* (195) sortorder ::= */ + 243, /* (196) groupby_opt ::= */ + 243, /* (197) groupby_opt ::= GROUP BY grouplist */ + 259, /* (198) grouplist ::= grouplist COMMA item */ + 259, /* (199) grouplist ::= item */ + 245, /* (200) having_opt ::= */ + 245, /* (201) having_opt ::= HAVING expr */ + 247, /* (202) limit_opt ::= */ + 247, /* (203) limit_opt ::= LIMIT signed */ + 247, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ + 247, /* (205) limit_opt ::= LIMIT signed COMMA signed */ + 246, /* (206) slimit_opt ::= */ + 246, /* (207) slimit_opt ::= SLIMIT signed */ + 246, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ + 246, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ + 238, /* (210) where_opt ::= */ + 238, /* (211) where_opt ::= WHERE expr */ + 251, /* (212) expr ::= LP expr RP */ + 251, /* (213) expr ::= ID */ + 251, /* (214) expr ::= ID DOT ID */ + 251, /* (215) expr ::= ID DOT STAR */ + 251, /* (216) expr ::= INTEGER */ + 251, /* (217) expr ::= MINUS INTEGER */ + 251, /* (218) expr ::= PLUS INTEGER */ + 251, /* (219) expr ::= FLOAT */ + 251, /* (220) expr ::= MINUS FLOAT */ + 251, /* (221) expr ::= PLUS FLOAT */ + 251, /* (222) expr ::= STRING */ + 251, /* (223) expr ::= NOW */ + 251, /* (224) expr ::= VARIABLE */ + 251, /* (225) expr ::= BOOL */ + 251, /* (226) expr ::= NULL */ + 251, /* (227) expr ::= ID LP exprlist RP */ + 251, /* (228) expr ::= ID LP STAR RP */ + 251, /* (229) expr ::= expr IS NULL */ + 251, /* (230) expr ::= expr IS NOT NULL */ + 251, /* (231) expr ::= expr LT expr */ + 251, /* (232) expr ::= expr GT expr */ + 251, /* (233) expr ::= expr LE expr */ + 251, /* (234) expr ::= expr GE expr */ + 251, /* (235) expr ::= expr NE expr */ + 251, /* (236) expr ::= expr EQ expr */ + 251, /* (237) expr ::= expr BETWEEN expr AND expr */ + 251, /* (238) expr ::= expr AND expr */ + 251, /* (239) expr ::= expr OR expr */ + 251, /* (240) expr ::= expr PLUS expr */ + 251, /* (241) expr ::= expr MINUS expr */ + 251, /* (242) expr ::= expr STAR expr */ + 251, /* (243) expr ::= expr SLASH expr */ + 251, /* (244) expr ::= expr REM expr */ + 251, /* (245) expr ::= expr LIKE expr */ + 251, /* (246) expr ::= expr IN LP exprlist RP */ + 260, /* (247) exprlist ::= exprlist COMMA expritem */ + 260, /* (248) exprlist ::= expritem */ + 261, /* (249) expritem ::= expr */ + 261, /* (250) expritem ::= */ + 188, /* (251) cmd ::= RESET QUERY CACHE */ + 188, /* (252) cmd ::= SYNCDB ids REPLICA */ + 188, /* (253) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + 188, /* (254) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + 188, /* (255) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + 188, /* (256) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + 188, /* (257) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + 188, /* (258) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + 188, /* (259) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + 188, /* (260) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + 188, /* (261) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + 188, /* (262) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + 188, /* (263) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + 188, /* (264) cmd ::= KILL CONNECTION INTEGER */ + 188, /* (265) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + 188, /* (266) cmd ::= KILL QUERY INTEGER COLON INTEGER */ +}; + +/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char yyRuleInfoNRhs[] = { + -1, /* (0) program ::= cmd */ + -2, /* (1) cmd ::= SHOW DATABASES */ + -2, /* (2) cmd ::= SHOW TOPICS */ + -2, /* (3) cmd ::= SHOW MNODES */ + -2, /* (4) cmd ::= SHOW DNODES */ + -2, /* (5) cmd ::= SHOW ACCOUNTS */ + -2, /* (6) cmd ::= SHOW USERS */ + -2, /* (7) cmd ::= SHOW MODULES */ + -2, /* (8) cmd ::= SHOW QUERIES */ + -2, /* (9) cmd ::= SHOW CONNECTIONS */ + -2, /* (10) cmd ::= SHOW STREAMS */ + -2, /* (11) cmd ::= SHOW VARIABLES */ + -2, /* (12) cmd ::= SHOW SCORES */ + -2, /* (13) cmd ::= SHOW GRANTS */ + -2, /* (14) cmd ::= SHOW VNODES */ + -3, /* (15) cmd ::= SHOW VNODES IPTOKEN */ + 0, /* (16) dbPrefix ::= */ + -2, /* (17) dbPrefix ::= ids DOT */ + 0, /* (18) cpxName ::= */ + -2, /* (19) cpxName ::= DOT ids */ + -5, /* (20) cmd ::= SHOW CREATE TABLE ids cpxName */ + -4, /* (21) cmd ::= SHOW CREATE DATABASE ids */ + -3, /* (22) cmd ::= SHOW dbPrefix TABLES */ + -5, /* (23) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + -3, /* (24) cmd ::= SHOW dbPrefix STABLES */ + -5, /* (25) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + -3, /* (26) cmd ::= SHOW dbPrefix VGROUPS */ + -4, /* (27) cmd ::= SHOW dbPrefix VGROUPS ids */ + -5, /* (28) cmd ::= DROP TABLE ifexists ids cpxName */ + -5, /* (29) cmd ::= DROP STABLE ifexists ids cpxName */ + -4, /* (30) cmd ::= DROP DATABASE ifexists ids */ + -4, /* (31) cmd ::= DROP TOPIC ifexists ids */ + -3, /* (32) cmd ::= DROP DNODE ids */ + -3, /* (33) cmd ::= DROP USER ids */ + -3, /* (34) cmd ::= DROP ACCOUNT ids */ + -2, /* (35) cmd ::= USE ids */ + -3, /* (36) cmd ::= DESCRIBE ids cpxName */ + -5, /* (37) cmd ::= ALTER USER ids PASS ids */ + -5, /* (38) cmd ::= ALTER USER ids PRIVILEGE ids */ + -4, /* (39) cmd ::= ALTER DNODE ids ids */ + -5, /* (40) cmd ::= ALTER DNODE ids ids ids */ + -3, /* (41) cmd ::= ALTER LOCAL ids */ + -4, /* (42) cmd ::= ALTER LOCAL ids ids */ + -4, /* (43) cmd ::= ALTER DATABASE ids alter_db_optr */ + -4, /* (44) cmd ::= ALTER TOPIC ids alter_topic_optr */ + -4, /* (45) cmd ::= ALTER ACCOUNT ids acct_optr */ + -6, /* (46) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + -1, /* (47) ids ::= ID */ + -1, /* (48) ids ::= STRING */ + -2, /* (49) ifexists ::= IF EXISTS */ + 0, /* (50) ifexists ::= */ + -3, /* (51) ifnotexists ::= IF NOT EXISTS */ + 0, /* (52) ifnotexists ::= */ + -3, /* (53) cmd ::= CREATE DNODE ids */ + -6, /* (54) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + -5, /* (55) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + -5, /* (56) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + -5, /* (57) cmd ::= CREATE USER ids PASS ids */ + 0, /* (58) pps ::= */ + -2, /* (59) pps ::= PPS INTEGER */ + 0, /* (60) tseries ::= */ + -2, /* (61) tseries ::= TSERIES INTEGER */ + 0, /* (62) dbs ::= */ + -2, /* (63) dbs ::= DBS INTEGER */ + 0, /* (64) streams ::= */ + -2, /* (65) streams ::= STREAMS INTEGER */ + 0, /* (66) storage ::= */ + -2, /* (67) storage ::= STORAGE INTEGER */ + 0, /* (68) qtime ::= */ + -2, /* (69) qtime ::= QTIME INTEGER */ + 0, /* (70) users ::= */ + -2, /* (71) users ::= USERS INTEGER */ + 0, /* (72) conns ::= */ + -2, /* (73) conns ::= CONNS INTEGER */ + 0, /* (74) state ::= */ + -2, /* (75) state ::= STATE ids */ + -9, /* (76) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + -2, /* (77) keep ::= KEEP tagitemlist */ + -2, /* (78) cache ::= CACHE INTEGER */ + -2, /* (79) replica ::= REPLICA INTEGER */ + -2, /* (80) quorum ::= QUORUM INTEGER */ + -2, /* (81) days ::= DAYS INTEGER */ + -2, /* (82) minrows ::= MINROWS INTEGER */ + -2, /* (83) maxrows ::= MAXROWS INTEGER */ + -2, /* (84) blocks ::= BLOCKS INTEGER */ + -2, /* (85) ctime ::= CTIME INTEGER */ + -2, /* (86) wal ::= WAL INTEGER */ + -2, /* (87) fsync ::= FSYNC INTEGER */ + -2, /* (88) comp ::= COMP INTEGER */ + -2, /* (89) prec ::= PRECISION STRING */ + -2, /* (90) update ::= UPDATE INTEGER */ + -2, /* (91) cachelast ::= CACHELAST INTEGER */ + -2, /* (92) partitions ::= PARTITIONS INTEGER */ + 0, /* (93) db_optr ::= */ + -2, /* (94) db_optr ::= db_optr cache */ + -2, /* (95) db_optr ::= db_optr replica */ + -2, /* (96) db_optr ::= db_optr quorum */ + -2, /* (97) db_optr ::= db_optr days */ + -2, /* (98) db_optr ::= db_optr minrows */ + -2, /* (99) db_optr ::= db_optr maxrows */ + -2, /* (100) db_optr ::= db_optr blocks */ + -2, /* (101) db_optr ::= db_optr ctime */ + -2, /* (102) db_optr ::= db_optr wal */ + -2, /* (103) db_optr ::= db_optr fsync */ + -2, /* (104) db_optr ::= db_optr comp */ + -2, /* (105) db_optr ::= db_optr prec */ + -2, /* (106) db_optr ::= db_optr keep */ + -2, /* (107) db_optr ::= db_optr update */ + -2, /* (108) db_optr ::= db_optr cachelast */ + -1, /* (109) topic_optr ::= db_optr */ + -2, /* (110) topic_optr ::= topic_optr partitions */ + 0, /* (111) alter_db_optr ::= */ + -2, /* (112) alter_db_optr ::= alter_db_optr replica */ + -2, /* (113) alter_db_optr ::= alter_db_optr quorum */ + -2, /* (114) alter_db_optr ::= alter_db_optr keep */ + -2, /* (115) alter_db_optr ::= alter_db_optr blocks */ + -2, /* (116) alter_db_optr ::= alter_db_optr comp */ + -2, /* (117) alter_db_optr ::= alter_db_optr wal */ + -2, /* (118) alter_db_optr ::= alter_db_optr fsync */ + -2, /* (119) alter_db_optr ::= alter_db_optr update */ + -2, /* (120) alter_db_optr ::= alter_db_optr cachelast */ + -1, /* (121) alter_topic_optr ::= alter_db_optr */ + -2, /* (122) alter_topic_optr ::= alter_topic_optr partitions */ + -1, /* (123) typename ::= ids */ + -4, /* (124) typename ::= ids LP signed RP */ + -2, /* (125) typename ::= ids UNSIGNED */ + -1, /* (126) signed ::= INTEGER */ + -2, /* (127) signed ::= PLUS INTEGER */ + -2, /* (128) signed ::= MINUS INTEGER */ + -3, /* (129) cmd ::= CREATE TABLE create_table_args */ + -3, /* (130) cmd ::= CREATE TABLE create_stable_args */ + -3, /* (131) cmd ::= CREATE STABLE create_stable_args */ + -3, /* (132) cmd ::= CREATE TABLE create_table_list */ + -1, /* (133) create_table_list ::= create_from_stable */ + -2, /* (134) create_table_list ::= create_table_list create_from_stable */ + -6, /* (135) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + -10, /* (136) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + -10, /* (137) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + -13, /* (138) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + -3, /* (139) tagNamelist ::= tagNamelist COMMA ids */ + -1, /* (140) tagNamelist ::= ids */ + -5, /* (141) create_table_args ::= ifnotexists ids cpxName AS select */ + -3, /* (142) columnlist ::= columnlist COMMA column */ + -1, /* (143) columnlist ::= column */ + -2, /* (144) column ::= ids typename */ + -3, /* (145) tagitemlist ::= tagitemlist COMMA tagitem */ + -1, /* (146) tagitemlist ::= tagitem */ + -1, /* (147) tagitem ::= INTEGER */ + -1, /* (148) tagitem ::= FLOAT */ + -1, /* (149) tagitem ::= STRING */ + -1, /* (150) tagitem ::= BOOL */ + -1, /* (151) tagitem ::= NULL */ + -2, /* (152) tagitem ::= MINUS INTEGER */ + -2, /* (153) tagitem ::= MINUS FLOAT */ + -2, /* (154) tagitem ::= PLUS INTEGER */ + -2, /* (155) tagitem ::= PLUS FLOAT */ + -13, /* (156) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ + -3, /* (157) select ::= LP select RP */ + -1, /* (158) union ::= select */ + -4, /* (159) union ::= union UNION ALL select */ + -1, /* (160) cmd ::= union */ + -2, /* (161) select ::= SELECT selcollist */ + -2, /* (162) sclp ::= selcollist COMMA */ + 0, /* (163) sclp ::= */ + -4, /* (164) selcollist ::= sclp distinct expr as */ + -2, /* (165) selcollist ::= sclp STAR */ + -2, /* (166) as ::= AS ids */ + -1, /* (167) as ::= ids */ + 0, /* (168) as ::= */ + -1, /* (169) distinct ::= DISTINCT */ + 0, /* (170) distinct ::= */ + -2, /* (171) from ::= FROM tablelist */ + -4, /* (172) from ::= FROM LP union RP */ + -2, /* (173) tablelist ::= ids cpxName */ + -3, /* (174) tablelist ::= ids cpxName ids */ + -4, /* (175) tablelist ::= tablelist COMMA ids cpxName */ + -5, /* (176) tablelist ::= tablelist COMMA ids cpxName ids */ + -1, /* (177) tmvar ::= VARIABLE */ + -4, /* (178) interval_opt ::= INTERVAL LP tmvar RP */ + -6, /* (179) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ + 0, /* (180) interval_opt ::= */ + 0, /* (181) session_option ::= */ + -7, /* (182) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + 0, /* (183) fill_opt ::= */ + -6, /* (184) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + -4, /* (185) fill_opt ::= FILL LP ID RP */ + -4, /* (186) sliding_opt ::= SLIDING LP tmvar RP */ + 0, /* (187) sliding_opt ::= */ + 0, /* (188) orderby_opt ::= */ + -3, /* (189) orderby_opt ::= ORDER BY sortlist */ + -4, /* (190) sortlist ::= sortlist COMMA item sortorder */ + -2, /* (191) sortlist ::= item sortorder */ + -2, /* (192) item ::= ids cpxName */ + -1, /* (193) sortorder ::= ASC */ + -1, /* (194) sortorder ::= DESC */ + 0, /* (195) sortorder ::= */ + 0, /* (196) groupby_opt ::= */ + -3, /* (197) groupby_opt ::= GROUP BY grouplist */ + -3, /* (198) grouplist ::= grouplist COMMA item */ + -1, /* (199) grouplist ::= item */ + 0, /* (200) having_opt ::= */ + -2, /* (201) having_opt ::= HAVING expr */ + 0, /* (202) limit_opt ::= */ + -2, /* (203) limit_opt ::= LIMIT signed */ + -4, /* (204) limit_opt ::= LIMIT signed OFFSET signed */ + -4, /* (205) limit_opt ::= LIMIT signed COMMA signed */ + 0, /* (206) slimit_opt ::= */ + -2, /* (207) slimit_opt ::= SLIMIT signed */ + -4, /* (208) slimit_opt ::= SLIMIT signed SOFFSET signed */ + -4, /* (209) slimit_opt ::= SLIMIT signed COMMA signed */ + 0, /* (210) where_opt ::= */ + -2, /* (211) where_opt ::= WHERE expr */ + -3, /* (212) expr ::= LP expr RP */ + -1, /* (213) expr ::= ID */ + -3, /* (214) expr ::= ID DOT ID */ + -3, /* (215) expr ::= ID DOT STAR */ + -1, /* (216) expr ::= INTEGER */ + -2, /* (217) expr ::= MINUS INTEGER */ + -2, /* (218) expr ::= PLUS INTEGER */ + -1, /* (219) expr ::= FLOAT */ + -2, /* (220) expr ::= MINUS FLOAT */ + -2, /* (221) expr ::= PLUS FLOAT */ + -1, /* (222) expr ::= STRING */ + -1, /* (223) expr ::= NOW */ + -1, /* (224) expr ::= VARIABLE */ + -1, /* (225) expr ::= BOOL */ + -1, /* (226) expr ::= NULL */ + -4, /* (227) expr ::= ID LP exprlist RP */ + -4, /* (228) expr ::= ID LP STAR RP */ + -3, /* (229) expr ::= expr IS NULL */ + -4, /* (230) expr ::= expr IS NOT NULL */ + -3, /* (231) expr ::= expr LT expr */ + -3, /* (232) expr ::= expr GT expr */ + -3, /* (233) expr ::= expr LE expr */ + -3, /* (234) expr ::= expr GE expr */ + -3, /* (235) expr ::= expr NE expr */ + -3, /* (236) expr ::= expr EQ expr */ + -5, /* (237) expr ::= expr BETWEEN expr AND expr */ + -3, /* (238) expr ::= expr AND expr */ + -3, /* (239) expr ::= expr OR expr */ + -3, /* (240) expr ::= expr PLUS expr */ + -3, /* (241) expr ::= expr MINUS expr */ + -3, /* (242) expr ::= expr STAR expr */ + -3, /* (243) expr ::= expr SLASH expr */ + -3, /* (244) expr ::= expr REM expr */ + -3, /* (245) expr ::= expr LIKE expr */ + -5, /* (246) expr ::= expr IN LP exprlist RP */ + -3, /* (247) exprlist ::= exprlist COMMA expritem */ + -1, /* (248) exprlist ::= expritem */ + -1, /* (249) expritem ::= expr */ + 0, /* (250) expritem ::= */ + -3, /* (251) cmd ::= RESET QUERY CACHE */ + -3, /* (252) cmd ::= SYNCDB ids REPLICA */ + -7, /* (253) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (254) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + -7, /* (255) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + -7, /* (256) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + -8, /* (257) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (258) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (259) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (260) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + -7, /* (261) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + -7, /* (262) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + -8, /* (263) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + -3, /* (264) cmd ::= KILL CONNECTION INTEGER */ + -5, /* (265) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + -5, /* (266) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2026,30 +2310,34 @@ static void yy_accept(yyParser*); /* Forward Declaration */ ** only called from one place, optimizing compilers will in-line it, which ** means that the extra parameters have no performance impact. */ -static void yy_reduce( +static YYACTIONTYPE yy_reduce( yyParser *yypParser, /* The parser */ unsigned int yyruleno, /* Number of the rule by which to reduce */ int yyLookahead, /* Lookahead token, or YYNOCODE if none */ ParseTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + ParseCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ - int yyact; /* The next action */ + YYACTIONTYPE yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; + ParseARG_FETCH (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; + yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", yyTracePrompt, - yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ yypParser->yyhwm++; @@ -2067,13 +2355,19 @@ static void yy_reduce( #if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ yyStackOverflow(yypParser); - return; + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); - return; + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; } yymsp = yypParser->yytos; } @@ -2258,13 +2552,13 @@ static void yy_reduce( break; case 43: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 44: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==44); -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy322, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy94, &t);} break; case 45: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy351);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy419);} break; case 46: /* cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy351);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy419);} break; case 47: /* ids ::= ID */ case 48: /* ids ::= STRING */ yytestcase(yyruleno==48); @@ -2286,11 +2580,11 @@ static void yy_reduce( { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} break; case 54: /* cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy351);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy419);} break; case 55: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 56: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==56); -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy322, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy94, &yymsp[-2].minor.yy0);} break; case 57: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2319,20 +2613,20 @@ static void yy_reduce( break; case 76: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy351.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy351.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy351.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy351.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy351.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy351.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy351.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy351.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy351.stat = yymsp[0].minor.yy0; + yylhsminor.yy419.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy419.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy419.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy419.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy419.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy419.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy419.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy419.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy419.stat = yymsp[0].minor.yy0; } - yymsp[-8].minor.yy351 = yylhsminor.yy351; + yymsp[-8].minor.yy419 = yylhsminor.yy419; break; case 77: /* keep ::= KEEP tagitemlist */ -{ yymsp[-1].minor.yy159 = yymsp[0].minor.yy159; } +{ yymsp[-1].minor.yy429 = yymsp[0].minor.yy429; } break; case 78: /* cache ::= CACHE INTEGER */ case 79: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==79); @@ -2352,234 +2646,234 @@ static void yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 93: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy94); yymsp[1].minor.yy94.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 94: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 95: /* db_optr ::= db_optr replica */ case 112: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==112); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 96: /* db_optr ::= db_optr quorum */ case 113: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==113); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 97: /* db_optr ::= db_optr days */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 98: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 99: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 100: /* db_optr ::= db_optr blocks */ case 115: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==115); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 101: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 102: /* db_optr ::= db_optr wal */ case 117: /* alter_db_optr ::= alter_db_optr wal */ yytestcase(yyruleno==117); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 103: /* db_optr ::= db_optr fsync */ case 118: /* alter_db_optr ::= alter_db_optr fsync */ yytestcase(yyruleno==118); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 104: /* db_optr ::= db_optr comp */ case 116: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==116); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 105: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 106: /* db_optr ::= db_optr keep */ case 114: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==114); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.keep = yymsp[0].minor.yy159; } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.keep = yymsp[0].minor.yy429; } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 107: /* db_optr ::= db_optr update */ case 119: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==119); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 108: /* db_optr ::= db_optr cachelast */ case 120: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==120); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 109: /* topic_optr ::= db_optr */ case 121: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==121); -{ yylhsminor.yy322 = yymsp[0].minor.yy322; yylhsminor.yy322.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[0].minor.yy94; yylhsminor.yy94.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy94 = yylhsminor.yy94; break; case 110: /* topic_optr ::= topic_optr partitions */ case 122: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==122); -{ yylhsminor.yy322 = yymsp[-1].minor.yy322; yylhsminor.yy322.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy322 = yylhsminor.yy322; +{ yylhsminor.yy94 = yymsp[-1].minor.yy94; yylhsminor.yy94.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy94 = yylhsminor.yy94; break; case 111: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy322); yymsp[1].minor.yy322.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy94); yymsp[1].minor.yy94.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 123: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy407, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy451, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy407 = yylhsminor.yy407; + yymsp[0].minor.yy451 = yylhsminor.yy451; break; case 124: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy317 <= 0) { + if (yymsp[-1].minor.yy481 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy451, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy317; // negative value of name length - tSetColumnType(&yylhsminor.yy407, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy481; // negative value of name length + tSetColumnType(&yylhsminor.yy451, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy407 = yylhsminor.yy407; + yymsp[-3].minor.yy451 = yylhsminor.yy451; break; case 125: /* typename ::= ids UNSIGNED */ { yymsp[-1].minor.yy0.type = 0; yymsp[-1].minor.yy0.n = ((yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z); - tSetColumnType (&yylhsminor.yy407, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy451, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy407 = yylhsminor.yy407; + yymsp[-1].minor.yy451 = yylhsminor.yy451; break; case 126: /* signed ::= INTEGER */ -{ yylhsminor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy317 = yylhsminor.yy317; +{ yylhsminor.yy481 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy481 = yylhsminor.yy481; break; case 127: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy317 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy481 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 128: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy317 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.yy481 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} break; case 132: /* cmd ::= CREATE TABLE create_table_list */ -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy14;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy194;} break; case 133: /* create_table_list ::= create_from_stable */ { SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy206); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy252); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy14 = pCreateTable; + yylhsminor.yy194 = pCreateTable; } - yymsp[0].minor.yy14 = yylhsminor.yy14; + yymsp[0].minor.yy194 = yylhsminor.yy194; break; case 134: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy14->childTableInfo, &yymsp[0].minor.yy206); - yylhsminor.yy14 = yymsp[-1].minor.yy14; + taosArrayPush(yymsp[-1].minor.yy194->childTableInfo, &yymsp[0].minor.yy252); + yylhsminor.yy194 = yymsp[-1].minor.yy194; } - yymsp[-1].minor.yy14 = yylhsminor.yy14; + yymsp[-1].minor.yy194 = yylhsminor.yy194; break; case 135: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-1].minor.yy159, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy194 = tSetCreateTableInfo(yymsp[-1].minor.yy429, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-4].minor.yy0, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy14 = yylhsminor.yy14; + yymsp[-5].minor.yy194 = yylhsminor.yy194; break; case 136: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy14 = tSetCreateTableInfo(yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy194 = tSetCreateTableInfo(yymsp[-5].minor.yy429, yymsp[-1].minor.yy429, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy14 = yylhsminor.yy14; + yymsp[-9].minor.yy194 = yylhsminor.yy194; break; case 137: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; - yylhsminor.yy206 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy159, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy252 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy429, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy206 = yylhsminor.yy206; + yymsp[-9].minor.yy252 = yylhsminor.yy252; break; case 138: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ { yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; yymsp[-11].minor.yy0.n += yymsp[-10].minor.yy0.n; - yylhsminor.yy206 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy159, yymsp[-1].minor.yy159, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy252 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy429, yymsp[-1].minor.yy429, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy206 = yylhsminor.yy206; + yymsp[-12].minor.yy252 = yylhsminor.yy252; break; case 139: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy0); yylhsminor.yy159 = yymsp[-2].minor.yy159; } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{taosArrayPush(yymsp[-2].minor.yy429, &yymsp[0].minor.yy0); yylhsminor.yy429 = yymsp[-2].minor.yy429; } + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 140: /* tagNamelist ::= ids */ -{yylhsminor.yy159 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy429 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy429, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy429 = yylhsminor.yy429; break; case 141: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy14 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy272, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy14, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy194 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy254, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy194, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy14 = yylhsminor.yy14; + yymsp[-4].minor.yy194 = yylhsminor.yy194; break; case 142: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy159, &yymsp[0].minor.yy407); yylhsminor.yy159 = yymsp[-2].minor.yy159; } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{taosArrayPush(yymsp[-2].minor.yy429, &yymsp[0].minor.yy451); yylhsminor.yy429 = yymsp[-2].minor.yy429; } + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 143: /* columnlist ::= column */ -{yylhsminor.yy159 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy159, &yymsp[0].minor.yy407);} - yymsp[0].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy429 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy429, &yymsp[0].minor.yy451);} + yymsp[0].minor.yy429 = yylhsminor.yy429; break; case 144: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy407, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy407); + tSetColumnInfo(&yylhsminor.yy451, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy451); } - yymsp[-1].minor.yy407 = yylhsminor.yy407; + yymsp[-1].minor.yy451 = yylhsminor.yy451; break; case 145: /* tagitemlist ::= tagitemlist COMMA tagitem */ -{ yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); } - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy429 = tVariantListAppend(yymsp[-2].minor.yy429, &yymsp[0].minor.yy218, -1); } + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 146: /* tagitemlist ::= tagitem */ -{ yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); } - yymsp[0].minor.yy159 = yylhsminor.yy159; +{ yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[0].minor.yy218, -1); } + yymsp[0].minor.yy429 = yylhsminor.yy429; break; case 147: /* tagitem ::= INTEGER */ case 148: /* tagitem ::= FLOAT */ yytestcase(yyruleno==148); case 149: /* tagitem ::= STRING */ yytestcase(yyruleno==149); case 150: /* tagitem ::= BOOL */ yytestcase(yyruleno==150); -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy218, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy218 = yylhsminor.yy218; break; case 151: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy488, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy488 = yylhsminor.yy488; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy218, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy218 = yylhsminor.yy218; break; case 152: /* tagitem ::= MINUS INTEGER */ case 153: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==153); @@ -2589,56 +2883,56 @@ static void yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = yymsp[0].minor.yy0.type; toTSDBType(yymsp[-1].minor.yy0.type); - tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy218, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy488 = yylhsminor.yy488; + yymsp[-1].minor.yy218 = yylhsminor.yy218; break; case 156: /* select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ { - yylhsminor.yy272 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy159, yymsp[-10].minor.yy514, yymsp[-9].minor.yy118, yymsp[-4].minor.yy159, yymsp[-3].minor.yy159, &yymsp[-8].minor.yy184, &yymsp[-7].minor.yy249, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy159, &yymsp[0].minor.yy440, &yymsp[-1].minor.yy440); + yylhsminor.yy254 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy429, yymsp[-10].minor.yy70, yymsp[-9].minor.yy170, yymsp[-4].minor.yy429, yymsp[-3].minor.yy429, &yymsp[-8].minor.yy220, &yymsp[-7].minor.yy87, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy429, &yymsp[0].minor.yy18, &yymsp[-1].minor.yy18, yymsp[-2].minor.yy170); } - yymsp[-12].minor.yy272 = yylhsminor.yy272; + yymsp[-12].minor.yy254 = yylhsminor.yy254; break; case 157: /* select ::= LP select RP */ -{yymsp[-2].minor.yy272 = yymsp[-1].minor.yy272;} +{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} break; case 158: /* union ::= select */ -{ yylhsminor.yy391 = setSubclause(NULL, yymsp[0].minor.yy272); } - yymsp[0].minor.yy391 = yylhsminor.yy391; +{ yylhsminor.yy141 = setSubclause(NULL, yymsp[0].minor.yy254); } + yymsp[0].minor.yy141 = yylhsminor.yy141; break; case 159: /* union ::= union UNION ALL select */ -{ yylhsminor.yy391 = appendSelectClause(yymsp[-3].minor.yy391, yymsp[0].minor.yy272); } - yymsp[-3].minor.yy391 = yylhsminor.yy391; +{ yylhsminor.yy141 = appendSelectClause(yymsp[-3].minor.yy141, yymsp[0].minor.yy254); } + yymsp[-3].minor.yy141 = yylhsminor.yy141; break; case 160: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy391, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy141, NULL, TSDB_SQL_SELECT); } break; case 161: /* select ::= SELECT selcollist */ { - yylhsminor.yy272 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy159, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy254 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy429, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy272 = yylhsminor.yy272; + yymsp[-1].minor.yy254 = yylhsminor.yy254; break; case 162: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy159 = yymsp[-1].minor.yy159;} - yymsp[-1].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy429 = yymsp[-1].minor.yy429;} + yymsp[-1].minor.yy429 = yylhsminor.yy429; break; case 163: /* sclp ::= */ case 188: /* orderby_opt ::= */ yytestcase(yyruleno==188); -{yymsp[1].minor.yy159 = 0;} +{yymsp[1].minor.yy429 = 0;} break; case 164: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy159 = tSqlExprListAppend(yymsp[-3].minor.yy159, yymsp[-1].minor.yy118, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.yy429 = tSqlExprListAppend(yymsp[-3].minor.yy429, yymsp[-1].minor.yy170, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } - yymsp[-3].minor.yy159 = yylhsminor.yy159; + yymsp[-3].minor.yy429 = yylhsminor.yy429; break; case 165: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy159 = tSqlExprListAppend(yymsp[-1].minor.yy159, pNode, 0, 0); + yylhsminor.yy429 = tSqlExprListAppend(yymsp[-1].minor.yy429, pNode, 0, 0); } - yymsp[-1].minor.yy159 = yylhsminor.yy159; + yymsp[-1].minor.yy429 = yylhsminor.yy429; break; case 166: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -2655,35 +2949,35 @@ static void yy_reduce( yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 171: /* from ::= FROM tablelist */ -{yymsp[-1].minor.yy514 = yymsp[0].minor.yy159;} +{yymsp[-1].minor.yy70 = yymsp[0].minor.yy429;} break; case 172: /* from ::= FROM LP union RP */ -{yymsp[-3].minor.yy514 = yymsp[-1].minor.yy391;} +{yymsp[-3].minor.yy70 = yymsp[-1].minor.yy141;} break; case 173: /* tablelist ::= ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy159 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy429 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy159 = yylhsminor.yy159; + yymsp[-1].minor.yy429 = yylhsminor.yy429; break; case 174: /* tablelist ::= ids cpxName ids */ { toTSDBType(yymsp[-2].minor.yy0.type); toTSDBType(yymsp[0].minor.yy0.type); yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy159 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy429 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy159 = yylhsminor.yy159; + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 175: /* tablelist ::= tablelist COMMA ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy159 = setTableNameList(yymsp[-3].minor.yy159, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy429 = setTableNameList(yymsp[-3].minor.yy429, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy159 = yylhsminor.yy159; + yymsp[-3].minor.yy429 = yylhsminor.yy429; break; case 176: /* tablelist ::= tablelist COMMA ids cpxName ids */ { @@ -2691,35 +2985,35 @@ static void yy_reduce( toTSDBType(yymsp[0].minor.yy0.type); yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy159 = setTableNameList(yymsp[-4].minor.yy159, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy429 = setTableNameList(yymsp[-4].minor.yy429, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy159 = yylhsminor.yy159; + yymsp[-4].minor.yy429 = yylhsminor.yy429; break; case 177: /* tmvar ::= VARIABLE */ {yylhsminor.yy0 = yymsp[0].minor.yy0;} yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 178: /* interval_opt ::= INTERVAL LP tmvar RP */ -{yymsp[-3].minor.yy184.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy184.offset.n = 0;} +{yymsp[-3].minor.yy220.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy220.offset.n = 0;} break; case 179: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ -{yymsp[-5].minor.yy184.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy184.offset = yymsp[-1].minor.yy0;} +{yymsp[-5].minor.yy220.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy220.offset = yymsp[-1].minor.yy0;} break; case 180: /* interval_opt ::= */ -{memset(&yymsp[1].minor.yy184, 0, sizeof(yymsp[1].minor.yy184));} +{memset(&yymsp[1].minor.yy220, 0, sizeof(yymsp[1].minor.yy220));} break; case 181: /* session_option ::= */ -{yymsp[1].minor.yy249.col.n = 0; yymsp[1].minor.yy249.gap.n = 0;} +{yymsp[1].minor.yy87.col.n = 0; yymsp[1].minor.yy87.gap.n = 0;} break; case 182: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy249.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy249.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy87.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy87.gap = yymsp[-1].minor.yy0; } break; case 183: /* fill_opt ::= */ -{ yymsp[1].minor.yy159 = 0; } +{ yymsp[1].minor.yy429 = 0; } break; case 184: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { @@ -2727,14 +3021,14 @@ static void yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0); - tVariantListInsert(yymsp[-1].minor.yy159, &A, -1, 0); - yymsp[-5].minor.yy159 = yymsp[-1].minor.yy159; + tVariantListInsert(yymsp[-1].minor.yy429, &A, -1, 0); + yymsp[-5].minor.yy429 = yymsp[-1].minor.yy429; } break; case 185: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy159 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yymsp[-3].minor.yy429 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } break; case 186: /* sliding_opt ::= SLIDING LP tmvar RP */ @@ -2744,230 +3038,230 @@ static void yy_reduce( {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } break; case 189: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} +{yymsp[-2].minor.yy429 = yymsp[0].minor.yy429;} break; case 190: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy159 = tVariantListAppend(yymsp[-3].minor.yy159, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); + yylhsminor.yy429 = tVariantListAppend(yymsp[-3].minor.yy429, &yymsp[-1].minor.yy218, yymsp[0].minor.yy116); } - yymsp[-3].minor.yy159 = yylhsminor.yy159; + yymsp[-3].minor.yy429 = yylhsminor.yy429; break; case 191: /* sortlist ::= item sortorder */ { - yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[-1].minor.yy488, yymsp[0].minor.yy20); + yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[-1].minor.yy218, yymsp[0].minor.yy116); } - yymsp[-1].minor.yy159 = yylhsminor.yy159; + yymsp[-1].minor.yy429 = yylhsminor.yy429; break; case 192: /* item ::= ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - tVariantCreate(&yylhsminor.yy488, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy218, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy488 = yylhsminor.yy488; + yymsp[-1].minor.yy218 = yylhsminor.yy218; break; case 193: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy20 = TSDB_ORDER_ASC; } +{ yymsp[0].minor.yy116 = TSDB_ORDER_ASC; } break; case 194: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy20 = TSDB_ORDER_DESC;} +{ yymsp[0].minor.yy116 = TSDB_ORDER_DESC;} break; case 195: /* sortorder ::= */ -{ yymsp[1].minor.yy20 = TSDB_ORDER_ASC; } +{ yymsp[1].minor.yy116 = TSDB_ORDER_ASC; } break; case 196: /* groupby_opt ::= */ -{ yymsp[1].minor.yy159 = 0;} +{ yymsp[1].minor.yy429 = 0;} break; case 197: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy159 = yymsp[0].minor.yy159;} +{ yymsp[-2].minor.yy429 = yymsp[0].minor.yy429;} break; case 198: /* grouplist ::= grouplist COMMA item */ { - yylhsminor.yy159 = tVariantListAppend(yymsp[-2].minor.yy159, &yymsp[0].minor.yy488, -1); + yylhsminor.yy429 = tVariantListAppend(yymsp[-2].minor.yy429, &yymsp[0].minor.yy218, -1); } - yymsp[-2].minor.yy159 = yylhsminor.yy159; + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 199: /* grouplist ::= item */ { - yylhsminor.yy159 = tVariantListAppend(NULL, &yymsp[0].minor.yy488, -1); + yylhsminor.yy429 = tVariantListAppend(NULL, &yymsp[0].minor.yy218, -1); } - yymsp[0].minor.yy159 = yylhsminor.yy159; + yymsp[0].minor.yy429 = yylhsminor.yy429; break; case 200: /* having_opt ::= */ case 210: /* where_opt ::= */ yytestcase(yyruleno==210); case 250: /* expritem ::= */ yytestcase(yyruleno==250); -{yymsp[1].minor.yy118 = 0;} +{yymsp[1].minor.yy170 = 0;} break; case 201: /* having_opt ::= HAVING expr */ case 211: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==211); -{yymsp[-1].minor.yy118 = yymsp[0].minor.yy118;} +{yymsp[-1].minor.yy170 = yymsp[0].minor.yy170;} break; case 202: /* limit_opt ::= */ case 206: /* slimit_opt ::= */ yytestcase(yyruleno==206); -{yymsp[1].minor.yy440.limit = -1; yymsp[1].minor.yy440.offset = 0;} +{yymsp[1].minor.yy18.limit = -1; yymsp[1].minor.yy18.offset = 0;} break; case 203: /* limit_opt ::= LIMIT signed */ case 207: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==207); -{yymsp[-1].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-1].minor.yy440.offset = 0;} +{yymsp[-1].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-1].minor.yy18.offset = 0;} break; case 204: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} +{ yymsp[-3].minor.yy18.limit = yymsp[-2].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[0].minor.yy481;} break; case 205: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} +{ yymsp[-3].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[-2].minor.yy481;} break; case 208: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy440.limit = yymsp[-2].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[0].minor.yy317;} +{yymsp[-3].minor.yy18.limit = yymsp[-2].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[0].minor.yy481;} break; case 209: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy440.limit = yymsp[0].minor.yy317; yymsp[-3].minor.yy440.offset = yymsp[-2].minor.yy317;} +{yymsp[-3].minor.yy18.limit = yymsp[0].minor.yy481; yymsp[-3].minor.yy18.offset = yymsp[-2].minor.yy481;} break; case 212: /* expr ::= LP expr RP */ -{yylhsminor.yy118 = yymsp[-1].minor.yy118; yylhsminor.yy118->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy118->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = yymsp[-1].minor.yy170; yylhsminor.yy170->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy170->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 213: /* expr ::= ID */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 214: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 215: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 216: /* expr ::= INTEGER */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 217: /* expr ::= MINUS INTEGER */ case 218: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==218); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy118 = yylhsminor.yy118; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy170 = yylhsminor.yy170; break; case 219: /* expr ::= FLOAT */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 220: /* expr ::= MINUS FLOAT */ case 221: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==221); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy118 = yylhsminor.yy118; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} + yymsp[-1].minor.yy170 = yylhsminor.yy170; break; case 222: /* expr ::= STRING */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 223: /* expr ::= NOW */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 224: /* expr ::= VARIABLE */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 225: /* expr ::= BOOL */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 226: /* expr ::= NULL */ -{ yylhsminor.yy118 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 227: /* expr ::= ID LP exprlist RP */ -{ yylhsminor.yy118 = tSqlExprCreateFunction(yymsp[-1].minor.yy159, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateFunction(yymsp[-1].minor.yy429, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy170 = yylhsminor.yy170; break; case 228: /* expr ::= ID LP STAR RP */ -{ yylhsminor.yy118 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy118 = yylhsminor.yy118; +{ yylhsminor.yy170 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy170 = yylhsminor.yy170; break; case 229: /* expr ::= expr IS NULL */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, NULL, TK_ISNULL);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, NULL, TK_ISNULL);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 230: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-3].minor.yy118, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-3].minor.yy170, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy170 = yylhsminor.yy170; break; case 231: /* expr ::= expr LT expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LT);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LT);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 232: /* expr ::= expr GT expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GT);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_GT);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 233: /* expr ::= expr LE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LE);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 234: /* expr ::= expr GE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_GE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_GE);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 235: /* expr ::= expr NE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_NE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_NE);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 236: /* expr ::= expr EQ expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_EQ);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_EQ);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 237: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy118); yylhsminor.yy118 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy118, yymsp[-2].minor.yy118, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy118, TK_LE), TK_AND);} - yymsp[-4].minor.yy118 = yylhsminor.yy118; +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy170); yylhsminor.yy170 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy170, yymsp[-2].minor.yy170, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy170, TK_LE), TK_AND);} + yymsp[-4].minor.yy170 = yylhsminor.yy170; break; case 238: /* expr ::= expr AND expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_AND);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_AND);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 239: /* expr ::= expr OR expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_OR); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_OR); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 240: /* expr ::= expr PLUS expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_PLUS); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_PLUS); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 241: /* expr ::= expr MINUS expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_MINUS); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_MINUS); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 242: /* expr ::= expr STAR expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_STAR); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_STAR); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 243: /* expr ::= expr SLASH expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_DIVIDE);} - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_DIVIDE);} + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 244: /* expr ::= expr REM expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_REM); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_REM); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 245: /* expr ::= expr LIKE expr */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-2].minor.yy118, yymsp[0].minor.yy118, TK_LIKE); } - yymsp[-2].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-2].minor.yy170, yymsp[0].minor.yy170, TK_LIKE); } + yymsp[-2].minor.yy170 = yylhsminor.yy170; break; case 246: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy118 = tSqlExprCreate(yymsp[-4].minor.yy118, (tSqlExpr*)yymsp[-1].minor.yy159, TK_IN); } - yymsp[-4].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = tSqlExprCreate(yymsp[-4].minor.yy170, (tSqlExpr*)yymsp[-1].minor.yy429, TK_IN); } + yymsp[-4].minor.yy170 = yylhsminor.yy170; break; case 247: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy159 = tSqlExprListAppend(yymsp[-2].minor.yy159,yymsp[0].minor.yy118,0, 0);} - yymsp[-2].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy429 = tSqlExprListAppend(yymsp[-2].minor.yy429,yymsp[0].minor.yy170,0, 0);} + yymsp[-2].minor.yy429 = yylhsminor.yy429; break; case 248: /* exprlist ::= expritem */ -{yylhsminor.yy159 = tSqlExprListAppend(0,yymsp[0].minor.yy118,0, 0);} - yymsp[0].minor.yy159 = yylhsminor.yy159; +{yylhsminor.yy429 = tSqlExprListAppend(0,yymsp[0].minor.yy170,0, 0);} + yymsp[0].minor.yy429 = yylhsminor.yy429; break; case 249: /* expritem ::= expr */ -{yylhsminor.yy118 = yymsp[0].minor.yy118;} - yymsp[0].minor.yy118 = yylhsminor.yy118; +{yylhsminor.yy170 = yymsp[0].minor.yy170;} + yymsp[0].minor.yy170 = yylhsminor.yy170; break; case 251: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} @@ -2978,7 +3272,7 @@ static void yy_reduce( case 253: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy429, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -2996,7 +3290,7 @@ static void yy_reduce( case 255: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy429, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3031,7 +3325,7 @@ static void yy_reduce( toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy488, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy218, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); @@ -3040,7 +3334,7 @@ static void yy_reduce( case 259: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy429, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3058,7 +3352,7 @@ static void yy_reduce( case 261: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy159, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy429, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; @@ -3100,9 +3394,9 @@ static void yy_reduce( break; /********** End reduce actions ************************************************/ }; - assert( yyrulenostateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact, "... then shift"); + return yyact; } /* @@ -3126,7 +3421,8 @@ static void yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); @@ -3137,7 +3433,8 @@ static void yy_parse_failed( ** parser fails */ /************ Begin %parse_failure code ***************************************/ /************ End %parse_failure code *****************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } #endif /* YYNOERRORRECOVERY */ @@ -3149,7 +3446,8 @@ static void yy_syntax_error( int yymajor, /* The major type of the error token */ ParseTOKENTYPE yyminor /* The minor type of the error token */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ @@ -3175,7 +3473,8 @@ static void yy_syntax_error( assert(len <= outputBufLen); /************ End %syntax_error code ******************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* @@ -3184,7 +3483,8 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); @@ -3199,7 +3499,8 @@ static void yy_accept( /*********** Begin %parse_accept code *****************************************/ /*********** End %parse_accept code *******************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* The main parser program. @@ -3228,45 +3529,47 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - unsigned int yyact; /* The parser action. */ + YYACTIONTYPE yyact; /* The parser action. */ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) int yyendofinput; /* True if we are at the end of input */ #endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif - yyParser *yypParser; /* The parser */ + yyParser *yypParser = (yyParser*)yyp; /* The parser */ + ParseCTX_FETCH + ParseARG_STORE - yypParser = (yyParser*)yyp; assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); #endif - ParseARG_STORE; + yyact = yypParser->yytos->stateno; #ifndef NDEBUG if( yyTraceFILE ){ - int stateno = yypParser->yytos->stateno; - if( stateno < YY_MIN_REDUCE ){ + if( yyact < YY_MIN_REDUCE ){ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", - yyTracePrompt,yyTokenName[yymajor],stateno); + yyTracePrompt,yyTokenName[yymajor],yyact); }else{ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", - yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE); + yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); } } #endif do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); + assert( yyact==yypParser->yytos->stateno ); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor); + yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, + yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,yymajor,yyminor); + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; #endif - yymajor = YYNOCODE; + break; }else if( yyact==YY_ACCEPT_ACTION ){ yypParser->yytos--; yy_accept(yypParser); @@ -3317,10 +3620,9 @@ void Parse( yymajor = YYNOCODE; }else{ while( yypParser->yytos >= yypParser->yystack - && yymx != YYERRORSYMBOL && (yyact = yy_find_reduce_action( yypParser->yytos->stateno, - YYERRORSYMBOL)) >= YY_MIN_REDUCE + YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE ){ yy_pop_parser_stack(yypParser); } @@ -3337,6 +3639,8 @@ void Parse( } yypParser->yyerrcnt = 3; yyerrorhit = 1; + if( yymajor==YYNOCODE ) break; + yyact = yypParser->yytos->stateno; #elif defined(YYNOERRORRECOVERY) /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to ** do any kind of error recovery. Instead, simply invoke the syntax @@ -3347,8 +3651,7 @@ void Parse( */ yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - + break; #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -3370,10 +3673,10 @@ void Parse( yypParser->yyerrcnt = -1; #endif } - yymajor = YYNOCODE; + break; #endif } - }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); + }while( yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -3388,3 +3691,17 @@ void Parse( #endif return; } + +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +int ParseFallback(int iToken){ +#ifdef YYFALLBACK + assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); + return yyFallback[iToken]; +#else + (void)iToken; + return 0; +#endif +} diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 133ae6d0ab..db3c72c2fc 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -295,7 +295,7 @@ void *rpcOpen(const SRpcInit *pInit) { return NULL; } } else { - pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, pRpc->idleTime); + pRpc->pCache = rpcOpenConnCache(pRpc->sessions, rpcCloseConn, pRpc->tmrCtrl, pRpc->idleTime * 30); if ( pRpc->pCache == NULL ) { tError("%s failed to init connection cache", pRpc->label); rpcClose(pRpc); @@ -470,7 +470,7 @@ void rpcSendResponse(const SRpcMsg *pRsp) { taosTmrStopA(&pConn->pTimer); // set the idle timer to monitor the activity - taosTmrReset(rpcProcessIdleTimer, pRpc->idleTime, pConn, pRpc->tmrCtrl, &pConn->pIdleTimer); + taosTmrReset(rpcProcessIdleTimer, pRpc->idleTime * 30, pConn, pRpc->tmrCtrl, &pConn->pIdleTimer); rpcSendMsgToPeer(pConn, msg, msgLen); // if not set to secured, set it expcet NOT_READY case, since client wont treat it as secured @@ -997,8 +997,8 @@ static SRpcConn *rpcProcessMsgHead(SRpcInfo *pRpc, SRecvInfo *pRecv, SRpcReqCont } if ( rpcIsReq(pHead->msgType) ) { - terrno = rpcProcessReqHead(pConn, pHead); pConn->connType = pRecv->connType; + terrno = rpcProcessReqHead(pConn, pHead); // stop idle timer taosTmrStopA(&pConn->pIdleTimer); @@ -1367,7 +1367,7 @@ static void rpcProcessConnError(void *param, void *id) { tDebug("%s %p, connection error happens", pRpc->label, pContext->ahandle); - if (pContext->numOfTry >= pContext->epSet.numOfEps) { + if (pContext->numOfTry >= pContext->epSet.numOfEps || pContext->msgType == TSDB_MSG_TYPE_FETCH) { rpcMsg.msgType = pContext->msgType+1; rpcMsg.ahandle = pContext->ahandle; rpcMsg.code = pContext->code; diff --git a/src/sync/inc/syncInt.h b/src/sync/inc/syncInt.h index 2b87938474..ec6dfcbc82 100644 --- a/src/sync/inc/syncInt.h +++ b/src/sync/inc/syncInt.h @@ -35,7 +35,7 @@ extern "C" { #define SYNC_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + sizeof(SSyncHead) + 16) #define SYNC_RECV_BUFFER_SIZE (5*1024*1024) -#define SYNC_MAX_FWDS 512 +#define SYNC_MAX_FWDS 4096 #define SYNC_FWD_TIMER 300 #define SYNC_ROLE_TIMER 15000 // ms #define SYNC_CHECK_INTERVAL 1000 // ms @@ -117,7 +117,6 @@ typedef struct SSyncNode { FStartSyncFile startSyncFileFp; FStopSyncFile stopSyncFileFp; FGetVersion getVersionFp; - FResetVersion resetVersionFp; FSendFile sendFileFp; FRecvFile recvFileFp; pthread_mutex_t mutex; diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c index 76d4379c5f..e5f2d94c4a 100644 --- a/src/sync/src/syncMain.c +++ b/src/sync/src/syncMain.c @@ -182,7 +182,6 @@ int64_t syncStart(const SSyncInfo *pInfo) { pNode->startSyncFileFp = pInfo->startSyncFileFp; pNode->stopSyncFileFp = pInfo->stopSyncFileFp; pNode->getVersionFp = pInfo->getVersionFp; - pNode->resetVersionFp = pInfo->resetVersionFp; pNode->sendFileFp = pInfo->sendFileFp; pNode->recvFileFp = pInfo->recvFileFp; @@ -410,23 +409,22 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code, bool force) syncReleaseNode(pNode); } -#if 1 void syncRecover(int64_t rid) { SSyncPeer *pPeer; SSyncNode *pNode = syncAcquireNode(rid); if (pNode == NULL) return; - // to do: add a few lines to check if recover is OK - // if take this node to unsync state, the whole system may not work - nodeRole = TAOS_SYNC_ROLE_UNSYNCED; (*pNode->notifyRoleFp)(pNode->vgId, nodeRole); - nodeVersion = 0; pthread_mutex_lock(&pNode->mutex); + nodeVersion = 0; + for (int32_t i = 0; i < pNode->replica; ++i) { + if (i == pNode->selfIndex) continue; + pPeer = pNode->peerInfo[i]; if (pPeer->peerFd >= 0) { syncRestartConnection(pPeer); @@ -437,7 +435,6 @@ void syncRecover(int64_t rid) { syncReleaseNode(pNode); } -#endif int32_t syncGetNodesRole(int64_t rid, SNodesRole *pNodesRole) { SSyncNode *pNode = syncAcquireNode(rid); @@ -552,7 +549,10 @@ static void syncClosePeerConn(SSyncPeer *pPeer) { if (pPeer->peerFd >= 0) { pPeer->peerFd = -1; void *pConn = pPeer->pConn; - if (pConn != NULL) syncFreeTcpConn(pPeer->pConn); + if (pConn != NULL) { + syncFreeTcpConn(pPeer->pConn); + pPeer->pConn = NULL; + } } } @@ -998,17 +998,24 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) { sTrace("%s, forward is received, hver:%" PRIu64 ", len:%d", pPeer->id, pHead->version, pHead->len); + int32_t code = 0; if (nodeRole == TAOS_SYNC_ROLE_SLAVE) { // nodeVersion = pHead->version; - (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); + code = (*pNode->writeToCacheFp)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); } else { if (nodeSStatus != TAOS_SYNC_STATUS_INIT) { - syncSaveIntoBuffer(pPeer, pHead); + code = syncSaveIntoBuffer(pPeer, pHead); } else { sError("%s, forward discarded since sstatus:%s, hver:%" PRIu64, pPeer->id, syncStatus[nodeSStatus], pHead->version); + code = -1; } } + + if (code != 0) { + sError("%s, failed to process fwd msg, hver:%" PRIu64 ", len:%d", pPeer->id, pHead->version, pHead->len); + syncRestartConnection(pPeer); + } } static void syncProcessPeersStatusMsg(SPeersStatus *pPeersStatus, SSyncPeer *pPeer) { @@ -1373,7 +1380,7 @@ static void syncMonitorNodeRole(void *param, void *tmrId) { if (/*pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && */ nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue; if (/*pPeer->sstatus > TAOS_SYNC_STATUS_INIT || */ nodeSStatus > TAOS_SYNC_STATUS_INIT) continue; - sDebug("%s, check roles since self:%s sstatus:%s, peer:%s sstatus:%s", pPeer->id, syncRole[pPeer->role], + sDebug("%s, check roles since peer:%s sstatus:%s, self:%s sstatus:%s", pPeer->id, syncRole[pPeer->role], syncStatus[pPeer->sstatus], syncRole[nodeRole], syncStatus[nodeSStatus]); syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_CHECK_ROLE, syncGenTranId()); break; @@ -1460,7 +1467,12 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle if ((pNode->quorum > 1 || force) && code == 0) { code = syncSaveFwdInfo(pNode, pWalHead->version, mhandle); - if (code >= 0) code = 1; + if (code >= 0) { + code = 1; + } else { + pthread_mutex_unlock(&pNode->mutex); + return code; + } } int32_t retLen = taosWriteMsg(pPeer->peerFd, pSyncHead, fwdLen); diff --git a/src/sync/src/syncRestore.c b/src/sync/src/syncRestore.c index 22d0a27581..c0d66316cd 100644 --- a/src/sync/src/syncRestore.c +++ b/src/sync/src/syncRestore.c @@ -238,7 +238,6 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { (*pNode->stopSyncFileFp)(pNode->vgId, fversion); nodeVersion = fversion; - if (pNode->resetVersionFp) (*pNode->resetVersionFp)(pNode->vgId, fversion); sInfo("%s, start to restore wal, fver:%" PRIu64, pPeer->id, nodeVersion); uint64_t wver = 0; diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 8969f61596..99929f3542 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -526,7 +526,7 @@ static void tsdbStartStream(STsdbRepo *pRepo) { STable *pTable = pMeta->tables[i]; if (pTable && pTable->type == TSDB_STREAM_TABLE) { pTable->cqhandle = (*pRepo->appH.cqCreateFunc)(pRepo->appH.cqH, TABLE_UID(pTable), TABLE_TID(pTable), TABLE_NAME(pTable)->data, pTable->sql, - tsdbGetTableSchemaImpl(pTable, false, false, -1)); + tsdbGetTableSchemaImpl(pTable, false, false, -1), 0); } } } @@ -619,4 +619,4 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) { tsdbDestroyReadH(&readh); return 0; -} \ No newline at end of file +} diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 824f69608e..3e6263b9d3 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -840,7 +840,7 @@ static int tsdbAddTableToMeta(STsdbRepo *pRepo, STable *pTable, bool addIdx, boo if (lock && tsdbUnlockRepoMeta(pRepo) < 0) return -1; if (TABLE_TYPE(pTable) == TSDB_STREAM_TABLE && addIdx) { pTable->cqhandle = (*pRepo->appH.cqCreateFunc)(pRepo->appH.cqH, TABLE_UID(pTable), TABLE_TID(pTable), TABLE_NAME(pTable)->data, pTable->sql, - tsdbGetTableSchemaImpl(pTable, false, false, -1)); + tsdbGetTableSchemaImpl(pTable, false, false, -1), 1); } tsdbDebug("vgId:%d table %s tid %d uid %" PRIu64 " is added to meta", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), @@ -1322,4 +1322,4 @@ static int tsdbCheckTableTagVal(SKVRow *pKVRow, STSchema *pSchema) { } return 0; -} \ No newline at end of file +} diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index ea72760568..cd97b2a9d6 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -2861,12 +2861,6 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta if (pHandle->statis[i].numOfNull == -1) { // set the column data are all NULL pHandle->statis[i].numOfNull = pBlockInfo->compBlock->numOfRows; } - - SColumnInfo* pColInfo = taosArrayGet(pHandle->pColumns, i); - if (pColInfo->type == TSDB_DATA_TYPE_TIMESTAMP) { - pHandle->statis[i].min = pBlockInfo->compBlock->keyFirst; - pHandle->statis[i].max = pBlockInfo->compBlock->keyLast; - } } int64_t elapsed = taosGetTimestampUs() - stime; diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 918ccc4935..586a886f47 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -175,6 +175,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TABLE_ID, "Table name too long") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TABLE_NAME, "Table does not exist") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TABLE_TYPE, "Invalid table type in tsdb") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_TAGS, "Too many tags") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_COLUMNS, "Too many columns") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_TIMESERIES, "Too many time series") TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_SUPER_TABLE, "Not super table") // operation only available for super table TAOS_DEFINE_ERROR(TSDB_CODE_MND_COL_NAME_TOO_LONG, "Tag name too long") diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c index b33cdb8b80..77941cba82 100644 --- a/src/util/src/tsocket.c +++ b/src/util/src/tsocket.c @@ -22,6 +22,8 @@ #define SIGPIPE EPIPE #endif +#define TCP_CONN_TIMEOUT 3000 // conn timeout + int32_t taosGetFqdn(char *fqdn) { char hostname[1024]; hostname[1023] = '\0'; @@ -346,10 +348,47 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie serverAddr.sin_addr.s_addr = destIp; serverAddr.sin_port = (uint16_t)htons((uint16_t)destPort); - ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); +#ifdef _TD_LINUX + taosSetNonblocking(sockFd, 1); + ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); + if (ret == -1) { + if (errno == EHOSTUNREACH) { + uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno)); + taosCloseSocket(sockFd); + return -1; + } else if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) { + struct pollfd wfd[1]; + + wfd[0].fd = sockFd; + wfd[0].events = POLLOUT; + + int res = poll(wfd, 1, TCP_CONN_TIMEOUT); + if (res == -1 || res == 0) { + uError("failed to connect socket, ip:0x%x, port:%hu(poll error/conn timeout)", destIp, destPort); + taosCloseSocket(sockFd); // + return -1; + } + int optVal = -1, optLen = sizeof(int); + if ((0 != taosGetSockOpt(sockFd, SOL_SOCKET, SO_ERROR, &optVal, &optLen)) || (optVal != 0)) { + uError("failed to connect socket, ip:0x%x, port:%hu(connect host error)", destIp, destPort); + taosCloseSocket(sockFd); // + return -1; + } + ret = 0; + } else { // Other error + uError("failed to connect socket, ip:0x%x, port:%hu(target host cannot be reached)", destIp, destPort); + taosCloseSocket(sockFd); // + return -1; + } + } + taosSetNonblocking(sockFd, 0); + +#else + ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); +#endif if (ret != 0) { - // uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno)); + uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno)); taosCloseSocket(sockFd); sockFd = -1; } else { diff --git a/src/vnode/inc/vnodeBackup.h b/src/vnode/inc/vnodeBackup.h new file mode 100644 index 0000000000..0a6b26546c --- /dev/null +++ b/src/vnode/inc/vnodeBackup.h @@ -0,0 +1,32 @@ +/* + * 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 . + */ + +#ifndef TDENGINE_VNODE_BACKUP_H +#define TDENGINE_VNODE_BACKUP_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "vnodeInt.h" + +int32_t vnodeInitBackup(); +void vnodeCleanupBackup(); +int32_t vnodeBackup(int32_t vgId); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/vnode/inc/vnodeInt.h b/src/vnode/inc/vnodeInt.h index 4aa07196a7..d770a38e37 100644 --- a/src/vnode/inc/vnodeInt.h +++ b/src/vnode/inc/vnodeInt.h @@ -37,6 +37,7 @@ extern int32_t vDebugFlag; typedef struct { int32_t vgId; // global vnode group ID int32_t refCount; // reference count + int64_t queuedWMsgSize; int32_t queuedWMsg; int32_t queuedRMsg; int32_t flowctrlLevel; diff --git a/src/vnode/inc/vnodeSync.h b/src/vnode/inc/vnodeSync.h index 75d7ffbabd..28fb63dd6a 100644 --- a/src/vnode/inc/vnodeSync.h +++ b/src/vnode/inc/vnodeSync.h @@ -30,7 +30,6 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion); void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code); int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam); int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver); -int32_t vnodeResetVersion(int32_t vgId, uint64_t fver); void vnodeConfirmForward(void *pVnode, uint64_t version, int32_t code, bool force); diff --git a/src/vnode/src/vnodeBackup.c b/src/vnode/src/vnodeBackup.c new file mode 100644 index 0000000000..a0a975be2b --- /dev/null +++ b/src/vnode/src/vnodeBackup.c @@ -0,0 +1,172 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "os.h" +#include "taoserror.h" +#include "taosmsg.h" +#include "tutil.h" +#include "tqueue.h" +#include "tglobal.h" +#include "tfs.h" +#include "vnodeBackup.h" +#include "vnodeMain.h" + +typedef struct { + int32_t vgId; +} SVBackupMsg; + +typedef struct { + pthread_t thread; + int32_t workerId; +} SVBackupWorker; + +typedef struct { + int32_t num; + SVBackupWorker *worker; +} SVBackupWorkerPool; + +static SVBackupWorkerPool tsVBackupPool; +static taos_qset tsVBackupQset; +static taos_queue tsVBackupQueue; + +static void vnodeProcessBackupMsg(SVBackupMsg *pMsg) { + int32_t vgId = pMsg->vgId; + char newDir[TSDB_FILENAME_LEN] = {0}; + char stagingDir[TSDB_FILENAME_LEN] = {0}; + + sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId); + sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId); + + if (tsEnableVnodeBak) { + tfsRmdir(newDir); + tfsRename(stagingDir, newDir); + } else { + vInfo("vgId:%d, vnode backup not enabled", vgId); + + tfsRmdir(stagingDir); + } +} + +static void *vnodeBackupFunc(void *param) { + while (1) { + SVBackupMsg *pMsg = NULL; + if (taosReadQitemFromQset(tsVBackupQset, NULL, (void **)&pMsg, NULL) == 0) { + vDebug("qset:%p, vbackup got no message from qset, exiting", tsVBackupQset); + break; + } + + vTrace("vgId:%d, will be processed in vbackup queue", pMsg->vgId); + vnodeProcessBackupMsg(pMsg); + + vTrace("vgId:%d, disposed in vbackup worker", pMsg->vgId); + taosFreeQitem(pMsg); + } + + return NULL; +} + +static int32_t vnodeStartBackup() { + tsVBackupQueue = taosOpenQueue(); + if (tsVBackupQueue == NULL) return TSDB_CODE_DND_OUT_OF_MEMORY; + + taosAddIntoQset(tsVBackupQset, tsVBackupQueue, NULL); + + for (int32_t i = 0; i < tsVBackupPool.num; ++i) { + SVBackupWorker *pWorker = tsVBackupPool.worker + i; + pWorker->workerId = i; + + pthread_attr_t thAttr; + pthread_attr_init(&thAttr); + pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE); + + if (pthread_create(&pWorker->thread, &thAttr, vnodeBackupFunc, pWorker) != 0) { + vError("failed to create thread to process vbackup queue, reason:%s", strerror(errno)); + } + + pthread_attr_destroy(&thAttr); + + vDebug("vbackup:%d is launched, total:%d", pWorker->workerId, tsVBackupPool.num); + } + + vDebug("vbackup queue:%p is allocated", tsVBackupQueue); + + return TSDB_CODE_SUCCESS; +} + +static int32_t vnodeWriteIntoBackupWorker(int32_t vgId) { + SVBackupMsg *pMsg = taosAllocateQitem(sizeof(SVBackupMsg)); + if (pMsg == NULL) return TSDB_CODE_VND_OUT_OF_MEMORY; + + pMsg->vgId = vgId; + + int32_t code = taosWriteQitem(tsVBackupQueue, TAOS_QTYPE_RPC, pMsg); + if (code == 0) code = TSDB_CODE_DND_ACTION_IN_PROGRESS; + + return code; +} + +int32_t vnodeBackup(int32_t vgId) { + vTrace("vgId:%d, will backup", vgId); + return vnodeWriteIntoBackupWorker(vgId); +} + +int32_t vnodeInitBackup() { + tsVBackupQset = taosOpenQset(); + + tsVBackupPool.num = 1; + tsVBackupPool.worker = calloc(sizeof(SVBackupWorker), tsVBackupPool.num); + + if (tsVBackupPool.worker == NULL) return -1; + for (int32_t i = 0; i < tsVBackupPool.num; ++i) { + SVBackupWorker *pWorker = tsVBackupPool.worker + i; + pWorker->workerId = i; + vDebug("vbackup:%d is created", i); + } + + vDebug("vbackup is initialized, num:%d qset:%p", tsVBackupPool.num, tsVBackupQset); + + return vnodeStartBackup(); +} + +void vnodeCleanupBackup() { + for (int32_t i = 0; i < tsVBackupPool.num; ++i) { + SVBackupWorker *pWorker = tsVBackupPool.worker + i; + if (taosCheckPthreadValid(pWorker->thread)) { + taosQsetThreadResume(tsVBackupQset); + } + vDebug("vbackup:%d is closed", i); + } + + for (int32_t i = 0; i < tsVBackupPool.num; ++i) { + SVBackupWorker *pWorker = tsVBackupPool.worker + i; + vDebug("vbackup:%d start to join", i); + if (taosCheckPthreadValid(pWorker->thread)) { + pthread_join(pWorker->thread, NULL); + } + vDebug("vbackup:%d join success", i); + } + + vDebug("vbackup is closed, qset:%p", tsVBackupQset); + + taosCloseQset(tsVBackupQset); + tsVBackupQset = NULL; + + tfree(tsVBackupPool.worker); + + vDebug("vbackup queue:%p is freed", tsVBackupQueue); + taosCloseQueue(tsVBackupQueue); + tsVBackupQueue = NULL; +} diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 441e951250..ee8ed9e0fa 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -27,6 +27,7 @@ #include "vnodeVersion.h" #include "vnodeMgmt.h" #include "vnodeWorker.h" +#include "vnodeBackup.h" #include "vnodeMain.h" static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno); @@ -98,8 +99,13 @@ int32_t vnodeSync(int32_t vgId) { return TSDB_CODE_VND_INVALID_VGROUP_ID; } - if (pVnode->role != TAOS_SYNC_ROLE_MASTER) { + if (pVnode->role == TAOS_SYNC_ROLE_SLAVE) { vInfo("vgId:%d, vnode will sync, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode); + + pVnode->version = 0; + pVnode->fversion = 0; + walResetVersion(pVnode->wal, pVnode->fversion); + syncRecover(pVnode->sync); } @@ -364,7 +370,6 @@ int32_t vnodeOpen(int32_t vgId) { syncInfo.startSyncFileFp = vnodeStartSyncFile; syncInfo.stopSyncFileFp = vnodeStopSyncFile; syncInfo.getVersionFp = vnodeGetVersion; - syncInfo.resetVersionFp = vnodeResetVersion; syncInfo.sendFileFp = tsdbSyncSend; syncInfo.recvFileFp = tsdbSyncRecv; syncInfo.pTsdb = pVnode->tsdb; @@ -448,18 +453,14 @@ void vnodeDestroy(SVnodeObj *pVnode) { if (pVnode->dropped) { char rootDir[TSDB_FILENAME_LEN] = {0}; - char newDir[TSDB_FILENAME_LEN] = {0}; + char stagingDir[TSDB_FILENAME_LEN] = {0}; sprintf(rootDir, "%s/vnode%d", "vnode", vgId); - sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId); + sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId); - if (0 == tsEnableVnodeBak) { - vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId); - } else { - tfsRmdir(newDir); - tfsRename(rootDir, newDir); - } + tfsRename(rootDir, stagingDir); + + vnodeBackup(vgId); - tfsRmdir(rootDir); dnodeSendStatusMsgToMnode(); } diff --git a/src/vnode/src/vnodeMgmt.c b/src/vnode/src/vnodeMgmt.c index 71d9bc07f5..32f9532138 100644 --- a/src/vnode/src/vnodeMgmt.c +++ b/src/vnode/src/vnodeMgmt.c @@ -17,6 +17,7 @@ #include "os.h" #include "dnode.h" #include "vnodeStatus.h" +#include "vnodeBackup.h" #include "vnodeWorker.h" #include "vnodeRead.h" #include "vnodeWrite.h" @@ -29,6 +30,7 @@ static void vnodeCleanupHash(void); static void vnodeIncRef(void *ptNode); static SStep tsVnodeSteps[] = { + {"vnode-backup", vnodeInitBackup, vnodeCleanupBackup}, {"vnode-worker", vnodeInitMWorker, vnodeCleanupMWorker}, {"vnode-write", vnodeInitWrite, vnodeCleanupWrite}, {"vnode-read", vnodeInitRead, vnodeCleanupRead}, diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 0836ade77f..2448fada50 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -208,6 +208,7 @@ static void vnodeBuildNoResultQueryRsp(SRspRet *pRet) { pRsp->completed = true; } + static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { void * pCont = pRead->pCont; int32_t contLen = pRead->contLen; @@ -226,7 +227,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { if (contLen != 0) { qinfo_t pQInfo = NULL; - uint64_t qId = 0; + uint64_t qId = genQueryId(); code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo, &qId); SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp)); @@ -239,7 +240,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { // current connect is broken if (code == TSDB_CODE_SUCCESS) { - handle = qRegisterQInfo(pVnode->qMgmt, qId, (uint64_t)pQInfo); + handle = qRegisterQInfo(pVnode->qMgmt, qId, pQInfo); if (handle == NULL) { // failed to register qhandle pRsp->code = terrno; terrno = 0; diff --git a/src/vnode/src/vnodeSync.c b/src/vnode/src/vnodeSync.c index 929dd15926..aa4cf0fc15 100644 --- a/src/vnode/src/vnodeSync.c +++ b/src/vnode/src/vnodeSync.c @@ -107,8 +107,9 @@ void vnodeStopSyncFile(int32_t vgId, uint64_t fversion) { pVnode->fversion = fversion; pVnode->version = fversion; vnodeSaveVersion(pVnode); + walResetVersion(pVnode->wal, fversion); - vDebug("vgId:%d, datafile is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion); + vInfo("vgId:%d, datafile is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion); vnodeSetReadyStatus(pVnode); vnodeRelease(pVnode); @@ -158,22 +159,6 @@ int32_t vnodeGetVersion(int32_t vgId, uint64_t *fver, uint64_t *wver) { return code; } -int32_t vnodeResetVersion(int32_t vgId, uint64_t fver) { - SVnodeObj *pVnode = vnodeAcquire(vgId); - if (pVnode == NULL) { - vError("vgId:%d, vnode not found while reset version", vgId); - return -1; - } - - pVnode->fversion = fver; - pVnode->version = fver; - walResetVersion(pVnode->wal, fver); - vInfo("vgId:%d, version reset to %" PRIu64, vgId, fver); - - vnodeRelease(pVnode); - return 0; -} - void vnodeConfirmForward(void *vparam, uint64_t version, int32_t code, bool force) { SVnodeObj *pVnode = vparam; syncConfirmForward(pVnode->sync, version, code, force); diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index e318978a11..aab685e678 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -25,6 +25,7 @@ #include "vnodeStatus.h" #define MAX_QUEUED_MSG_NUM 100000 +#define MAX_QUEUED_MSG_SIZE 1024*1024*1024 //1GB extern void * tsDnodeTmr; static int32_t (*vnodeProcessWriteMsgFp[TSDB_MSG_TYPE_MAX])(SVnodeObj *, void *pCont, SRspRet *); @@ -91,12 +92,17 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara int32_t syncCode = 0; bool force = (pWrite == NULL ? false : pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT); syncCode = syncForwardToPeer(pVnode->sync, pHead, pWrite, qtype, force); - if (syncCode < 0) return syncCode; + if (syncCode < 0) { + pHead->version = 0; + return syncCode; + } // write into WAL code = walWrite(pVnode->wal, pHead); if (code < 0) { + if (syncCode > 0) atomic_sub_fetch_32(&pWrite->processedCount, 1); vError("vgId:%d, hver:%" PRIu64 " vver:%" PRIu64 " code:0x%x", pVnode->vgId, pHead->version, pVnode->version, code); + pHead->version = 0; return code; } @@ -104,7 +110,10 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara // write data locally code = (*vnodeProcessWriteMsgFp[pHead->msgType])(pVnode, pHead->cont, pRspRet); - if (code < 0) return code; + if (code < 0) { + if (syncCode > 0) atomic_sub_fetch_32(&pWrite->processedCount, 1); + return code; + } return syncCode; } @@ -261,6 +270,13 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) { } } + if (tsAvailDataDirGB <= tsMinimalDataDirGB) { + vError("vgId:%d, failed to write into vwqueue since no diskspace, avail:%fGB", pVnode->vgId, tsAvailDataDirGB); + taosFreeQitem(pWrite); + vnodeRelease(pVnode); + return TSDB_CODE_VND_NO_DISKSPACE; + } + if (!vnodeInReadyOrUpdatingStatus(pVnode)) { vError("vgId:%d, failed to write into vwqueue, vstatus is %s, refCount:%d pVnode:%p", pVnode->vgId, vnodeStatus[pVnode->status], pVnode->refCount, pVnode); @@ -270,14 +286,17 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) { } int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1); - if (queued > MAX_QUEUED_MSG_NUM) { + int64_t queuedSize = atomic_add_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len); + + if (queued > MAX_QUEUED_MSG_NUM || queuedSize > MAX_QUEUED_MSG_SIZE) { int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3; if (ms > 100) ms = 100; vDebug("vgId:%d, too many msg:%d in vwqueue, flow control %dms", pVnode->vgId, queued, ms); taosMsleep(ms); } - vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedWMsg); + vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d size:%" PRId64, pVnode->vgId, pVnode->refCount, + pVnode->queuedWMsg, pVnode->queuedWMsgSize); taosWriteQitem(pVnode->wqueue, pWrite->qtype, pWrite); return TSDB_CODE_SUCCESS; @@ -300,7 +319,10 @@ void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) { SVnodeObj *pVnode = vparam; int32_t queued = atomic_sub_fetch_32(&pVnode->queuedWMsg, 1); - vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d", pVnode->vgId, pWrite, pWrite->rpcMsg.ahandle, queued); + int64_t queuedSize = atomic_sub_fetch_64(&pVnode->queuedWMsgSize, pWrite->pHead.len); + + vTrace("vgId:%d, msg:%p, app:%p, free from vwqueue, queued:%d size:%" PRId64, pVnode->vgId, pWrite, + pWrite->rpcMsg.ahandle, queued, queuedSize); taosFreeQitem(pWrite); vnodeRelease(pVnode); @@ -336,7 +358,9 @@ static void vnodeFlowCtrlMsgToWQueue(void *param, void *tmrId) { static int32_t vnodePerformFlowCtrl(SVWriteMsg *pWrite) { SVnodeObj *pVnode = pWrite->pVnode; if (pWrite->qtype != TAOS_QTYPE_RPC) return 0; - if (pVnode->queuedWMsg < MAX_QUEUED_MSG_NUM && pVnode->flowctrlLevel <= 0) return 0; + if (pVnode->queuedWMsg < MAX_QUEUED_MSG_NUM && pVnode->queuedWMsgSize < MAX_QUEUED_MSG_SIZE && + pVnode->flowctrlLevel <= 0) + return 0; if (tsEnableFlowCtrl == 0) { int32_t ms = (int32_t)pow(2, pVnode->flowctrlLevel + 2); diff --git a/src/wal/src/walMgmt.c b/src/wal/src/walMgmt.c index 39ce2657aa..55ab9b031b 100644 --- a/src/wal/src/walMgmt.c +++ b/src/wal/src/walMgmt.c @@ -104,7 +104,7 @@ int32_t walAlter(void *handle, SWalCfg *pCfg) { pWal->level = pCfg->walLevel; pWal->fsyncPeriod = pCfg->fsyncPeriod; - pWal->fsyncSeq = pCfg->fsyncPeriod % 1000; + pWal->fsyncSeq = pCfg->fsyncPeriod / 1000; if (pWal->fsyncSeq <= 0) pWal->fsyncSeq = 1; return TSDB_CODE_SUCCESS; diff --git a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java index 07a21e79d1..da865b3ffd 100644 --- a/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java +++ b/tests/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JDBCDemo.java @@ -68,12 +68,12 @@ public class JDBCDemo { } private void insert() { - final String sql = "insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)"; + final String sql = "insert into " + dbName + "." + tbName + " (ts, temperature, humidity) values(now, 20.5, 34)"; exuete(sql); } private void select() { - final String sql = "select * from test.weather"; + final String sql = "select * from "+ dbName + "." + tbName; executeQuery(sql); } diff --git a/tests/examples/JDBC/taosdemo/src/main/resources/insert.json b/tests/examples/JDBC/taosdemo/src/main/resources/insert.json index 35c7773175..7578083d33 100644 --- a/tests/examples/JDBC/taosdemo/src/main/resources/insert.json +++ b/tests/examples/JDBC/taosdemo/src/main/resources/insert.json @@ -36,8 +36,6 @@ "insert_mode": "taosc", "insert_rate": 0, "insert_rows": 100, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "interlace_rows": 3, "max_sql_len": 1024, "disorder_ratio": 0, diff --git a/tests/examples/c/asyncdemo.c b/tests/examples/c/asyncdemo.c index d711ce22c1..f2a96dd825 100644 --- a/tests/examples/c/asyncdemo.c +++ b/tests/examples/c/asyncdemo.c @@ -28,7 +28,8 @@ int points = 5; int numOfTables = 3; -int tablesProcessed = 0; +int tablesInsertProcessed = 0; +int tablesSelectProcessed = 0; int64_t st, et; typedef struct { @@ -134,6 +135,9 @@ int main(int argc, char *argv[]) gettimeofday(&systemTime, NULL); st = systemTime.tv_sec * 1000000 + systemTime.tv_usec; + tablesInsertProcessed = 0; + tablesSelectProcessed = 0; + for (i = 0; iname); - tablesProcessed++; - if (tablesProcessed >= numOfTables) { + tablesInsertProcessed++; + if (tablesInsertProcessed >= numOfTables) { gettimeofday(&systemTime, NULL); et = systemTime.tv_sec * 1000000 + systemTime.tv_usec; printf("%lld mseconds to insert %d data points\n", (et - st) / 1000, points*numOfTables); @@ -251,15 +263,17 @@ void taos_retrieve_call_back(void *param, TAOS_RES *tres, int numOfRows) //taos_free_result(tres); printf("%d rows data retrieved from %s\n", pTable->rowsRetrieved, pTable->name); - tablesProcessed++; - if (tablesProcessed >= numOfTables) { + tablesSelectProcessed++; + if (tablesSelectProcessed >= numOfTables) { gettimeofday(&systemTime, NULL); et = systemTime.tv_sec * 1000000 + systemTime.tv_usec; printf("%lld mseconds to query %d data rows\n", (et - st) / 1000, points * numOfTables); } + + taos_free_result(tres); } - taos_free_result(tres); + } void taos_select_call_back(void *param, TAOS_RES *tres, int code) @@ -276,6 +290,4 @@ void taos_select_call_back(void *param, TAOS_RES *tres, int code) taos_cleanup(); exit(1); } - - taos_free_result(tres); } diff --git a/tests/examples/c/demo.c b/tests/examples/c/demo.c index e074e64966..0b1cd7b5d2 100644 --- a/tests/examples/c/demo.c +++ b/tests/examples/c/demo.c @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) { printf("failed to connect to server, reason:%s\n", "null taos"/*taos_errstr(taos)*/); exit(1); } - for (int i = 0; i < 4000000; i++) { + for (int i = 0; i < 100; i++) { Test(taos, qstr, i); } taos_close(taos); diff --git a/tests/examples/go/taosdemo.go b/tests/examples/go/taosdemo.go index 2c3a7d09b6..003f5aeddc 100644 --- a/tests/examples/go/taosdemo.go +++ b/tests/examples/go/taosdemo.go @@ -16,45 +16,47 @@ package main import ( "database/sql" + "flag" "fmt" - _ "github.com/taosdata/driver-go/taosSql" + "math/rand" "os" - "sync" "runtime" "strconv" + "sync" "time" - "flag" - "math/rand" + + _ "github.com/taosdata/driver-go/taosSql" + //"golang.org/x/sys/unix" ) const ( - maxLocationSize = 32 - maxSqlBufSize = 65480 + maxLocationSize = 32 + //maxSqlBufSize = 65480 ) -var locations = [maxLocationSize]string { - "Beijing", "Shanghai", "Guangzhou", "Shenzhen", - "HangZhou", "Tianjin", "Wuhan", "Changsha", - "Nanjing", "Xian"} +var locations = [maxLocationSize]string{ + "Beijing", "Shanghai", "Guangzhou", "Shenzhen", + "HangZhou", "Tianjin", "Wuhan", "Changsha", + "Nanjing", "Xian"} type config struct { - hostName string - serverPort int - user string - password string - dbName string - supTblName string - tablePrefix string - numOftables int - numOfRecordsPerTable int - numOfRecordsPerReq int - numOfThreads int - startTimestamp string - startTs int64 + hostName string + serverPort int + user string + password string + dbName string + supTblName string + tablePrefix string + numOftables int + numOfRecordsPerTable int + numOfRecordsPerReq int + numOfThreads int + startTimestamp string + startTs int64 - keep int - days int + keep int + days int } var configPara config @@ -62,7 +64,7 @@ var taosDriverName = "taosSql" var url string func init() { - flag.StringVar(&configPara.hostName, "h", "127.0.0.1","The host to connect to TDengine server.") + flag.StringVar(&configPara.hostName, "h", "127.0.0.1", "The host to connect to TDengine server.") flag.IntVar(&configPara.serverPort, "p", 6030, "The TCP/IP port number to use for the connection to TDengine server.") flag.StringVar(&configPara.user, "u", "root", "The TDengine user name to use when connecting to the server.") flag.StringVar(&configPara.password, "P", "taosdata", "The password to use when connecting to the server.") @@ -80,14 +82,14 @@ func init() { configPara.supTblName = "meters" startTs, err := time.ParseInLocation("2006-01-02 15:04:05", configPara.startTimestamp, time.Local) - if err==nil { - configPara.startTs = startTs.UnixNano() / 1e6 + if err == nil { + configPara.startTs = startTs.UnixNano() / 1e6 } } func printAllArgs() { fmt.Printf("\n============= args parse result: =============\n") - fmt.Printf("hostName: %v\n", configPara.hostName) + fmt.Printf("hostName: %v\n", configPara.hostName) fmt.Printf("serverPort: %v\n", configPara.serverPort) fmt.Printf("usr: %v\n", configPara.user) fmt.Printf("password: %v\n", configPara.password) @@ -104,10 +106,10 @@ func printAllArgs() { func main() { printAllArgs() fmt.Printf("Please press enter key to continue....\n") - fmt.Scanln() + _, _ = fmt.Scanln() url = "root:taosdata@/tcp(" + configPara.hostName + ":" + strconv.Itoa(configPara.serverPort) + ")/" - //url = fmt.Sprintf("%s:%s@/tcp(%s:%d)/%s?interpolateParams=true", configPara.user, configPara.password, configPara.hostName, configPara.serverPort, configPara.dbName) + //url = fmt.Sprintf("%s:%s@/tcp(%s:%d)/%s?interpolateParams=true", configPara.user, configPara.password, configPara.hostName, configPara.serverPort, configPara.dbName) // open connect to taos server //db, err := sql.Open(taosDriverName, url) //if err != nil { @@ -115,7 +117,7 @@ func main() { // os.Exit(1) //} //defer db.Close() - rand.Seed(time.Now().Unix()) + rand.Seed(time.Now().Unix()) createDatabase(configPara.dbName, configPara.supTblName) fmt.Printf("======== create database success! ========\n\n") @@ -138,7 +140,7 @@ func main() { func createDatabase(dbName string, supTblName string) { db, err := sql.Open(taosDriverName, url) if err != nil { - fmt.Println("Open database error: %s\n", err) + fmt.Printf("Open database error: %s\n", err) os.Exit(1) } defer db.Close() @@ -165,27 +167,27 @@ func createDatabase(dbName string, supTblName string) { checkErr(err, sqlStr) } -func multiThreadCreateTable(threads int, ntables int, dbName string, tablePrefix string) { +func multiThreadCreateTable(threads int, nTables int, dbName string, tablePrefix string) { st := time.Now().UnixNano() - if (threads < 1) { - threads = 1; + if threads < 1 { + threads = 1 } - a := ntables / threads; - if (a < 1) { - threads = ntables; - a = 1; + a := nTables / threads + if a < 1 { + threads = nTables + a = 1 } - b := ntables % threads; + b := nTables % threads - last := 0; + last := 0 endTblId := 0 wg := sync.WaitGroup{} for i := 0; i < threads; i++ { startTblId := last - if (i < b ) { + if i < b { endTblId = last + a } else { endTblId = last + a - 1 @@ -206,42 +208,43 @@ func createTable(dbName string, childTblPrefix string, startTblId int, endTblId db, err := sql.Open(taosDriverName, url) if err != nil { - fmt.Println("Open database error: %s\n", err) + fmt.Printf("Open database error: %s\n", err) os.Exit(1) } defer db.Close() - for i := startTblId; i <= endTblId; i++ { - sqlStr := "create table if not exists " + dbName + "." + childTblPrefix + strconv.Itoa(i) + " using " + dbName + ".meters tags('" + locations[i%maxLocationSize] + "', " + strconv.Itoa(i) + ");" - //fmt.Printf("sqlStr: %v\n", sqlStr) - _, err = db.Exec(sqlStr) - checkErr(err, sqlStr) - } - wg.Done() - runtime.Goexit() + for i := startTblId; i <= endTblId; i++ { + sqlStr := "create table if not exists " + dbName + "." + childTblPrefix + strconv.Itoa(i) + " using " + dbName + ".meters tags('" + locations[i%maxLocationSize] + "', " + strconv.Itoa(i) + ");" + //fmt.Printf("sqlStr: %v\n", sqlStr) + _, err = db.Exec(sqlStr) + checkErr(err, sqlStr) + } + wg.Done() + runtime.Goexit() } func generateRowData(ts int64) string { - voltage := rand.Int() % 1000 - current := 200 + rand.Float32() - phase := rand.Float32() - values := "( " + strconv.FormatInt(ts, 10) + ", " + strconv.FormatFloat(float64(current), 'f', 6, 64) + ", " + strconv.Itoa(voltage) + ", " + strconv.FormatFloat(float64(phase), 'f', 6, 64) + " ) " - return values + voltage := rand.Int() % 1000 + current := 200 + rand.Float32() + phase := rand.Float32() + values := "( " + strconv.FormatInt(ts, 10) + ", " + strconv.FormatFloat(float64(current), 'f', 6, 64) + ", " + strconv.Itoa(voltage) + ", " + strconv.FormatFloat(float64(phase), 'f', 6, 64) + " ) " + return values } + func insertData(dbName string, childTblPrefix string, startTblId int, endTblId int, wg *sync.WaitGroup) { //fmt.Printf("subThread[%d]: insert data to table from %d to %d \n", unix.Gettid(), startTblId, endTblId) // windows.GetCurrentThreadId() db, err := sql.Open(taosDriverName, url) if err != nil { - fmt.Println("Open database error: %s\n", err) + fmt.Printf("Open database error: %s\n", err) os.Exit(1) } defer db.Close() - tmpTs := configPara.startTs; + tmpTs := configPara.startTs //rand.New(rand.NewSource(time.Now().UnixNano())) - for tID := startTblId; tID <= endTblId; tID++{ + for tID := startTblId; tID <= endTblId; tID++ { totalNum := 0 for { sqlStr := "insert into " + dbName + "." + childTblPrefix + strconv.Itoa(tID) + " values " @@ -249,13 +252,13 @@ func insertData(dbName string, childTblPrefix string, startTblId int, endTblId i for { tmpTs += 1000 valuesOfRow := generateRowData(tmpTs) - currRowNum += 1 - totalNum += 1 + currRowNum += 1 + totalNum += 1 sqlStr = fmt.Sprintf("%s %s", sqlStr, valuesOfRow) - if (currRowNum >= configPara.numOfRecordsPerReq || totalNum >= configPara.numOfRecordsPerTable) { - break + if currRowNum >= configPara.numOfRecordsPerReq || totalNum >= configPara.numOfRecordsPerTable { + break } } @@ -265,12 +268,12 @@ func insertData(dbName string, childTblPrefix string, startTblId int, endTblId i count, err := res.RowsAffected() checkErr(err, "rows affected") - if (count != int64(currRowNum)) { - fmt.Printf("insert data, expect affected:%d, actual:%d\n", currRowNum, count) + if count != int64(currRowNum) { + fmt.Printf("insert data, expect affected:%d, actual:%d\n", currRowNum, count) os.Exit(1) } - if (totalNum >= configPara.numOfRecordsPerTable) { + if totalNum >= configPara.numOfRecordsPerTable { break } } @@ -279,44 +282,46 @@ func insertData(dbName string, childTblPrefix string, startTblId int, endTblId i wg.Done() runtime.Goexit() } -func multiThreadInsertData(threads int, ntables int, dbName string, tablePrefix string) { + +func multiThreadInsertData(threads int, nTables int, dbName string, tablePrefix string) { st := time.Now().UnixNano() - if (threads < 1) { - threads = 1; + if threads < 1 { + threads = 1 } - a := ntables / threads; - if (a < 1) { - threads = ntables; - a = 1; + a := nTables / threads + if a < 1 { + threads = nTables + a = 1 } - b := ntables % threads; + b := nTables % threads - last := 0; + last := 0 endTblId := 0 wg := sync.WaitGroup{} for i := 0; i < threads; i++ { startTblId := last - if (i < b ) { + if i < b { endTblId = last + a } else { endTblId = last + a - 1 } last = endTblId + 1 wg.Add(1) - go insertData(dbName, tablePrefix, startTblId , endTblId, &wg) + go insertData(dbName, tablePrefix, startTblId, endTblId, &wg) } wg.Wait() et := time.Now().UnixNano() fmt.Printf("insert data spent duration: %6.6fs\n", (float32(et-st))/1e9) } -func selectTest(dbName string, tbPrefix string, supTblName string){ + +func selectTest(dbName string, tbPrefix string, supTblName string) { db, err := sql.Open(taosDriverName, url) if err != nil { - fmt.Println("Open database error: %s\n", err) + fmt.Printf("Open database error: %s\n", err) os.Exit(1) } defer db.Close() @@ -332,12 +337,12 @@ func selectTest(dbName string, tbPrefix string, supTblName string){ fmt.Printf("query sql: %s\n", sqlStr) for rows.Next() { var ( - ts string - current float32 - voltage int - phase float32 - location string - groupid int + ts string + current float32 + voltage int + phase float32 + location string + groupid int ) err := rows.Scan(&ts, ¤t, &voltage, &phase, &location, &groupid) if err != nil { @@ -352,7 +357,7 @@ func selectTest(dbName string, tbPrefix string, supTblName string){ } // select sql 2 - sqlStr = "select avg(voltage), min(voltage), max(voltage) from " + dbName + "." + tbPrefix + strconv.Itoa( rand.Int() % configPara.numOftables) + sqlStr = "select avg(voltage), min(voltage), max(voltage) from " + dbName + "." + tbPrefix + strconv.Itoa(rand.Int()%configPara.numOftables) rows, err = db.Query(sqlStr) checkErr(err, sqlStr) @@ -360,9 +365,9 @@ func selectTest(dbName string, tbPrefix string, supTblName string){ fmt.Printf("\nquery sql: %s\n", sqlStr) for rows.Next() { var ( - voltageAvg float32 - voltageMin int - voltageMax int + voltageAvg float32 + voltageMin int + voltageMax int ) err := rows.Scan(&voltageAvg, &voltageMin, &voltageMax) if err != nil { @@ -385,10 +390,10 @@ func selectTest(dbName string, tbPrefix string, supTblName string){ fmt.Printf("\nquery sql: %s\n", sqlStr) for rows.Next() { var ( - lastTs string - lastCurrent float32 - lastVoltage int - lastPhase float32 + lastTs string + lastCurrent float32 + lastVoltage int + lastPhase float32 ) err := rows.Scan(&lastTs, &lastCurrent, &lastVoltage, &lastPhase) if err != nil { diff --git a/tests/examples/lua/README.md b/tests/examples/lua/README.md index dd9c9d0787..32d6a4cace 100644 --- a/tests/examples/lua/README.md +++ b/tests/examples/lua/README.md @@ -19,6 +19,10 @@ Run lua sample: lua test.lua ``` +## Run performance test: +``` +time lua benchmark.lua +``` ## OpenResty Dependencies - OpenResty: ``` diff --git a/tests/examples/lua/benchmark.lua b/tests/examples/lua/benchmark.lua new file mode 100644 index 0000000000..900e7891d8 --- /dev/null +++ b/tests/examples/lua/benchmark.lua @@ -0,0 +1,67 @@ +local driver = require "luaconnector" + +local config = { + password = "taosdata", + host = "127.0.0.1", + port = 6030, + database = "", + user = "root", + + max_packet_size = 1024 * 1024 +} + +local conn +local res = driver.connect(config) +if res.code ~=0 then + print("connect--- failed: "..res.error) + return +else + conn = res.conn + print("connect--- pass.") +end + +local res = driver.query(conn,"drop database if exists demo") + +res = driver.query(conn,"create database demo") +if res.code ~=0 then + print("create db--- failed: "..res.error) + return +else + print("create db--- pass.") +end + +res = driver.query(conn,"use demo") +if res.code ~=0 then + print("select db--- failed: "..res.error) + return +else + print("select db--- pass.") +end + +res = driver.query(conn,"create table m1 (ts timestamp, speed int,owner binary(20))") +if res.code ~=0 then + print("create table---failed: "..res.error) + return +else + print("create table--- pass.") +end + +local base = 1617330000000 +local index =0 +local count = 100000 +local t +while( index < count ) +do + t = base + index + local q=string.format([[insert into m1 values (%d,0,'robotspace')]],t) +res = driver.query(conn,q) +if res.code ~=0 then + print("insert records failed: "..res.error) + return +else + +end + index = index+1 +end +print(string.format([["Done. %d records has been stored."]],count)) +driver.close(conn) diff --git a/tests/examples/lua/build.sh b/tests/examples/lua/build.sh index 8018a3b0d8..cbd47bdfd2 100755 --- a/tests/examples/lua/build.sh +++ b/tests/examples/lua/build.sh @@ -1,2 +1,2 @@ -gcc lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos +gcc -std=c99 lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos diff --git a/tests/examples/lua/lua51/build.sh b/tests/examples/lua/lua51/build.sh index da2981bf7d..3b52ed1448 100755 --- a/tests/examples/lua/lua51/build.sh +++ b/tests/examples/lua/lua51/build.sh @@ -1,2 +1,2 @@ -gcc lua_connector51.c -fPIC -shared -o luaconnector51.so -Wall -ltaos +gcc -std=c99 lua_connector51.c -fPIC -shared -o luaconnector51.so -Wall -ltaos diff --git a/tests/examples/lua/lua_connector.c b/tests/examples/lua/lua_connector.c index 920d2cdc35..8078ed2665 100644 --- a/tests/examples/lua/lua_connector.c +++ b/tests/examples/lua/lua_connector.c @@ -23,7 +23,7 @@ static int l_connect(lua_State *L){ luaL_checktype(L, 1, LUA_TTABLE); - lua_getfield(L,-1,"host"); + lua_getfield(L,1,"host"); if (lua_isstring(L,-1)){ host = lua_tostring(L, -1); // printf("host = %s\n", host); diff --git a/tests/perftest-scripts/perftest-query.sh b/tests/perftest-scripts/perftest-query.sh index 8b9fa1a546..0325f552b1 100755 --- a/tests/perftest-scripts/perftest-query.sh +++ b/tests/perftest-scripts/perftest-query.sh @@ -40,8 +40,8 @@ function buildTDengine { git remote update > /dev/null git reset --hard HEAD - git checkout develop - REMOTE_COMMIT=`git rev-parse --short remotes/origin/develop` + git checkout master + REMOTE_COMMIT=`git rev-parse --short remotes/origin/master` LOCAL_COMMIT=`git rev-parse --short @` echo " LOCAL: $LOCAL_COMMIT" @@ -73,6 +73,9 @@ function runQueryPerfTest { python3 insert/insertFromCSVPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT python3 tools/taosdemoPerformance.py -c $LOCAL_COMMIT | tee -a $PERFORMANCE_TEST_REPORT + + python3 perfbenchmark/joinPerformance.py | tee -a $PERFORMANCE_TEST_REPORT + } diff --git a/tests/pytest/cluster/clusterEnvSetup/insert.json b/tests/pytest/cluster/clusterEnvSetup/insert.json index 4548ef74e6..2f3cf0f0d9 100644 --- a/tests/pytest/cluster/clusterEnvSetup/insert.json +++ b/tests/pytest/cluster/clusterEnvSetup/insert.json @@ -37,8 +37,6 @@ "insert_mode": "taosc", "insert_rate": 0, "insert_rows": 100000, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 1, "interlace_rows": 100, "max_sql_len": 1024000, "disorder_ratio": 0, diff --git a/tests/pytest/concurrent_inquiry.sh b/tests/pytest/concurrent_inquiry.sh index f426fbbcec..e5918792f4 100755 --- a/tests/pytest/concurrent_inquiry.sh +++ b/tests/pytest/concurrent_inquiry.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash # This is the script for us to try to cause the TDengine server or client to crash # diff --git a/tests/pytest/crash_gen/README.md b/tests/pytest/crash_gen/README.md index 6788ab1a63..8cdddd5b57 100644 --- a/tests/pytest/crash_gen/README.md +++ b/tests/pytest/crash_gen/README.md @@ -6,6 +6,25 @@ To effectively test and debug our TDengine product, we have developed a simple t exercise various functions of the system in a randomized fashion, hoping to expose maximum number of problems, hopefully without a pre-determined scenario. +# Features + +This tool can run as a test client with the following features: + +1. Any number of concurrent threads +1. Any number of test steps/loops +1. Auto-create and writing to multiple databases +1. Ignore specific error codes +1. Write small or large data blocks +1. Auto-generate out-of-sequence data, if needed +1. Verify the result of write operations +1. Concurrent writing to a shadow database for later data verification +1. User specified number of replicas to use, against clusters + +This tool can also use to start a TDengine service, either in stand-alone mode or +cluster mode. The features include: + +1. User specified number of D-Nodes to create/use. + # Preparation To run this tool, please ensure the followed preparation work is done first. @@ -16,7 +35,7 @@ To run this tool, please ensure the followed preparation work is done first. Ubuntu 20.04LTS as our own development environment, and suggest you also use such an environment if possible. -# Simple Execution +# Simple Execution as Client Test Tool To run the tool with the simplest method, follow the steps below: @@ -28,19 +47,21 @@ To run the tool with the simplest method, follow the steps below: That's it! -# Running Clusters +# Running Server-side Clusters This tool also makes it easy to test/verify the clustering capabilities of TDengine. You can start a cluster quite easily with the following command: ``` $ cd tests/pytest/ -$ ./crash_gen.sh -e -o 3 +$ rm -rf ../../build/cluster_dnode_?; ./crash_gen.sh -e -o 3 # first part optional ``` The `-e` option above tells the tool to start the service, and do not run any tests, while the `-o 3` option tells the tool to start 3 DNodes and join them together in a cluster. -Obviously you can adjust the the number here. +Obviously you can adjust the the number here. The `rm -rf` command line is optional +to clean up previous cluster data, so that we can start from a clean state with no data +at all. ## Behind the Scenes @@ -89,8 +110,9 @@ The exhaustive features of the tool is available through the `-h` option: ``` $ ./crash_gen.sh -h -usage: crash_gen_bootstrap.py [-h] [-a] [-b MAX_DBS] [-c CONNECTOR_TYPE] [-d] [-e] [-g IGNORE_ERRORS] [-i MAX_REPLICAS] [-l] [-n] [-o NUM_DNODES] [-p] [-r] - [-s MAX_STEPS] [-t NUM_THREADS] [-v] [-x] +usage: crash_gen_bootstrap.py [-h] [-a] [-b MAX_DBS] [-c CONNECTOR_TYPE] [-d] [-e] [-g IGNORE_ERRORS] + [-i NUM_REPLICAS] [-k] [-l] [-m] [-n] + [-o NUM_DNODES] [-p] [-r] [-s MAX_STEPS] [-t NUM_THREADS] [-v] [-w] [-x] TDengine Auto Crash Generator (PLEASE NOTICE the Prerequisites Below) --------------------------------------------------------------------- @@ -109,11 +131,14 @@ optional arguments: -e, --run-tdengine Run TDengine service in foreground (default: false) -g IGNORE_ERRORS, --ignore-errors IGNORE_ERRORS Ignore error codes, comma separated, 0x supported (default: None) - -i MAX_REPLICAS, --max-replicas MAX_REPLICAS - Maximum number of replicas to use, when testing against clusters. (default: 1) + -i NUM_REPLICAS, --num-replicas NUM_REPLICAS + Number (fixed) of replicas to use, when testing against clusters. (default: 1) + -k, --track-memory-leaks + Use Valgrind tool to track memory leaks (default: false) -l, --larger-data Write larger amount of data during write operations (default: false) + -m, --mix-oos-data Mix out-of-sequence data into the test data stream (default: true) -n, --dynamic-db-table-names - Use non-fixed names for dbs/tables, useful for multi-instance executions (default: false) + Use non-fixed names for dbs/tables, for -b, useful for multi-instance executions (default: false) -o NUM_DNODES, --num-dnodes NUM_DNODES Number of Dnodes to initialize, used with -e option. (default: 1) -p, --per-thread-db-connection @@ -124,6 +149,7 @@ optional arguments: -t NUM_THREADS, --num-threads NUM_THREADS Number of threads to run (default: 10) -v, --verify-data Verify data written in a number of places by reading back (default: false) + -w, --use-shadow-db Use a shaddow database to verify data integrity (default: false) -x, --continue-on-exception Continue execution after encountering unexpected/disallowed errors/exceptions (default: false) ``` diff --git a/tests/pytest/crash_gen/crash_gen_main.py b/tests/pytest/crash_gen/crash_gen_main.py index 0fe94bad1d..44295e8bee 100755 --- a/tests/pytest/crash_gen/crash_gen_main.py +++ b/tests/pytest/crash_gen/crash_gen_main.py @@ -1574,9 +1574,9 @@ class TaskCreateDb(StateTransitionTask): def _executeInternal(self, te: TaskExecutor, wt: WorkerThread): # was: self.execWtSql(wt, "create database db") repStr = "" - if gConfig.max_replicas != 1: + if gConfig.num_replicas != 1: # numReplica = Dice.throw(gConfig.max_replicas) + 1 # 1,2 ... N - numReplica = gConfig.max_replicas # fixed, always + numReplica = gConfig.num_replicas # fixed, always repStr = "replica {}".format(numReplica) updatePostfix = "update 1" if gConfig.verify_data else "" # allow update only when "verify data" is active dbName = self._db.getName() @@ -2394,11 +2394,16 @@ class MainExec: help='Ignore error codes, comma separated, 0x supported (default: None)') parser.add_argument( '-i', - '--max-replicas', + '--num-replicas', action='store', default=1, type=int, - help='Maximum number of replicas to use, when testing against clusters. (default: 1)') + help='Number (fixed) of replicas to use, when testing against clusters. (default: 1)') + parser.add_argument( + '-k', + '--track-memory-leaks', + action='store_true', + help='Use Valgrind tool to track memory leaks (default: false)') parser.add_argument( '-l', '--larger-data', diff --git a/tests/pytest/crash_gen/service_manager.py b/tests/pytest/crash_gen/service_manager.py index ae6f8d5d3a..cdbf2db4da 100644 --- a/tests/pytest/crash_gen/service_manager.py +++ b/tests/pytest/crash_gen/service_manager.py @@ -19,6 +19,7 @@ from queue import Queue, Empty from .misc import Logging, Status, CrashGenError, Dice, Helper, Progress from .db import DbConn, DbTarget +import crash_gen.settings class TdeInstance(): """ @@ -132,6 +133,7 @@ keep 36500 walLevel 1 # # maxConnections 100 +quorum 2 """ cfgContent = cfgTemplate.format_map(cfgValues) f = open(cfgFile, "w") @@ -164,7 +166,12 @@ walLevel 1 return "127.0.0.1" def getServiceCmdLine(self): # to start the instance - return [self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen() + cmdLine = [] + if crash_gen.settings.gConfig.track_memory_leaks: + Logging.info("Invoking VALGRIND on service...") + cmdLine = ['valgrind', '--leak-check=yes'] + cmdLine += ["exec " + self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen() + return cmdLine def _getDnodes(self, dbc): dbc.query("show dnodes") @@ -202,7 +209,7 @@ walLevel 1 self.generateCfgFile() # service side generates config file, client does not self.rotateLogs() - self._smThread.start(self.getServiceCmdLine()) + self._smThread.start(self.getServiceCmdLine(), self.getLogDir()) # May raise exceptions def stop(self): self._smThread.stop() @@ -225,7 +232,7 @@ class TdeSubProcess: # RET_SUCCESS = -4 def __init__(self): - self.subProcess = None + self.subProcess = None # type: subprocess.Popen # if tInst is None: # raise CrashGenError("Empty instance not allowed in TdeSubProcess") # self._tInst = tInst # Default create at ServiceManagerThread @@ -263,7 +270,7 @@ class TdeSubProcess: # print("Starting TDengine with env: ", myEnv.items()) # print("Starting TDengine via Shell: {}".format(cmdLineStr)) - useShell = True + useShell = True # Needed to pass environments into it self.subProcess = subprocess.Popen( # ' '.join(cmdLine) if useShell else cmdLine, # shell=useShell, @@ -276,12 +283,12 @@ class TdeSubProcess: env=myEnv ) # had text=True, which interferred with reading EOF - STOP_SIGNAL = signal.SIGKILL # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process? + STOP_SIGNAL = signal.SIGINT # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process? SIG_KILL_RETCODE = 137 # ref: https://stackoverflow.com/questions/43268156/process-finished-with-exit-code-137-in-pycharm def stop(self): """ - Stop a sub process, and try to return a meaningful return code. + Stop a sub process, DO NOT return anything, process all conditions INSIDE Common POSIX signal values (from man -7 signal): SIGHUP 1 @@ -301,40 +308,99 @@ class TdeSubProcess: """ if not self.subProcess: Logging.error("Sub process already stopped") - return # -1 + return retCode = self.subProcess.poll() # ret -N means killed with signal N, otherwise it's from exit(N) if retCode: # valid return code, process ended - retCode = -retCode # only if valid + # retCode = -retCode # only if valid Logging.warning("TSP.stop(): process ended itself") self.subProcess = None - return retCode + return # process still alive, let's interrupt it - Logging.info("Terminate running process, send SIG_{} and wait...".format(self.STOP_SIGNAL)) - # sub process should end, then IPC queue should end, causing IO thread to end - topSubProc = psutil.Process(self.subProcess.pid) - for child in topSubProc.children(recursive=True): # or parent.children() for recursive=False - child.send_signal(self.STOP_SIGNAL) - time.sleep(0.2) # 200 ms - # topSubProc.send_signal(sig) # now kill the main sub process (likely the Shell) + self._stopForSure(self.subProcess, self.STOP_SIGNAL) # success if no exception + self.subProcess = None - self.subProcess.send_signal(self.STOP_SIGNAL) # main sub process (likely the Shell) - self.subProcess.wait(20) - retCode = self.subProcess.returncode # should always be there - # May throw subprocess.TimeoutExpired exception above, therefore - # The process is guranteed to have ended by now - self.subProcess = None - if retCode == self.SIG_KILL_RETCODE: - Logging.info("TSP.stop(): sub proc KILLED, as expected") - elif retCode == (- self.STOP_SIGNAL): - Logging.info("TSP.stop(), sub process STOPPED, as expected") - elif retCode != 0: # != (- signal.SIGINT): - Logging.error("TSP.stop(): Failed to stop sub proc properly w/ SIG {}, retCode={}".format( - self.STOP_SIGNAL, retCode)) - else: - Logging.info("TSP.stop(): sub proc successfully terminated with SIG {}".format(self.STOP_SIGNAL)) - return - retCode + # sub process should end, then IPC queue should end, causing IO thread to end + + @classmethod + def _stopForSure(cls, proc: subprocess.Popen, sig: int): + ''' + Stop a process and all sub processes with a singal, and SIGKILL if necessary + ''' + def doKillTdService(proc: subprocess.Popen, sig: int): + Logging.info("Killing sub-sub process {} with signal {}".format(proc.pid, sig)) + proc.send_signal(sig) + try: + retCode = proc.wait(20) + if (- retCode) == signal.SIGSEGV: # Crashed + Logging.warning("Process {} CRASHED, please check CORE file!".format(proc.pid)) + elif (- retCode) == sig : + Logging.info("TD service terminated with expected return code {}".format(sig)) + else: + Logging.warning("TD service terminated, EXPECTING ret code {}, got {}".format(sig, -retCode)) + return True # terminated successfully + except subprocess.TimeoutExpired as err: + Logging.warning("Failed to kill sub-sub process {} with signal {}".format(proc.pid, sig)) + return False # failed to terminate + + + def doKillChild(child: psutil.Process, sig: int): + Logging.info("Killing sub-sub process {} with signal {}".format(child.pid, sig)) + child.send_signal(sig) + try: + retCode = child.wait(20) + if (- retCode) == signal.SIGSEGV: # Crashed + Logging.warning("Process {} CRASHED, please check CORE file!".format(child.pid)) + elif (- retCode) == sig : + Logging.info("Sub-sub process terminated with expected return code {}".format(sig)) + else: + Logging.warning("Process terminated, EXPECTING ret code {}, got {}".format(sig, -retCode)) + return True # terminated successfully + except psutil.TimeoutExpired as err: + Logging.warning("Failed to kill sub-sub process {} with signal {}".format(child.pid, sig)) + return False # did not terminate + + def doKill(proc: subprocess.Popen, sig: int): + pid = proc.pid + try: + topSubProc = psutil.Process(pid) + for child in topSubProc.children(recursive=True): # or parent.children() for recursive=False + Logging.warning("Unexpected child to be killed") + doKillChild(child, sig) + except psutil.NoSuchProcess as err: + Logging.info("Process not found, can't kill, pid = {}".format(pid)) + + return doKillTdService(proc, sig) + # TODO: re-examine if we need to kill the top process, which is always the SHELL for now + # try: + # proc.wait(1) # SHELL process here, may throw subprocess.TimeoutExpired exception + # # expRetCode = self.SIG_KILL_RETCODE if sig==signal.SIGKILL else (-sig) + # # if retCode == expRetCode: + # # Logging.info("Process terminated with expected return code {}".format(retCode)) + # # else: + # # Logging.warning("Process terminated, EXPECTING ret code {}, got {}".format(expRetCode, retCode)) + # # return True # success + # except subprocess.TimeoutExpired as err: + # Logging.warning("Failed to kill process {} with signal {}".format(pid, sig)) + # return False # failed to kill + + def softKill(proc, sig): + return doKill(proc, sig) + + def hardKill(proc): + return doKill(proc, signal.SIGKILL) + + + + pid = proc.pid + Logging.info("Terminate running processes under {}, with SIG #{} and wait...".format(pid, sig)) + if softKill(proc, sig): + return# success + if sig != signal.SIGKILL: # really was soft above + if hardKill(proc): + return + raise CrashGenError("Failed to stop process, pid={}".format(pid)) class ServiceManager: PAUSE_BETWEEN_IPC_CHECK = 1.2 # seconds between checks on STDOUT of sub process @@ -560,7 +626,8 @@ class ServiceManagerThread: # self._tInstNum = tInstNum # instance serial number in cluster, ZERO based # self._tInst = tInst or TdeInstance() # Need an instance - self._thread = None # The actual thread, # type: threading.Thread + self._thread = None # The actual thread, # type: threading.Thread + self._thread2 = None # watching stderr self._status = Status(Status.STATUS_STOPPED) # The status of the underlying service, actually. def __repr__(self): @@ -568,11 +635,20 @@ class ServiceManagerThread: self.getStatus(), self._tdeSubProcess) def getStatus(self): + ''' + Get the status of the process being managed. (misnomer alert!) + ''' return self._status # Start the thread (with sub process), and wait for the sub service # to become fully operational - def start(self, cmdLine): + def start(self, cmdLine : str, logDir: str): + ''' + Request the manager thread to start a new sub process, and manage it. + + :param cmdLine: the command line to invoke + :param logDir: the logging directory, to hold stdout/stderr files + ''' if self._thread: raise RuntimeError("Unexpected _thread") if self._tdeSubProcess: @@ -582,20 +658,30 @@ class ServiceManagerThread: self._status.set(Status.STATUS_STARTING) self._tdeSubProcess = TdeSubProcess() - self._tdeSubProcess.start(cmdLine) + self._tdeSubProcess.start(cmdLine) # TODO: verify process is running self._ipcQueue = Queue() self._thread = threading.Thread( # First thread captures server OUTPUT target=self.svcOutputReader, - args=(self._tdeSubProcess.getStdOut(), self._ipcQueue)) + args=(self._tdeSubProcess.getStdOut(), self._ipcQueue, logDir)) self._thread.daemon = True # thread dies with the program self._thread.start() + time.sleep(0.01) + if not self._thread.is_alive(): # What happened? + Logging.info("Failed to started process to monitor STDOUT") + self.stop() + raise CrashGenError("Failed to start thread to monitor STDOUT") + Logging.info("Successfully started process to monitor STDOUT") self._thread2 = threading.Thread( # 2nd thread captures server ERRORs target=self.svcErrorReader, - args=(self._tdeSubProcess.getStdErr(), self._ipcQueue)) + args=(self._tdeSubProcess.getStdErr(), self._ipcQueue, logDir)) self._thread2.daemon = True # thread dies with the program self._thread2.start() + time.sleep(0.01) + if not self._thread2.is_alive(): + self.stop() + raise CrashGenError("Failed to start thread to monitor STDERR") # wait for service to start for i in range(0, 100): @@ -643,7 +729,7 @@ class ServiceManagerThread: Logging.info("Service already stopped") return if self.getStatus().isStopping(): - Logging.info("Service is already being stopped") + Logging.info("Service is already being stopped, pid: {}".format(self._tdeSubProcess.getPid())) return # Linux will send Control-C generated SIGINT to the TDengine process # already, ref: @@ -653,14 +739,14 @@ class ServiceManagerThread: self._status.set(Status.STATUS_STOPPING) # retCode = self._tdeSubProcess.stop() - try: - retCode = self._tdeSubProcess.stop() - # print("Attempted to stop sub process, got return code: {}".format(retCode)) - if retCode == signal.SIGSEGV : # SGV - Logging.error("[[--ERROR--]]: TDengine service SEGV fault (check core file!)") - except subprocess.TimeoutExpired as err: - Logging.info("Time out waiting for TDengine service process to exit") - else: + # try: + # retCode = self._tdeSubProcess.stop() + # # print("Attempted to stop sub process, got return code: {}".format(retCode)) + # if retCode == signal.SIGSEGV : # SGV + # Logging.error("[[--ERROR--]]: TDengine service SEGV fault (check core file!)") + # except subprocess.TimeoutExpired as err: + # Logging.info("Time out waiting for TDengine service process to exit") + if not self._tdeSubProcess.stop(): # everything withing if self._tdeSubProcess.isRunning(): # still running, should now never happen Logging.error("FAILED to stop sub process, it is still running... pid = {}".format( self._tdeSubProcess.getPid())) @@ -683,16 +769,18 @@ class ServiceManagerThread: raise RuntimeError( "SMT.Join(): Unexpected status: {}".format(self._status)) - if self._thread: - self._thread.join() - self._thread = None - self._status.set(Status.STATUS_STOPPED) - # STD ERR thread - self._thread2.join() - self._thread2 = None + if self._thread or self._thread2 : + if self._thread: + self._thread.join() + self._thread = None + if self._thread2: # STD ERR thread + self._thread2.join() + self._thread2 = None else: print("Joining empty thread, doing nothing") + self._status.set(Status.STATUS_STOPPED) + def _trimQueue(self, targetSize): if targetSize <= 0: return # do nothing @@ -739,11 +827,22 @@ class ServiceManagerThread: print(pBar, end="", flush=True) print('\b\b\b\b', end="", flush=True) - def svcOutputReader(self, out: IO, queue): + def svcOutputReader(self, out: IO, queue, logDir: str): + ''' + The infinite routine that processes the STDOUT stream for the sub process being managed. + + :param out: the IO stream object used to fetch the data from + :param queue: the queue where we dump the roughly parsed line-by-line data + :param logDir: where we should dump a verbatim output file + ''' + os.makedirs(logDir, exist_ok=True) + logFile = os.path.join(logDir,'stdout.log') + fOut = open(logFile, 'wb') # Important Reference: https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python # print("This is the svcOutput Reader...") # for line in out : for line in iter(out.readline, b''): + fOut.write(line) # print("Finished reading a line: {}".format(line)) # print("Adding item to queue...") try: @@ -772,10 +871,16 @@ class ServiceManagerThread: # queue.put(line) # meaning sub process must have died Logging.info("EOF for TDengine STDOUT: {}".format(self)) - out.close() + out.close() # Close the stream + fOut.close() # Close the output file - def svcErrorReader(self, err: IO, queue): + def svcErrorReader(self, err: IO, queue, logDir: str): + os.makedirs(logDir, exist_ok=True) + logFile = os.path.join(logDir,'stderr.log') + fErr = open(logFile, 'wb') for line in iter(err.readline, b''): + fErr.write(line) Logging.info("TDengine STDERR: {}".format(line)) Logging.info("EOF for TDengine STDERR: {}".format(self)) - err.close() \ No newline at end of file + err.close() + fErr.close() \ No newline at end of file diff --git a/tests/pytest/crash_gen/valgrind_taos.supp b/tests/pytest/crash_gen/valgrind_taos.supp index 123858b3db..5eb5403395 100644 --- a/tests/pytest/crash_gen/valgrind_taos.supp +++ b/tests/pytest/crash_gen/valgrind_taos.supp @@ -17247,3 +17247,88 @@ fun:_PyEval_EvalFrameDefault fun:_PyEval_EvalCodeWithName } +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + fun:_PyEval_EvalFrameDefault + fun:_PyFunction_Vectorcall + fun:_PyEval_EvalFrameDefault + fun:_PyEval_EvalCodeWithName + fun:_PyEval_EvalCodeWithName + obj:/usr/bin/python3.8 + obj:/usr/bin/python3.8 + fun:PyVectorcall_Call + fun:_PyEval_EvalFrameDefault +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault + fun:_PyFunction_Vectorcall + fun:_PyEval_EvalFrameDefault + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + fun:_PyEval_EvalFrameDefault + fun:_PyFunction_Vectorcall + fun:_PyEval_EvalFrameDefault + fun:_PyEval_EvalCodeWithName + fun:PyEval_EvalCode + obj:/usr/bin/python3.8 + obj:/usr/bin/python3.8 + fun:PyVectorcall_Call + fun:_PyEval_EvalFrameDefault +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault + fun:_PyFunction_Vectorcall + fun:_PyEval_EvalFrameDefault + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault + obj:/usr/bin/python3.8 + fun:_PyEval_EvalFrameDefault + fun:_PyEval_EvalCodeWithName +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:/usr/lib/python3/dist-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so + obj:/usr/bin/python3.8 + obj:/usr/bin/python3.8 + obj:/usr/bin/python3.8 + fun:PyObject_CallMethod + fun:PyInit__openssl + fun:_PyImport_LoadDynamicModuleWithSpec + obj:/usr/bin/python3.8 + obj:/usr/bin/python3.8 + fun:PyVectorcall_Call + fun:_PyEval_EvalFrameDefault +} diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index c3282ce6f7..e7e0586636 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -22,6 +22,7 @@ python3 ./test.py -f insert/alterTableAndInsert.py python3 ./test.py -f insert/insertIntoTwoTables.py python3 ./test.py -f insert/before_1970.py python3 bug2265.py +python3 ./test.py -f insert/bug3654.py #table python3 ./test.py -f table/alter_wal0.py @@ -139,6 +140,18 @@ python3 ./test.py -f import_merge/importInsertThenImport.py python3 ./test.py -f import_merge/importCSV.py #======================p1-end=============== #======================p2-start=============== +# tools +python3 test.py -f tools/taosdumpTest.py + +python3 test.py -f tools/taosdemoTest.py +python3 test.py -f tools/taosdemoTestWithoutMetric.py +python3 test.py -f tools/taosdemoTestWithJson.py +python3 test.py -f tools/taosdemoTestLimitOffset.py +python3 test.py -f tools/taosdemoTestTblAlt.py +python3 test.py -f tools/taosdemoTestSampleData.py +python3 test.py -f tools/taosdemoTestInterlace.py +python3 test.py -f tools/taosdemoTestQuery.py + # update python3 ./test.py -f update/allow_update.py python3 ./test.py -f update/allow_update-0.py @@ -166,7 +179,7 @@ python3 ./test.py -f stable/query_after_reset.py # perfbenchmark python3 ./test.py -f perfbenchmark/bug3433.py -python3 ./test.py -f perfbenchmark/bug3589.py +#python3 ./test.py -f perfbenchmark/bug3589.py #query @@ -201,9 +214,11 @@ python3 ./test.py -f query/bug2119.py python3 ./test.py -f query/isNullTest.py python3 ./test.py -f query/queryWithTaosdKilled.py python3 ./test.py -f query/floatCompare.py +python3 ./test.py -f query/query1970YearsAf.py +python3 ./test.py -f query/bug3351.py python3 ./test.py -f query/bug3375.py - - +python3 ./test.py -f query/queryJoin10tables.py +python3 ./test.py -f query/queryStddevWithGroupby.py #stream python3 ./test.py -f stream/metric_1.py @@ -243,22 +258,12 @@ python3 test.py -f subscribe/singlemeter.py #python3 test.py -f subscribe/stability.py python3 test.py -f subscribe/supertable.py +# topic +python3 ./test.py -f topic/topicQuery.py #======================p3-end=============== #======================p4-start=============== -# tools -python3 test.py -f tools/taosdumpTest.py - -python3 test.py -f tools/taosdemoTest.py -python3 test.py -f tools/taosdemoTestWithoutMetric.py -python3 test.py -f tools/taosdemoTestWithJson.py -python3 test.py -f tools/taosdemoTestLimitOffset.py -python3 test.py -f tools/taosdemoTest2.py -python3 test.py -f tools/taosdemoTestSampleData.py -python3 test.py -f tools/taosdemoTestInterlace.py -python3 test.py -f tools/taosdemoTestQuery.py - python3 ./test.py -f update/merge_commit_data-0.py # wal python3 ./test.py -f wal/addOldWalTest.py diff --git a/tests/pytest/handle_crash_gen_val_log.sh b/tests/pytest/handle_crash_gen_val_log.sh index 55c10639d7..01cc62aaf8 100755 --- a/tests/pytest/handle_crash_gen_val_log.sh +++ b/tests/pytest/handle_crash_gen_val_log.sh @@ -36,16 +36,11 @@ for defiMemError in `grep 'definitely lost:' crash_gen-definitely-lost-out.log | do defiMemError=(${defiMemError//,/}) if [ -n "$defiMemError" ]; then - if [ "$defiMemError" -gt 0 -a "$defiMemError" -lt 1013 ]; then + if [ "$defiMemError" -gt 0 ]; then cat valgrind.err echo -e "${RED} ## Memory errors number valgrind reports \ Definitely lost is $defiMemError. More than our threshold! ## ${NC}" exit 8 - elif [ "$defiMemError" -gt 1013 ];then #add for azure - cat valgrind.err - echo -e "${RED} ## Memory errors number valgrind reports \ - Definitely lost is $defiMemError. More than our threshold! ## ${NC}" - exit 8 fi fi done diff --git a/tests/pytest/handle_taosd_val_log.sh b/tests/pytest/handle_taosd_val_log.sh index 6b7f669efe..829bc68225 100755 --- a/tests/pytest/handle_taosd_val_log.sh +++ b/tests/pytest/handle_taosd_val_log.sh @@ -21,7 +21,7 @@ rm -rf /var/lib/taos/* nohup valgrind --leak-check=yes $TAOSD_DIR > $TDIR/$VALGRIND_OUT 2> $TDIR/$VALGRIND_ERR & sleep 20 cd - -./crash_gen.sh -p -t 10 -s 200 +./crash_gen.sh -p -t 10 -s 1000 ps -ef |grep valgrind|grep -v grep|awk '{print $2}'|xargs kill -term while true do @@ -53,16 +53,11 @@ for defiMemError in `grep 'definitely lost:' taosd-definitely-lost-out.log | awk do defiMemError=(${defiMemError//,/}) if [ -n "$defiMemError" ]; then - if [ "$defiMemError" -gt 0 -a "$defiMemError" -lt 1013 ]; then + if [ "$defiMemError" -gt 0 ]; then cat $VALGRIND_ERR echo -e "${RED} ## Memory errors number valgrind reports \ Definitely lost is $defiMemError. More than our threshold! ## ${NC}" exit 8 - elif [ "$defiMemError" -gt 1013 ];then #add for azure - cat $VALGRIND_ERR - echo -e "${RED} ## Memory errors number valgrind reports \ - Definitely lost is $defiMemError. More than our threshold! ## ${NC}" - exit 8 fi fi done diff --git a/tests/pytest/insert/basic.py b/tests/pytest/insert/basic.py index dcb5834d55..f23f38651a 100644 --- a/tests/pytest/insert/basic.py +++ b/tests/pytest/insert/basic.py @@ -43,6 +43,9 @@ class TDTestCase: tdSql.query("select * from tb") tdSql.checkRows(insertRows + 4) + # test case for https://jira.taosdata.com:18080/browse/TD-3716: + tdSql.error("insert into tb(now, 1)") + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/insert/bug3654.py b/tests/pytest/insert/bug3654.py new file mode 100644 index 0000000000..41bedf771b --- /dev/null +++ b/tests/pytest/insert/bug3654.py @@ -0,0 +1,53 @@ +################################################################### +# 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 taos +import sys + +from util.log import * +from util.sql import * +from util.cases import * + +class TDTestCase: + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + + def run(self): + tdSql.prepare() + + tdLog.printNoPrefix("==========step1:create table") + tdSql.execute("drop database if exists db") + tdSql.execute("create database db keep 36500,36500,36500") + tdSql.execute("use db") + tdSql.execute("create stable if not exists stb1 (ts timestamp, c1 int) tags(t11 int)") + tdSql.execute("create table t10 using stb1 tags(1)") + gapdate = (datetime.datetime.now() - datetime.datetime(1970, 1, 1, 8, 0, 0)).days + + tdLog.printNoPrefix("==========step2:insert data") + tdSql.execute(f"insert into t10 values (now-{gapdate}d, 1)") + tdSql.execute(f"insert into t10 values (now-{gapdate + 1}d, 2)") + + tdLog.printNoPrefix("==========step3:query") + tdSql.query("select * from t10 where c1=1") + tdSql.checkRows(1) + tdSql.query("select * from t10 where c1=2") + tdSql.checkRows(1) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/insert/metadataUpdate.py b/tests/pytest/insert/metadataUpdate.py index 4c32b0e39a..1a960a20e6 100644 --- a/tests/pytest/insert/metadataUpdate.py +++ b/tests/pytest/insert/metadataUpdate.py @@ -11,13 +11,13 @@ # -*- coding: utf-8 -*- -import sys import taos from util.log import tdLog from util.cases import tdCases from util.sql import tdSql from util.dnodes import tdDnodes -from multiprocessing import Process +from multiprocessing import Process +import subprocess class TDTestCase: def init(self, conn, logSql): @@ -40,27 +40,22 @@ class TDTestCase: print("alter table done") def deleteTableAndRecreate(self): - self.host = "127.0.0.1" - self.user = "root" - self.password = "taosdata" self.config = tdDnodes.getSimCfgPath() - self.conn = taos.connect(host = self.host, user = self.user, password = self.password, config = self.config) - self.cursor = self.conn.cursor() - - self.cursor.execute("use test") - print("drop table stb") - self.cursor.execute("drop table stb") - - print("create table stb") - self.cursor.execute("create table if not exists stb (ts timestamp, col1 int) tags(areaid int, city nchar(20))") - print("insert data") + sqlCmds = "use test; drop table stb;" + sqlCmds += "create table if not exists stb (ts timestamp, col1 int) tags(areaid int, city nchar(20));" for i in range(self.tables): city = "beijing" if i % 2 == 0 else "shanghai" - self.cursor.execute("create table tb%d using stb tags(%d, '%s')" % (i, i, city)) - for j in range(self.rows): - self.cursor.execute("insert into tb%d values(%d, %d)" % (i, self.ts + j, j * 100000)) - + sqlCmds += "create table tb%d using stb tags(%d, '%s');" % (i, i, city) + for j in range(5): + sqlCmds += "insert into tb%d values(%d, %d);" % (i, self.ts + j, j * 100000) + command = ["taos", "-c", self.config, "-s", sqlCmds] + print("drop stb, recreate stb and insert data ") + result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") + if result.returncode == 0: + print("success:", result) + else: + print("error:", result) def run(self): tdSql.prepare() @@ -100,19 +95,17 @@ class TDTestCase: tdSql.query("select count(*) from stb") tdSql.checkData(0, 0, 10000) - tdSql.query("select count(*) from tb1") + tdSql.query("select count(*) from tb0") tdSql.checkData(0, 0, 1000) - p = Process(target=self.deleteTableAndRecreate, args=()) - p.start() - p.join() - p.terminate() + # drop stable in subprocess + self.deleteTableAndRecreate() tdSql.query("select count(*) from stb") - tdSql.checkData(0, 0, 10000) + tdSql.checkData(0, 0, 5 * self.tables) - tdSql.query("select count(*) from tb1") - tdSql.checkData(0, 0, 1000) + tdSql.query("select count(*) from tb0") + tdSql.checkData(0, 0, 5) def stop(self): tdSql.close() diff --git a/tests/pytest/perfbenchmark/bug3433.py b/tests/pytest/perfbenchmark/bug3433.py index 80e9cce0dc..e4480df6b6 100644 --- a/tests/pytest/perfbenchmark/bug3433.py +++ b/tests/pytest/perfbenchmark/bug3433.py @@ -91,8 +91,6 @@ class TDTestCase: "data_source": "rand", "insert_mode": "taosc", "insert_rows": 1, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "rows_per_tbl": 1, "max_sql_len": 65480, "disorder_ratio": 0, @@ -135,8 +133,6 @@ class TDTestCase: "data_source": "rand", "insert_mode": "taosc", "insert_rows": 1, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "rows_per_tbl": 1, "max_sql_len": 65480, "disorder_ratio": 0, diff --git a/tests/pytest/perfbenchmark/joinPerformance.py b/tests/pytest/perfbenchmark/joinPerformance.py new file mode 100644 index 0000000000..acd4f88c9b --- /dev/null +++ b/tests/pytest/perfbenchmark/joinPerformance.py @@ -0,0 +1,355 @@ +################################################################### +# 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 taos +import os +import json +import argparse +import subprocess +import datetime +import re + +from multiprocessing import cpu_count +# from util.log import * +# from util.sql import * +# from util.cases import * +# from util.dnodes import * + +class JoinPerf: + + def __init__(self, clearCache, dbName, keep): + self.clearCache = clearCache + self.dbname = dbName + self.drop = "yes" + self.keep = keep + self.host = "127.0.0.1" + self.user = "root" + self.password = "taosdata" + self.config = "/etc/taosperf" + self.conn = taos.connect( + self.host, + self.user, + self.password, + self.config) + + # def init(self, conn, logSql): + # tdLog.debug(f"start to excute {__file__}") + # tdSql.init(conn.cursor()) + + def getBuildPath(self) -> str: + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/debug/build/bin")] + break + return buildPath + + def getCfgDir(self) -> str: + return self.getBuildPath() + "/sim/dnode1/cfg" + + # def initConnection(self): + # return self.getCfgDir() + + # def connectDB(self): + # self.conn = taos.connect( + # self.host, + # self.user, + # self.password, + # self.getCfgDir()) + # return self.conn.cursor() + + def dbinfocfg(self) -> dict: + return { + "name": self.dbname, + "drop": self.drop, + "replica": 1, + "days": 10, + "cache": 16, + "blocks": 8, + "precision": "ms", + "keep": self.keep, + "minRows": 100, + "maxRows": 4096, + "comp": 2, + "walLevel": 1, + "cachelast": 0, + "quorum": 1, + "fsync": 3000, + "update": 0 + } + + # def column_tag_count(self, **column_tag) -> list : + # return [{"type": type, "count": count} for type, count in column_tag.items()] + + def type_check(func): + def wrapper(self, **kwargs): + num_types = ["int", "float", "bigint", "tinyint", "smallint", "double"] + str_types = ["binary", "nchar"] + for k ,v in kwargs.items(): + if k.lower() not in num_types and k.lower() not in str_types: + return f"args {k} type error, not allowed" + elif not isinstance(v, (int, list, tuple)): + return f"value {v} type error, not allowed" + elif k.lower() in num_types and not isinstance(v, int): + return f"arg {v} takes 1 positional argument must be type int " + elif isinstance(v, (list,tuple)) and len(v) > 2: + return f"arg {v} takes from 1 to 2 positional arguments but more than 2 were given " + elif isinstance(v,(list,tuple)) and [ False for _ in v if not isinstance(_, int) ]: + return f"arg {v} takes from 1 to 2 positional arguments must be type int " + else: + pass + return func(self, **kwargs) + return wrapper + + @type_check + def column_tag_count(self, **column_tag) -> list : + init_column_tag = [] + for k, v in column_tag.items(): + if re.search(k, "int, float, bigint, tinyint, smallint, double", re.IGNORECASE): + init_column_tag.append({"type": k, "count": v}) + elif re.search(k, "binary, nchar", re.IGNORECASE): + if isinstance(v, int): + init_column_tag.append({"type": k, "count": v, "len":8}) + elif len(v) == 1: + init_column_tag.append({"type": k, "count": v[0], "len": 8}) + else: + init_column_tag.append({"type": k, "count": v[0], "len": v[1]}) + return init_column_tag + + def stbcfg(self, stb: str, child_tab_count: int, prechildtab: str, columns: dict, tags: dict) -> dict: + return { + "name": stb, + "child_table_exists": "no", + "childtable_count": child_tab_count, + "childtable_prefix": prechildtab, + "auto_create_table": "no", + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 50, + "multi_thread_write_one_tbl": "no", + "number_of_tbl_in_one_sql": 0, + "rows_per_tbl": 1, + "max_sql_len": 65480, + "disorder_ratio": 0, + "disorder_range": 1000, + "timestamp_step": 20000, + "start_timestamp": "1969-12-31 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": self.column_tag_count(**columns), + "tags": self.column_tag_count(**tags) + } + + def createcfg(self,db: dict, stbs: list) -> dict: + return { + "filetype": "insert", + "cfgdir": self.config, + "host": self.host, + "port": 6030, + "user": self.user, + "password": self.password, + "thread_count": cpu_count(), + "thread_count_create_tbl": cpu_count(), + "result_file": "/tmp/insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "num_of_records_per_req": 100, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": db, + "super_tables": stbs + }] + } + + def createinsertfile(self,db: dict, stbs: list) -> str: + date = datetime.datetime.now().strftime("%Y%m%d%H%M") + file_create_table = f"/tmp/insert_{date}.json" + + with open(file_create_table, 'w') as f: + json.dump(self.createcfg(db, stbs), f) + + return file_create_table + + def querysqls(self, sql: str) -> list: + return [{"sql":sql,"result":""}] + + def querycfg(self, sql: str) -> dict: + return { + "filetype": "query", + "cfgdir": self.config, + "host": self.host, + "port": 6030, + "user": self.user, + "password": self.password, + "confirm_parameter_prompt": "yes", + "databases": "db", + "specified_table_query": { + "query_interval": 0, + "concurrent": cpu_count(), + "sqls": self.querysqls(sql) + } + } + + def createqueryfile(self, sql: str): + date = datetime.datetime.now().strftime("%Y%m%d%H%M") + file_query_table = f"/tmp/query_{date}.json" + + with open(file_query_table,"w") as f: + json.dump(self.querycfg(sql), f) + + return file_query_table + + def taosdemotable(self, filepath, resultfile="/dev/null"): + taosdemopath = self.getBuildPath() + "/debug/build/bin" + with open(filepath,"r") as f: + filetype = json.load(f)["filetype"] + if filetype == "insert": + taosdemo_table_cmd = f"{taosdemopath}/taosdemo -f {filepath} > {resultfile} 2>&1" + else: + taosdemo_table_cmd = f"yes | {taosdemopath}/taosdemo -f {filepath} > {resultfile} 2>&1" + _ = subprocess.check_output(taosdemo_table_cmd, shell=True).decode("utf-8") + + def droptmpfile(self): + drop_file_cmd = "rm -f /tmp/query_* " + _ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8") + drop_file_cmd = "rm -f querySystemInfo-*" + _ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8") + drop_file_cmd = "rm -f /tmp/insert_* " + _ = subprocess.check_output(drop_file_cmd, shell=True).decode("utf-8") + + def run(self): + print("========== join on table schema performance ==========") + if self.clearCache == True: + # must be root permission + subprocess.check_output("echo 3 > /proc/sys/vm/drop_caches") + + # cfg = { + # 'enableRecordSql': '1' + # } + # tdDnodes.deploy(1, cfg) + + # tdLog.printNoPrefix("==========step1: create 1024 columns on different data type==========") + # db = self.dbinfocfg() + # stblist = [] + # # the supertable config for each type in column_tag_types + # column_tag_types = ["INT","FLOAT","BIGINT","TINYINT","SMALLINT","DOUBLE","BINARY","NCHAR"] + # for i in range(len(column_tag_types)): + # tagtype = { + # "INT": 0, + # "FLOAT": 0, + # "BIGINT": 0, + # "TINYINT": 0, + # "SMALLINT": 0, + # "DOUBLE": 0, + # "BINARY": 0, + # "NCHAR": 0 + # } + # columntype = tagtype.copy() + # tagtype["INT"] = 2 + # if column_tag_types[i] == "BINARY": + # columntype[column_tag_types[i]] = [509, 10] + # elif column_tag_types[i] == "NCHAR": + # columntype[column_tag_types[i]] = [350, 10] + # else: + # columntype[column_tag_types[i]] = 1021 + # supertable = self.stbcfg( + # stb=f"stb{i}", + # child_tab_count=2, + # prechildtab=f"t{i}", + # columns=columntype, + # tags=tagtype + # ) + # stblist.append(supertable) + # self.taosdemotable(self.createinsertfile(db=db, stbs=stblist)) + + # tdLog.printNoPrefix("==========step2: execute query operation==========") + # tdLog.printNoPrefix("==========execute query operation==========") + sqls = { + "nchar":"select * from t00,t01 where t00.ts=t01.ts" + } + for type, sql in sqls.items(): + result_file = f"/tmp/queryResult_{type}.log" + self.taosdemotable(self.createqueryfile(sql), resultfile=result_file) + if result_file: + # tdLog.printNoPrefix(f"execute type {type} sql, the sql is: {sql}") + print(f"execute type {type} sql, the sql is: {sql}") + max_sql_time_cmd = f''' + grep Spent {result_file} | awk 'NR==1{{max=$7;next}}{{max=max>$7?max:$7}}END{{print "Max=",max,"s"}}' + ''' + max_sql_time = subprocess.check_output(max_sql_time_cmd, shell=True).decode("UTF-8") + # tdLog.printNoPrefix(f"type: {type} sql time : {max_sql_time}") + print(f"type: {type} sql time : {max_sql_time}") + + min_sql_time_cmd = f''' + grep Spent {result_file} | awk 'NR==1{{min=$7;next}}{{min=min<$7?min:$7}}END{{print "Min=",min,"s"}}' + ''' + min_sql_time = subprocess.check_output(min_sql_time_cmd, shell=True).decode("UTF-8") + # tdLog.printNoPrefix(f"type: {type} sql time : {min_sql_time}") + print(f"type: {type} sql time : {min_sql_time}") + + avg_sql_time_cmd = f''' + grep Spent {result_file} |awk '{{sum+=$7}}END{{print "Average=",sum/NR,"s"}}' + ''' + avg_sql_time = subprocess.check_output(avg_sql_time_cmd, shell=True).decode("UTF-8") + # tdLog.printNoPrefix(f"type: {type} sql time : {avg_sql_time}") + print(f"type: {type} sql time : {avg_sql_time}") + + # tdLog.printNoPrefix(f"==========type {type} sql is over==========") + + # tdLog.printNoPrefix("==========query operation is over==========") + + self.droptmpfile() + # tdLog.printNoPrefix("==========tmp file has been deleted==========") + + # def stop(self): + # tdSql.close() + # tdLog.success(f"{__file__} successfully executed") + +# tdCases.addLinux(__file__, TDTestCase()) +# tdCases.addWindows(__file__, TDTestCase()) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + '-r', + '--remove-cache', + action='store_true', + default=False, + help='clear cache before query (default: False)') + parser.add_argument( + '-d', + '--database-name', + action='store', + default='db', + type=str, + help='Database name to be created (default: db)') + parser.add_argument( + '-k', + '--keep-time', + action='store', + default=36500, + type=int, + help='Database keep parameters (default: 36500)') + + args = parser.parse_args() + jointest = JoinPerf(args.remove_cache, args.database_name, args.keep_time) + jointest.run() \ No newline at end of file diff --git a/tests/pytest/query/bug3351.py b/tests/pytest/query/bug3351.py new file mode 100644 index 0000000000..288d071a69 --- /dev/null +++ b/tests/pytest/query/bug3351.py @@ -0,0 +1,74 @@ +################################################################### +# 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 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") + tdSql.execute("create database if not exists db keep 36500") + tdSql.execute("use db") + tdLog.printNoPrefix("==========step1:create table && insert data") + + tdSql.execute( + "create table stb1 (ts timestamp, c1 int) TAGS(t1 int)" + ) + tdSql.execute("create table t0 using stb1 tags(1)") + tdSql.execute("insert into t0 values (-865000000, 1)") + tdSql.execute("insert into t0 values (-864000000, 2)") + tdSql.execute("insert into t0 values (-863000000, 3)") + tdSql.execute("insert into t0 values (-15230000, 4)") + tdSql.execute("insert into t0 values (-15220000, 5)") + tdSql.execute("insert into t0 values (-15210000, 6)") + + tdLog.printNoPrefix("==========step2:query") + # bug1:when ts > -864000000, return 0 rows; + # bug2:when ts = -15220000, return 0 rows. + tdSql.query('select * from t0 where ts < -864000000') + tdSql.checkRows(1) + tdSql.query('select * from t0 where ts <= -864000000') + tdSql.checkRows(2) + tdSql.query('select * from t0 where ts = -864000000') + tdSql.checkRows(1) + tdSql.query('select * from t0 where ts > -864000000') + tdSql.checkRows(4) + tdSql.query('select * from t0 where ts >= -864000000') + tdSql.checkRows(5) + tdSql.query('select * from t0 where ts < -15220000') + tdSql.checkRows(4) + tdSql.query('select * from t0 where ts <= -15220000') + tdSql.checkRows(5) + tdSql.query('select * from t0 where ts = -15220000') + tdSql.checkRows(1) + tdSql.query('select * from t0 where ts > -15220000') + tdSql.checkRows(1) + tdSql.query('select * from t0 where ts >= -15220000') + tdSql.checkRows(2) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/query/query1970YearsAf.py b/tests/pytest/query/query1970YearsAf.py index 9794973325..93404afd59 100644 --- a/tests/pytest/query/query1970YearsAf.py +++ b/tests/pytest/query/query1970YearsAf.py @@ -22,25 +22,34 @@ import datetime from util.log import * from util.sql import * from util.cases import * +from util.dnodes import * +from util.dnodes import TDDnode class TDTestCase: + def __init__(self): + self.path = "" + def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) - def getCfgDir(self, path): + def getcfgPath(self, path): binPath = os.path.dirname(os.path.realpath(__file__)) binPath = binPath + "/../../../debug/" - tdLog.debug("binPath %s" % (binPath)) + tdLog.debug(f"binPath {binPath}") binPath = os.path.realpath(binPath) - tdLog.debug("binPath real path %s" % (binPath)) + tdLog.debug(f"binPath real path {binPath}") + if path == "": self.path = os.path.abspath(binPath + "../../") else: self.path = os.path.realpath(path) + return self.path - self.cfgDir = "%s/sim/psim/cfg" % (self.path) + def getCfgDir(self): + self.getcfgPath(self.path) + self.cfgDir = f"{self.path}/sim/psim/cfg" return self.cfgDir def creatcfg(self): @@ -63,7 +72,7 @@ class TDTestCase: "update": 0 } - # 设置创建的超级表格式 + # set stable schema stable1 = { "name": "stb2", "child_table_exists": "no", @@ -73,37 +82,49 @@ class TDTestCase: "data_source": "rand", "insert_mode": "taosc", "insert_rows": 5000, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, - "rows_per_tbl": 1000, + "rows_per_tbl": 1, "max_sql_len": 65480, "disorder_ratio": 0, "disorder_range": 1000, - "timestamp_step": 19000000, - "start_timestamp": "1969-01-01 00:00:00.000", + "timestamp_step": 20000, + "start_timestamp": "1969-12-31 00:00:00.000", "sample_format": "csv", "sample_file": "./sample.csv", "tags_file": "", "columns": [ - {"type": "INT"}, - {"type": "DOUBLE", "count": 10}, - {"type": "BINARY", "len": 16, "count": 3}, - {"type": "BINARY", "len": 32, "count": 6} + {"type": "INT", "count": 2}, + {"type": "DOUBLE", "count": 2}, + {"type": "BIGINT", "count": 2}, + {"type": "FLOAT", "count": 2}, + {"type": "SMALLINT", "count": 2}, + {"type": "TINYINT", "count": 2}, + {"type": "BOOL", "count": 2}, + {"type": "NCHAR", "len": 3, "count": 1}, + {"type": "BINARY", "len": 8, "count": 1} + ], "tags": [ + {"type": "INT", "count": 2}, + {"type": "DOUBLE", "count": 2}, + {"type": "BIGINT", "count": 2}, + {"type": "FLOAT", "count": 2}, + {"type": "SMALLINT", "count": 2}, {"type": "TINYINT", "count": 2}, - {"type": "BINARY", "len": 16, "count": 5} + {"type": "BOOL", "count": 2}, + {"type": "NCHAR", "len": 3, "count": 1}, + {"type": "BINARY", "len": 8, "count": 1} ] } - # 需要创建多个超级表时,只需创建不同的超级表格式并添加至super_tables - super_tables = [stable1] + # create different stables like stable1 and add to list super_tables + super_tables = [] + super_tables.append(stable1) database = { "dbinfo": dbinfo, "super_tables": super_tables } - cfgdir = self.getCfgDir("") + cfgdir = self.getCfgDir() create_table = { "filetype": "insert", "cfgdir": cfgdir, @@ -121,17 +142,82 @@ class TDTestCase: } return create_table - def inserttable(self): + def createinsertfile(self): create_table = self.creatcfg() date = datetime.datetime.now().strftime("%Y%m%d%H%M") file_create_table = f"/tmp/insert_{date}.json" with open(file_create_table, 'w') as f: json.dump(create_table, f) + return file_create_table - create_table_cmd = f"taosdemo -f {file_create_table}" + def inserttable(self, filepath): + create_table_cmd = f"taosdemo -f {filepath} > /dev/null 2>&1" _ = subprocess.check_output(create_table_cmd, shell=True).decode("utf-8") + def sqlsquery(self): + # stable query + tdSql.query( + "select * from stb2 where stb2.ts < '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(43200) + + tdSql.query( + "select * from stb2 where stb2.ts >= '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(6800) + + tdSql.query( + "select * from stb2 where stb2.ts > '1969-12-31 23:00:00.000' and stb2.ts <'1970-01-01 01:00:00.000' " + ) + tdSql.checkRows(3590) + + # child-tables query + tdSql.query( + "select * from t0 where t0.ts < '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(4320) + + tdSql.query( + "select * from t1 where t1.ts >= '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(680) + + tdSql.query( + "select * from t9 where t9.ts > '1969-12-31 22:00:00.000' and t9.ts <'1970-01-01 02:00:00.000' " + ) + tdSql.checkRows(719) + + tdSql.query( + "select * from t0,t1 where t0.ts=t1.ts and t1.ts >= '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(680) + + tdSql.query( + "select diff(col1) from t0 where t0.ts >= '1970-01-01 00:00:00.000' " + ) + tdSql.checkRows(679) + + tdSql.query( + "select t0,col1 from stb2 where stb2.ts < '1970-01-01 00:00:00.000' order by ts" + ) + tdSql.checkRows(43200) + + # query with timestamp in 'where ...' + tdSql.query( + "select * from stb2 where stb2.ts > -28800000 " + ) + tdSql.checkRows(6790) + + tdSql.query( + "select * from stb2 where stb2.ts > -28800000 and stb2.ts < '1970-01-01 08:00:00.000' " + ) + tdSql.checkRows(6790) + + tdSql.query( + "select * from stb2 where stb2.ts < -28800000 and stb2.ts > '1969-12-31 22:00:00.000' " + ) + tdSql.checkRows(3590) def run(self): s = 'reset query cache' @@ -142,84 +228,24 @@ class TDTestCase: tdSql.execute(s) tdLog.info("==========step1:create table stable and child table,then insert data automatically") - self.inserttable() - # tdSql.execute( - # '''create table if not exists supt - # (ts timestamp, c1 int, c2 float, c3 bigint, c4 double, c5 smallint, c6 tinyint) - # tags(location binary(64), type int, isused bool , family nchar(64))''' - # ) - # tdSql.execute("create table t1 using supt tags('beijing', 1, 1, '自行车')") - # tdSql.execute("create table t2 using supt tags('shanghai', 2, 0, '拖拉机')") - # tdSql.execute( - # f"insert into t1 values (-31564800000, 6, 5, 4, 3, 2, 1)" - # ) - - + insertfile = self.createinsertfile() + self.inserttable(insertfile) tdLog.info("==========step2:query join") + self.sqlsquery() - # stable query - tdSql.query( - "select * from stb2 where stb2.ts < '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(16600) + # after wal and sync, check again + tdSql.query("show dnodes") + index = tdSql.getData(0, 0) + tdDnodes.stop(index) + tdDnodes.start(index) - tdSql.query( - "select * from stb2 where stb2.ts >= '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(33400) - - tdSql.query( - "select * from stb2 where stb2.ts > '1969-12-01 00:00:00.000' and stb2.ts <'1970-01-31 00:00:00.000' " - ) - tdSql.checkRows(2780) - - # child-table query - tdSql.query( - "select * from t0 where t0.ts < '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(1660) - - tdSql.query( - "select * from t1 where t1.ts >= '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(3340) - - tdSql.query( - "select * from t9 where t9.ts > '1969-12-01 00:00:00.000' and t9.ts <'1970-01-31 00:00:00.000' " - ) - tdSql.checkRows(278) - - tdSql.query( - "select * from t0,t1 where t0.ts=t1.ts and t1.ts >= '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(3340) - - tdSql.query( - "select diff(col1) from t0 where t0.ts >= '1970-01-01 00:00:00.000' " - ) - tdSql.checkRows(3339) - - tdSql.query( - "select t0,col1 from stb2 where stb2.ts < '1970-01-01 00:00:00.000' order by ts" - ) - tdSql.checkRows(16600) - - # query with timestamp in 'where ...' - tdSql.query( - "select * from stb2 where stb2.ts > -28800000 " - ) - tdSql.checkRows(33400) - - tdSql.query( - "select * from stb2 where stb2.ts > -28800000 and stb2.ts < '1970-01-01 08:00:00.000' " - ) - tdSql.checkRows(20) - - tdSql.query( - "select * from stb2 where stb2.ts < -28800000 and stb2.ts > '1969-12-31 16:00:00.000' " - ) + tdLog.info("==========step3: query join again") + self.sqlsquery() + # delete temporary file + rm_cmd = f"rm -f /tmp/insert* > /dev/null 2>&1" + _ = subprocess.check_output(rm_cmd, shell=True).decode("utf-8") def stop(self): tdSql.close() @@ -227,4 +253,4 @@ class TDTestCase: tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/pytest/query/queryJoin10tables.py b/tests/pytest/query/queryJoin10tables.py new file mode 100644 index 0000000000..01a7397d44 --- /dev/null +++ b/tests/pytest/query/queryJoin10tables.py @@ -0,0 +1,201 @@ +################################################################### +# 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 taos +import sys + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + + def createtable(self): + + # create stbles + tdSql.execute("create table if not exists stb1 (ts timestamp, c1 int) tags(t11 int, t12 int)") + tdSql.execute("create table if not exists stb2 (ts timestamp, c2 int) tags(t21 int, t22 int)") + tdSql.execute("create table if not exists stb3 (ts timestamp, c3 int) tags(t31 int, t32 int)") + tdSql.execute("create table if not exists stb4 (ts timestamp, c4 int) tags(t41 int, t42 int)") + tdSql.execute("create table if not exists stb5 (ts timestamp, c5 int) tags(t51 int, t52 int)") + tdSql.execute("create table if not exists stb6 (ts timestamp, c6 int) tags(t61 int, t62 int)") + tdSql.execute("create table if not exists stb7 (ts timestamp, c7 int) tags(t71 int, t72 int)") + tdSql.execute("create table if not exists stb8 (ts timestamp, c8 int) tags(t81 int, t82 int)") + tdSql.execute("create table if not exists stb9 (ts timestamp, c9 int) tags(t91 int, t92 int)") + tdSql.execute("create table if not exists stb10 (ts timestamp, c10 int) tags(t101 int, t102 int)") + tdSql.execute("create table if not exists stb11 (ts timestamp, c11 int) tags(t111 int, t112 int)") + + # create normal tables + tdSql.execute("create table t10 using stb1 tags(0, 9)") + tdSql.execute("create table t11 using stb1 tags(1, 8)") + tdSql.execute("create table t12 using stb1 tags(2, 7)") + tdSql.execute("create table t13 using stb1 tags(3, 6)") + tdSql.execute("create table t14 using stb1 tags(4, 5)") + tdSql.execute("create table t15 using stb1 tags(5, 4)") + tdSql.execute("create table t16 using stb1 tags(6, 3)") + tdSql.execute("create table t17 using stb1 tags(7, 2)") + tdSql.execute("create table t18 using stb1 tags(8, 1)") + tdSql.execute("create table t19 using stb1 tags(9, 0)") + tdSql.execute("create table t110 using stb1 tags(10, 10)") + + tdSql.execute("create table t20 using stb2 tags(0, 9)") + tdSql.execute("create table t21 using stb2 tags(1, 8)") + tdSql.execute("create table t22 using stb2 tags(2, 7)") + + tdSql.execute("create table t30 using stb3 tags(0, 9)") + tdSql.execute("create table t31 using stb3 tags(1, 8)") + tdSql.execute("create table t32 using stb3 tags(2, 7)") + + def inserttable(self): + for i in range(100): + if i<60: + tdSql.execute(f"insert into t20 values('2020-10-01 00:00:{i}.000', {i})") + tdSql.execute(f"insert into t21 values('2020-10-01 00:00:{i}.000', {i})") + tdSql.execute(f"insert into t22 values('2020-10-01 00:00:{i}.000', {i})") + tdSql.execute(f"insert into t30 values('2020-10-01 00:00:{i}.000', {i})") + tdSql.execute(f"insert into t31 values('2020-10-01 00:00:{i}.000', {i})") + tdSql.execute(f"insert into t32 values('2020-10-01 00:00:{i}.000', {i})") + else: + tdSql.execute(f"insert into t20 values('2020-10-01 00:01:{i-60}.000', {i})") + tdSql.execute(f"insert into t21 values('2020-10-01 00:01:{i-60}.000', {i})") + tdSql.execute(f"insert into t22 values('2020-10-01 00:01:{i-60}.000', {i})") + tdSql.execute(f"insert into t30 values('2020-10-01 00:01:{i-60}.000', {i})") + tdSql.execute(f"insert into t31 values('2020-10-01 00:01:{i-60}.000', {i})") + tdSql.execute(f"insert into t32 values('2020-10-01 00:01:{i-60}.000', {i})") + for j in range(11): + if i<60: + tdSql.execute(f"insert into t1{j} values('2020-10-01 00:00:{i}.000', {i})") + else: + tdSql.execute(f"insert into t1{j} values('2020-10-01 00:01:{i-60}.000', {i})") + + def queryjointable(self): + tdSql.error( + '''select from t10,t11,t12,t13,t14,t15,t16,t17,t18,t19 + where t10.ts=t11.ts and t10.ts=t12.ts and t10.ts=t13.ts and t10.ts=t14.ts and t10.ts=t15.ts + and t10.ts=t16.ts and t10.ts=t17.ts and t10.ts=t18.ts and t10.ts=t19.ts''' + ) + tdSql.error("select * from t10 where t10.ts=t11.ts") + tdSql.error("select * from where t10.ts=t11.ts") + tdSql.error("select * from t10,t11,t12,t13,t14,t15,t16,t17,t18,t19") + tdSql.error("select * from stb1, stb2, stb3 where stb1.ts=stb2.ts and stb1.ts=stb3.ts") + tdSql.error("select * from stb1, stb2, stb3 where stb1.t11=stb2.t21 and stb1.t11=stb3.t31") + tdSql.error("select * from stb1, stb2, stb3") + tdSql.error( + '''select * from stb1 + join stb2 on stb1.ts=stb2.ts and stb1.t11=stb2.t21 + join stb3 on stb1.ts=stb3.ts and stb1.t11=stb3.t31''' + ) + tdSql.error("select * from t10 join t11 on t10.ts=t11.ts join t12 on t11.ts=t12.ts") + tdSql.query( + '''select * from stb1,stb2,stb3 + where stb1.ts=stb2.ts and stb1.ts=stb3.ts and stb1.t11=stb2.t21 and stb1.t11 =stb3.t31''' + ) + tdSql.checkRows(300) + tdSql.query("select * from t11,t12,t13 where t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.checkRows(100) + tdSql.error("selec * from t11,t12,t13 where t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.error("select * form t11,t12,t13 where t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts <> t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts != t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts or t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.c1=t12.c2 and t11.c1=t13.c3") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.c3 and t11.c1=t13.ts") + tdSql.error("select ts from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts and ts>100") + tdSql.error("select * from t11,t12,stb1 when t11.ts=t12.ts and t11.ts=stb1.ts") + tdSql.error("select t14.ts from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts1") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t14.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts") + tdSql.error("select * from t11,t12,t13 when t11.ts=t12.ts and t11.ts=t13.ts and t11.c1=t13.c3") + tdSql.error( + '''select * from t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20 + where t10.ts=t11.ts and t10.ts=t12.ts and t10.ts=t13.ts and t10.ts=t14.ts and t10.ts=t15.ts + and t10.ts=t16.ts and t10.ts=t17.ts and t10.ts=t18.ts and t10.ts=t19.ts and t10.ts=t20.ts''' + ) + tdSql.error( + '''select * from t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20 + where t10.ts=t11.ts and t10.ts=t12.ts and t10.ts=t13.ts and t10.ts=t14.ts and t10.ts=t15.ts + and t10.ts=t16.ts and t10.ts=t17.ts and t10.ts=t18.ts and t10.ts=t19.ts''' + ) + tdSql.error( + '''select * from t10,t11,t12,t13,t14,t15,t16,t17,t18,t19 + where t10.ts=t11.ts and t10.ts=t12.ts and t10.ts=t13.ts and t10.ts=t14.ts and t10.ts=t15.ts + and t10.ts=t16.ts and t10.ts=t17.ts and t10.ts=t18.ts and t10.ts=t19.ts and t10.c1=t19.c1''' + ) + tdSql.error( + '''select * from stb1,stb2,stb3 + where stb1.ts=stb2.ts and stb1.ts=stb3.ts and stb1.t11=stb2.t21''' + ) + tdSql.error( + '''select * from stb1,stb2,stb3 + where stb1.ts=stb2.ts and stb1.t11=stb2.t21 and stb1.t11=stb3.t31''' + ) + tdSql.error( + '''select * from stb1,stb2,stb3 + where stb1.ts=stb2.ts and stb1.ts=stb3.ts and stb1.t11=stb2.t21 and stb1.t11=stb3.t31 + and stb1.t12=stb3=t32''' + ) + tdSql.error( + '''select * from stb1,stb2,stb3,stb4,stb5,stb6,stb7,stb8,stb9,stb10,stb11 + where stb1.ts=stb2.ts and stb1.ts=stb3.ts and stb1.ts=stb4.ts and stb1.ts=stb5.ts and stb1.ts=stb6.ts + and stb1.ts=stb7.ts and stb1.ts=stb8.ts and stb1.ts=stb9.ts and stb1.ts=stb10.ts and stb1.ts=stb11.ts + and stb1.t11=stb2.t21 and stb1.t11=stb3.t31 and stb1.t11=stb4.t41 and stb1.t11=stb5.t51 + and stb1.t11=stb6.t61 and stb1.t11=stb7.t71 and stb1.t11=stb8.t81 and stb1.t11=stb9.t91 + and stb1.t11=stb10.t101 and stb1.t11=stb11.t111''' + ) + tdSql.error( + '''select * from stb1,stb2,stb3,stb4,stb5,stb6,stb7,stb8,stb9,stb10 + where stb1.ts=stb2.ts and stb1.ts=stb3.ts and stb1.ts=stb4.ts and stb1.ts=stb5.ts and stb1.ts=stb6.ts + and stb1.ts=stb7.ts and stb1.ts=stb8.ts and stb1.ts=stb9.ts and stb1.ts=stb10.ts and stb1.t11=stb2.t21 + and stb1.t11=stb3.t31 and stb1.t11=stb4.t41 and stb1.t11=stb5.t51 and stb1.t11=stb6.t61 + and stb1.t11=stb7.t71 and stb1.t11=stb8.t81 and stb1.t11=stb9.t91 and stb1.t11=stb10.t101 + and stb1.t12=stb11.t102''' + ) + + def run(self): + tdSql.prepare() + + tdLog.printNoPrefix("==========step1:create table") + self.createtable() + + tdLog.printNoPrefix("==========step2:insert data") + self.inserttable() + + tdLog.printNoPrefix("==========step3:query timestamp type") + self.queryjointable() + + # after wal and sync, check again + tdSql.query("show dnodes") + index = tdSql.getData(0, 0) + tdDnodes.stop(index) + tdDnodes.start(index) + + tdLog.printNoPrefix("==========step4:query again after wal") + self.queryjointable() + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/query/queryStddevWithGroupby.py b/tests/pytest/query/queryStddevWithGroupby.py new file mode 100644 index 0000000000..aee88ca9c5 --- /dev/null +++ b/tests/pytest/query/queryStddevWithGroupby.py @@ -0,0 +1,68 @@ +################################################################### +# 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 init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def querysqls(self): + tdSql.query("select stddev(c1) from t10 group by c1") + tdSql.checkRows(6) + tdSql.checkData(0, 0, 0) + tdSql.checkData(1, 0, 0) + tdSql.checkData(2, 0, 0) + tdSql.checkData(3, 0, 0) + tdSql.checkData(4, 0, 0) + tdSql.checkData(5, 0, 0) + tdSql.query("select stddev(c2) from t10") + tdSql.checkData(0, 0, 0.5) + + def run(self): + tdSql.execute("drop database if exists db") + tdSql.execute("create database if not exists db keep 36500") + tdSql.execute("use db") + + tdLog.printNoPrefix("==========step1:create table && insert data") + tdSql.execute("create stable stb1 (ts timestamp , c1 int ,c2 float) tags(t1 int)") + tdSql.execute("create table t10 using stb1 tags(1)") + tdSql.execute("insert into t10 values ('1969-12-31 00:00:00.000', 2,1)") + tdSql.execute("insert into t10 values ('1970-01-01 00:00:00.000', 3,1)") + tdSql.execute("insert into t10 values (0, 4,1)") + tdSql.execute("insert into t10 values (now-18725d, 1,2)") + tdSql.execute("insert into t10 values ('2021-04-06 00:00:00.000', 5,2)") + tdSql.execute("insert into t10 values (now+1d,6,2)") + + tdLog.printNoPrefix("==========step2:query and check") + self.querysqls() + + tdLog.printNoPrefix("==========step3:after wal,check again") + tdSql.query("show dnodes") + index = tdSql.getData(0, 0) + tdDnodes.stop(index) + tdDnodes.start(index) + self.querysqls() + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/tools/insert-interlace.json b/tests/pytest/tools/insert-interlace.json index d4767ad064..a5c545d159 100644 --- a/tests/pytest/tools/insert-interlace.json +++ b/tests/pytest/tools/insert-interlace.json @@ -41,7 +41,6 @@ "data_source": "rand", "insert_mode": "taosc", "insert_rows": 250, - "multi_thread_write_one_tbl": "no", "interlace_rows": 80, "max_sql_len": 1024000, "disorder_ratio": 0, diff --git a/tests/pytest/tools/insert-tblimit-tboffset-createdb.json b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json new file mode 100644 index 0000000000..9220bc1d17 --- /dev/null +++ b/tests/pytest/tools/insert-tblimit-tboffset-createdb.json @@ -0,0 +1,55 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "num_of_records_per_req": 100, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "yes", + "replica": 1, + "days": 10, + "cache": 16, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb", + "child_table_exists":"no", + "childtable_count": 100, + "childtable_prefix": "stb_", + "auto_create_table": "no", + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 0, + "max_sql_len": 1024000, + "disorder_ratio": 0, + "disorder_range": 1000, + "timestamp_step": 1, + "start_timestamp": "2020-10-01 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} diff --git a/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json new file mode 100644 index 0000000000..164d4fe8be --- /dev/null +++ b/tests/pytest/tools/insert-tblimit-tboffset-insertrec.json @@ -0,0 +1,57 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "thread_count": 4, + "thread_count_create_tbl": 4, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "insert_interval": 0, + "num_of_records_per_req": 100, + "max_sql_len": 1024000, + "databases": [{ + "dbinfo": { + "name": "db", + "drop": "no", + "replica": 1, + "days": 10, + "cache": 16, + "blocks": 8, + "precision": "ms", + "keep": 365, + "minRows": 100, + "maxRows": 4096, + "comp":2, + "walLevel":1, + "cachelast":0, + "quorum":1, + "fsync":3000, + "update": 0 + }, + "super_tables": [{ + "name": "stb", + "child_table_exists":"yes", + "childtable_count": 100, + "childtable_prefix": "stb_", + "auto_create_table": "no", + "data_source": "rand", + "insert_mode": "taosc", + "insert_rows": 1000, + "childtable_limit": 33, + "childtable_offset": 33, + "max_sql_len": 1024000, + "disorder_ratio": 0, + "disorder_range": 1000, + "timestamp_step": 1, + "start_timestamp": "2020-10-01 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "tags_file": "", + "columns": [{"type": "INT"}, {"type": "DOUBLE", "count":10}, {"type": "BINARY", "len": 16, "count":3}, {"type": "BINARY", "len": 32, "count":6}], + "tags": [{"type": "TINYINT", "count":2}, {"type": "BINARY", "len": 16, "count":5}] + }] + }] +} diff --git a/tests/pytest/tools/insert-tblimit-tboffset.json b/tests/pytest/tools/insert-tblimit-tboffset.json index f3d3e864ba..0b8e0bd6c5 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset.json +++ b/tests/pytest/tools/insert-tblimit-tboffset.json @@ -42,8 +42,6 @@ "insert_rows": 1000, "childtable_limit": 33, "childtable_offset": 33, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "max_sql_len": 1024000, "disorder_ratio": 0, "disorder_range": 1000, diff --git a/tests/pytest/tools/insert-tblimit-tboffset0.json b/tests/pytest/tools/insert-tblimit-tboffset0.json index 7dcb2e0527..55d9e19055 100644 --- a/tests/pytest/tools/insert-tblimit-tboffset0.json +++ b/tests/pytest/tools/insert-tblimit-tboffset0.json @@ -15,7 +15,7 @@ "databases": [{ "dbinfo": { "name": "db", - "drop": "yes", + "drop": "no", "replica": 1, "days": 10, "cache": 16, @@ -33,7 +33,7 @@ }, "super_tables": [{ "name": "stb", - "child_table_exists":"no", + "child_table_exists":"yes", "childtable_count": 100, "childtable_prefix": "stb_", "auto_create_table": "no", @@ -42,8 +42,6 @@ "insert_rows": 1000, "childtable_limit": 20, "childtable_offset": 0, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "max_sql_len": 1024000, "disorder_ratio": 0, "disorder_range": 1000, diff --git a/tests/pytest/tools/insert-tblimit1-tboffset.json b/tests/pytest/tools/insert-tblimit1-tboffset.json index a33dc22d5d..3a88665661 100644 --- a/tests/pytest/tools/insert-tblimit1-tboffset.json +++ b/tests/pytest/tools/insert-tblimit1-tboffset.json @@ -15,7 +15,7 @@ "databases": [{ "dbinfo": { "name": "db", - "drop": "yes", + "drop": "no", "replica": 1, "days": 10, "cache": 16, @@ -33,7 +33,7 @@ }, "super_tables": [{ "name": "stb", - "child_table_exists":"no", + "child_table_exists":"yes", "childtable_count": 100, "childtable_prefix": "stb_", "auto_create_table": "no", @@ -42,8 +42,6 @@ "insert_rows": 1000, "childtable_limit": 1, "childtable_offset": 50, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "max_sql_len": 1024000, "disorder_ratio": 0, "disorder_range": 1000, diff --git a/tests/pytest/tools/taosdemo-sampledata.json b/tests/pytest/tools/taosdemo-sampledata.json index 473c977773..ce1c68b393 100644 --- a/tests/pytest/tools/taosdemo-sampledata.json +++ b/tests/pytest/tools/taosdemo-sampledata.json @@ -16,16 +16,12 @@ "name": "stb", "child_table_exists":"no", "childtable_count": 20, - "childtable_limit": 10, - "childtable_offset": 0, "childtable_prefix": "t_", "auto_create_table": "no", "data_source": "sample", "insert_mode": "taosc", "insert_rate": 0, "insert_rows": 20, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, "max_sql_len": 1048000, "timestamp_step": 1000, "start_timestamp": "2020-1-1 00:00:00", diff --git a/tests/pytest/tools/taosdemoPerformance.py b/tests/pytest/tools/taosdemoPerformance.py index 1156cc2484..b50180e2b3 100644 --- a/tests/pytest/tools/taosdemoPerformance.py +++ b/tests/pytest/tools/taosdemoPerformance.py @@ -49,9 +49,7 @@ class taosdemoPerformace: "batch_create_tbl_num": 10, "insert_mode": "taosc", "insert_rows": 100000, - "multi_thread_write_one_tbl": "no", - "number_of_tbl_in_one_sql": 0, - "rows_per_tbl": 100, + "interlace_rows": 100, "max_sql_len": 1024000, "disorder_ratio": 0, "disorder_range": 1000, @@ -159,4 +157,4 @@ if __name__ == '__main__': perftest = taosdemoPerformace(args.commit_id, args.database_name) perftest.insertData() - perftest.createTablesAndStoreData() \ No newline at end of file + perftest.createTablesAndStoreData() diff --git a/tests/pytest/tools/taosdemoTestLimitOffset.py b/tests/pytest/tools/taosdemoTestLimitOffset.py index bce41e1c75..dd8a1bee70 100644 --- a/tests/pytest/tools/taosdemoTestLimitOffset.py +++ b/tests/pytest/tools/taosdemoTestLimitOffset.py @@ -51,7 +51,8 @@ class TDTestCase: else: tdLog.info("taosd found in %s" % buildPath) binPath = buildPath+ "/build/bin/" - os.system("%staosdemo -f tools/insert-tblimit-tboffset.json" % binPath) + os.system("%staosdemo -f tools/insert-tblimit-tboffset-createdb.json" % binPath) + os.system("%staosdemo -f tools/insert-tblimit-tboffset-insertrec.json" % binPath) tdSql.execute("use db") tdSql.query("select count(tbname) from db.stb") @@ -59,6 +60,7 @@ class TDTestCase: tdSql.query("select count(*) from db.stb") tdSql.checkData(0, 0, 33000) + os.system("%staosdemo -f tools/insert-tblimit-tboffset-createdb.json" % binPath) os.system("%staosdemo -f tools/insert-tblimit-tboffset0.json" % binPath) tdSql.execute("reset query cache") @@ -68,6 +70,7 @@ class TDTestCase: tdSql.query("select count(*) from db.stb") tdSql.checkData(0, 0, 20000) + os.system("%staosdemo -f tools/insert-tblimit-tboffset-createdb.json" % binPath) os.system("%staosdemo -f tools/insert-tblimit1-tboffset.json" % binPath) tdSql.execute("reset query cache") diff --git a/tests/pytest/tools/taosdemoTestSampleData.py b/tests/pytest/tools/taosdemoTestSampleData.py index 893c53984d..a8710a9df3 100644 --- a/tests/pytest/tools/taosdemoTestSampleData.py +++ b/tests/pytest/tools/taosdemoTestSampleData.py @@ -57,7 +57,7 @@ class TDTestCase: tdSql.query("select count(tbname) from db.stb") tdSql.checkData(0, 0, 20) tdSql.query("select count(*) from db.stb") - tdSql.checkData(0, 0, 200) + tdSql.checkData(0, 0, 400) def stop(self): tdSql.close() diff --git a/tests/pytest/tools/taosdemoTest2.py b/tests/pytest/tools/taosdemoTestTblAlt.py similarity index 63% rename from tests/pytest/tools/taosdemoTest2.py rename to tests/pytest/tools/taosdemoTestTblAlt.py index 74b05faf8b..bb367817cf 100644 --- a/tests/pytest/tools/taosdemoTest2.py +++ b/tests/pytest/tools/taosdemoTestTblAlt.py @@ -29,10 +29,33 @@ class TDTestCase: self.numberOfTables = 10 self.numberOfRecords = 1000000 + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + def insertDataAndAlterTable(self, threadID): + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + binPath = buildPath + "/build/bin/" + if(threadID == 0): - os.system("taosdemo -y -t %d -n %d" % - (self.numberOfTables, self.numberOfRecords)) + os.system("%staosdemo -y -t %d -n %d" % + (binPath, self.numberOfTables, self.numberOfRecords)) if(threadID == 1): time.sleep(2) print("use test") @@ -47,7 +70,13 @@ class TDTestCase: # check if all the tables have heen created while True: - tdSql.query("show tables") + try: + tdSql.query("show tables") + except Exception as e: + tdLog.info("show tables test failed") + time.sleep(1) + continue + rows = tdSql.queryRows print("number of tables: %d" % rows) if(rows == self.numberOfTables): @@ -56,16 +85,23 @@ class TDTestCase: # check if there are any records in the last created table while True: print("query started") - tdSql.query("select * from test.t9") + try: + tdSql.query("select * from test.t9") + except Exception as e: + tdLog.info("select * test failed") + time.sleep(2) + continue + rows = tdSql.queryRows print("number of records: %d" % rows) if(rows > 0): break time.sleep(1) + print("alter table test.meters add column col10 int") tdSql.execute("alter table test.meters add column col10 int") - print("insert into test.t0 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)") - tdSql.execute("insert into test.t0 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)") + print("insert into test.t9 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)") + tdSql.execute("insert into test.t9 values (now, 1, 2, 3, 4, 0.1, 0.01,'test', '测试', TRUE, 1610000000000, 0)") def run(self): tdSql.prepare() @@ -78,6 +114,8 @@ class TDTestCase: t1.join() t2.join() + time.sleep(3) + tdSql.query("select count(*) from test.meters") tdSql.checkData(0, 0, self.numberOfRecords * self.numberOfTables + 1) diff --git a/tests/pytest/topic/topicQuery.py b/tests/pytest/topic/topicQuery.py new file mode 100644 index 0000000000..1ee3c3a427 --- /dev/null +++ b/tests/pytest/topic/topicQuery.py @@ -0,0 +1,91 @@ +################################################################### +# 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 -*- + +from util.log import tdLog +from util.cases import tdCases +from util.sql import tdSql + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + self.ts = 1538548685000 + + def run(self): + tdSql.prepare() + + # test case for https://jira.taosdata.com:18080/browse/TD-3679 + print("==============step1") + tdSql.execute( + "create topic tq_test partitions 10") + tdSql.execute( + "insert into tq_test.p1(off, ts, content) values(0, %d, 'aaaa')" % self.ts) + tdSql.execute( + "insert into tq_test.p1(off, ts, content) values(1, %d, 'aaaa')" % (self.ts + 1)) + tdSql.execute( + "insert into tq_test.p1(off, ts, content) values(2, %d, 'aaaa')" % (self.ts + 2)) + tdSql.execute( + "insert into tq_test.p1(off, ts, content) values(3, %d, 'aaaa')" % (self.ts + 3)) + + print("==============step2") + + tdSql.query("select * from tq_test.p1") + tdSql.checkRows(4) + + tdSql.query("select * from tq_test.p1 where ts >= %d" % self.ts) + tdSql.checkRows(4) + + tdSql.query("select * from tq_test.p1 where ts > %d" % self.ts) + tdSql.checkRows(3) + + tdSql.query("select * from tq_test.p1 where ts = %d" % self.ts) + tdSql.checkRows(1) + + + tdSql.execute("use db") + tdSql.execute("create table test(ts timestamp, start timestamp, value int)") + tdSql.execute("insert into test values(%d, %d, 1)" % (self.ts, self.ts)) + tdSql.execute("insert into test values(%d, %d, 1)" % (self.ts + 1, self.ts + 1)) + tdSql.execute("insert into test values(%d, %d, 1)" % (self.ts + 2, self.ts + 2)) + tdSql.execute("insert into test values(%d, %d, 1)" % (self.ts + 3, self.ts + 3)) + + tdSql.query("select * from test") + tdSql.checkRows(4) + + tdSql.query("select * from test where ts >= %d" % self.ts) + tdSql.checkRows(4) + + tdSql.query("select * from test where ts > %d" % self.ts) + tdSql.checkRows(3) + + tdSql.query("select * from test where ts = %d" % self.ts) + tdSql.checkRows(1) + + tdSql.query("select * from test where start >= %d" % self.ts) + tdSql.checkRows(4) + + tdSql.query("select * from test where start > %d" % self.ts) + tdSql.checkRows(3) + + tdSql.query("select * from test where start = %d" % self.ts) + tdSql.checkRows(1) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/script/general/parser/groupby.sim b/tests/script/general/parser/groupby.sim index dd7331054c..124e76e85c 100644 --- a/tests/script/general/parser/groupby.sim +++ b/tests/script/general/parser/groupby.sim @@ -220,6 +220,7 @@ sql_error select sum(c3), ts, c2 from group_tb0 where c1 < 20 group by c1; sql_error select sum(c3), first(ts), c2 from group_tb0 where c1 < 20 group by c1; sql_error select first(c3), ts, c1, c2 from group_tb0 where c1 < 20 group by c1; sql_error select first(c3), last(c3), ts, c1 from group_tb0 where c1 < 20 group by c1; +sql_error select ts from group_tb0 group by c1; #===========================interval=====not support====================== sql_error select count(*), c1 from group_tb0 where c1<20 interval(1y) group by c1; diff --git a/tests/script/general/parser/having.sim b/tests/script/general/parser/having.sim new file mode 100644 index 0000000000..2e95664d31 --- /dev/null +++ b/tests/script/general/parser/having.sim @@ -0,0 +1,1841 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 0 +system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect +print ======================== dnode1 start + +$db = testdb + +sql create database $db +sql use $db + +sql create stable st2 (ts timestamp, f1 int, f2 float, f3 double, f4 bigint, f5 smallint, f6 tinyint, f7 bool, f8 binary(10), f9 nchar(10)) tags (id1 int, id2 float, id3 nchar(10), id4 double, id5 smallint, id6 bigint, id7 binary(10)) + +sql create table tb1 using st2 tags (1,1.0,"1",1.0,1,1,"1"); +sql create table tb2 using st2 tags (2,2.0,"2",2.0,2,2,"2"); +sql create table tb3 using st2 tags (3,3.0,"3",3.0,3,3,"3"); +sql create table tb4 using st2 tags (4,4.0,"4",4.0,4,4,"4"); + +sql insert into tb1 values (now-200s,1,1.0,1.0,1,1,1,true ,"1","1") +sql insert into tb1 values (now-150s,1,1.0,1.0,1,1,1,false,"1","1") +sql insert into tb1 values (now-100s,2,2.0,2.0,2,2,2,true ,"2","2") +sql insert into tb1 values (now-50s ,2,2.0,2.0,2,2,2,false,"2","2") +sql insert into tb1 values (now ,3,3.0,3.0,3,3,3,true ,"3","3") +sql insert into tb1 values (now+50s ,3,3.0,3.0,3,3,3,false,"3","3") +sql insert into tb1 values (now+100s,4,4.0,4.0,4,4,4,true ,"4","4") +sql insert into tb1 values (now+150s,4,4.0,4.0,4,4,4,false,"4","4") + + +sql select count(*),f1 from st2 group by f1 having count(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + + + + +sql select count(*),f1 from st2 group by f1 having count(*) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + + +sql select count(*),f1 from st2 group by f1 having count(f2) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + +sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; + +sql select last(f1) from st2 group by f1 having count(f2) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data20 != 3 then + return -1 +endi +if $data30 != 4 then + return -1 +endi + +sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; + +sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; + +sql_error select top(f1,2) from st2 group by f1 having avg(f1) > 0; + +sql select avg(f1),count(f1) from st2 group by f1 having avg(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi + + +sql select avg(f1),count(f1) from st2 group by f1 having avg(f1) > 2 and sum(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having avg(f1) > 2 and sum(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having avg(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 2 and sum(f1) < 6; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi + + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having 1 <= sum(f1) and 5 >= sum(f1); +if $rows != 2 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1),twa(f1) from st2 group by tbname having twa(f1) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 2.500000000 then + return -1 +endi +if $data01 != 8 then + return -1 +endi +if $data02 != 20 then + return -1 +endi +if $data04 != tb1 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1),twa(f1) from st2 group by f1 having twa(f1) > 0; + +sql select avg(f1),count(f1),sum(f1),twa(f1) from st2 group by tbname having sum(f1) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 2.500000000 then + return -1 +endi +if $data01 != 8 then + return -1 +endi +if $data02 != 20 then + return -1 +endi +if $data04 != tb1 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1),twa(f1) from st2 group by f1 having sum(f1) > 0; + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 3; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +###########and issue +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 3 and sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 3 or sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 3 or sum(f1) > 4; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +############or issue +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having sum(f1) > 3 or avg(f1) > 4; +if $rows != 0 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having (sum(f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1) from st2 group by f1 having (sum(*) > 3); + +sql select avg(f1),count(f1),sum(f1) from st2 group by f1 having (sum(st2.f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1) from st2 group by f1 having (sum(st2.f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),stddev(f1) from st2 group by f1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi +if $data34 != 0.000000000 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having (stddev(st2.f1) > 3); +if $rows != 0 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having (stddev(st2.f1) < 1); +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having (LEASTSQUARES(f1) < 1); + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having LEASTSQUARES(f1) < 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having LEASTSQUARES(f1,1,1) < 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having LEASTSQUARES(f1,1,1) > 2; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),LEASTSQUARES(f1,1,1) from st2 group by f1 having LEASTSQUARES(f1,1,1) > 2; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),LEASTSQUARES(f1,1,1) from st2 group by f1 having sum(f1) > 2; + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1) from st2 group by f1 having min(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1) from st2 group by f1 having min(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 3 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 4 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1) from st2 group by f1 having max(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 3 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 4 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1) from st2 group by f1 having max(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1) from st2 group by f1 having first(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi + + + +sql select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1) from st2 group by f1 having first(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data06 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data16 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi +if $data26 != 4 then + return -1 +endi + + + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having top(f1,1); + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having top(f1,1) > 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having bottom(f1,1) > 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),top(f1,1),bottom(f1,1) from st2 group by f1 having bottom(f1,1) > 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),top(f1,1),bottom(f1,1) from st2 group by f1 having sum(f1) > 1; + +sql_error select PERCENTILE(f1) from st2 group by f1 having sum(f1) > 1; + +sql_error select PERCENTILE(f1,20) from st2 group by f1 having sum(f1) > 1; + +sql select aPERCENTILE(f1,20) from st2 group by f1 having sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from st2 group by f1 having apercentile(f1,1) > 1; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from st2 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,1) < 50; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from st2 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,1) < 3; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from st2 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,3) < 3; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + +sql_error select aPERCENTILE(f1,20) from st2 group by f1 having apercentile(1) > 1; + +sql_error select aPERCENTILE(f1,20),LAST_ROW(f1) from st2 group by f1 having apercentile(1) > 1; + +sql_error select aPERCENTILE(f1,20),LAST_ROW(f1) from st2 group by f1 having apercentile(f1,1) > 1; + +sql_error select sum(f1) from st2 group by f1 having last_row(f1) > 1; + +sql_error select avg(f1) from st2 group by f1 having diff(f1) > 0; + +sql_error select avg(f1),diff(f1) from st2 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),diff(f1) from st2 group by f1 having spread(f2) > 0; + +sql select avg(f1) from st2 group by f1 having spread(f2) > 0; +if $rows != 0 then + return -1 +endi + +sql select avg(f1) from st2 group by f1 having spread(f2) = 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi + +sql select avg(f1),spread(f2) from st2 group by f1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) = 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) != 0; +if $rows != 0 then + return -1 +endi + + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) + 1 > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) + 1; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) + sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) + sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) - sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) * sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) / sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) > sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) 0 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) + 0 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) - f1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) - id1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) > id1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) > id1 and sum(f1) > 1; + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) > 2 and sum(f1) > 1; +if $rows != 0 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) = 0 and sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by f1 having spread(f1) = 0 and avg(f1) > 1; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by c1 having spread(f1) = 0 and avg(f1) > 1; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by id1 having avg(id1) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 group by id1 having avg(f1) > id1; + +sql_error select avg(f1),spread(f1,f2,st2.f1),avg(id1) from st2 group by id1 having avg(f1) > id1; + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by id1 having avg(f1) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 2.500000000 then + return -1 +endi +if $data01 != 3.000000000 then + return -1 +endi +if $data02 != 3.000000000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 group by id1 having avg(f1) < 2; +if $rows != 0 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f1 > 0 group by f1 having avg(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f1 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f3 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having avg(f1) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having avg(ts) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having avg(f7) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having avg(f8) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having avg(f9) > 0; + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having count(f9) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having last(f9) > 0; + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having last(f2) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 3 group by f1 having last(f3) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 1 group by f1 having last(f3) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 1 group by f1 having last(f4) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 1 group by f1 having last(f5) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 1 group by f1 having last(f6) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + + +sql_error select avg(f1),spread(f1,f2,st2.f1),f1,f2 from st2 where f2 > 1 group by f1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1),f1,f6 from st2 where f2 > 1 group by f1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1),f1,f6 from st2 where f2 > 1 group by f1,f2 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1),f1,f6 from st2 where f2 > 1 group by f1,id1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,st2.f1),f1,f6 from st2 where f2 > 1 group by id1 having last(f6) > 0; + +sql select avg(f1),spread(f1,f2,st2.f1) from st2 where f2 > 1 group by id1 having last(f6) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2.000000000 then + return -1 +endi +if $data02 != 2.000000000 then + return -1 +endi +if $data03 != 2.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi + +sql_error select top(f1,2) from tb1 group by f1 having count(f1) > 0; + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/having_child.sim b/tests/script/general/parser/having_child.sim new file mode 100644 index 0000000000..1f29a63b91 --- /dev/null +++ b/tests/script/general/parser/having_child.sim @@ -0,0 +1,1891 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 0 +system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 +system sh/exec.sh -n dnode1 -s start + +sleep 100 +sql connect +print ======================== dnode1 start + +$db = testdb + +sql create database $db +sql use $db + +sql create stable st2 (ts timestamp, f1 int, f2 float, f3 double, f4 bigint, f5 smallint, f6 tinyint, f7 bool, f8 binary(10), f9 nchar(10)) tags (id1 int, id2 float, id3 nchar(10), id4 double, id5 smallint, id6 bigint, id7 binary(10)) + +sql create table tb1 using st2 tags (1,1.0,"1",1.0,1,1,"1"); +sql create table tb2 using st2 tags (2,2.0,"2",2.0,2,2,"2"); +sql create table tb3 using st2 tags (3,3.0,"3",3.0,3,3,"3"); +sql create table tb4 using st2 tags (4,4.0,"4",4.0,4,4,"4"); + +sql insert into tb1 values (now-200s,1,1.0,1.0,1,1,1,true ,"1","1") +sql insert into tb1 values (now-150s,1,1.0,1.0,1,1,1,false,"1","1") +sql insert into tb1 values (now-100s,2,2.0,2.0,2,2,2,true ,"2","2") +sql insert into tb1 values (now-50s ,2,2.0,2.0,2,2,2,false,"2","2") +sql insert into tb1 values (now ,3,3.0,3.0,3,3,3,true ,"3","3") +sql insert into tb1 values (now+50s ,3,3.0,3.0,3,3,3,false,"3","3") +sql insert into tb1 values (now+100s,4,4.0,4.0,4,4,4,true ,"4","4") +sql insert into tb1 values (now+150s,4,4.0,4.0,4,4,4,false,"4","4") + + +sql select count(*),f1 from tb1 group by f1 having count(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + + +sql select count(*),f1 from tb1 group by f1 having count(*) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + + +sql select count(*),f1 from tb1 group by f1 having count(f2) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data20 != 2 then + return -1 +endi +if $data21 != 3 then + return -1 +endi +if $data30 != 2 then + return -1 +endi +if $data31 != 4 then + return -1 +endi + +sql_error select top(f1,2) from tb1 group by f1 having count(f2) > 0; + +sql select last(f1) from tb1 group by f1 having count(f2) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1 then + return -1 +endi +if $data10 != 2 then + return -1 +endi +if $data20 != 3 then + return -1 +endi +if $data30 != 4 then + return -1 +endi + +sql_error select top(f1,2) from tb1 group by f1 having count(f2) > 0; + +sql_error select top(f1,2) from tb1 group by f1 having count(f2) > 0; + +sql_error select top(f1,2) from tb1 group by f1 having avg(f1) > 0; + +sql select avg(f1),count(f1) from tb1 group by f1 having avg(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi + + +sql select avg(f1),count(f1) from tb1 group by f1 having avg(f1) > 2 and sum(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having avg(f1) > 2 and sum(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having avg(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 2 and sum(f1) < 6; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi + + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having 1 <= sum(f1) and 5 >= sum(f1); +if $rows != 2 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1),twa(f1) from tb1 group by tbname having twa(f1) > 0; + +sql select avg(f1),count(f1),sum(f1),twa(f1) from tb1 group by f1 having twa(f1) > 3; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 8 then + return -1 +endi +if $data03 != 4.000000000 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1),twa(f1) from tb1 group by tbname having sum(f1) > 0; + +sql select avg(f1),count(f1),sum(f1),twa(f1) from tb1 group by f1 having sum(f1) = 4; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data03 != 2.000000000 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 3; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +###########and issue +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 3 and sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 3 or sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 3 or sum(f1) > 4; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +############or issue +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having sum(f1) > 3 or avg(f1) > 4; +if $rows != 0 then + return -1 +endi + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having (sum(f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql_error select avg(f1),count(f1),sum(f1) from tb1 group by f1 having (sum(*) > 3); + +sql select avg(f1),count(f1),sum(f1) from tb1 group by f1 having (sum(tb1.f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1) from tb1 group by f1 having (sum(tb1.f1) > 3); +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),stddev(f1) from tb1 group by f1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi +if $data34 != 0.000000000 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having (stddev(tb1.f1) > 3); +if $rows != 0 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having (stddev(tb1.f1) < 1); +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 4 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 6 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 2 then + return -1 +endi +if $data32 != 8 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having (LEASTSQUARES(f1) < 1); + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having LEASTSQUARES(f1) < 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having LEASTSQUARES(f1,1,1) < 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having LEASTSQUARES(f1,1,1) > 2; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),LEASTSQUARES(f1,1,1) from tb1 group by f1 having LEASTSQUARES(f1,1,1) > 2; + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),LEASTSQUARES(f1,1,1) from tb1 group by f1 having sum(f1) > 2; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 4 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1) from tb1 group by f1 having min(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1) from tb1 group by f1 having min(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 3 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 4 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1) from tb1 group by f1 having max(f1) > 2; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 6 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 3 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 8 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 4 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1) from tb1 group by f1 having max(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1) from tb1 group by f1 having first(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi + + + +sql select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1) from tb1 group by f1 having first(f1) != 2; +if $rows != 3 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 2 then + return -1 +endi +if $data02 != 2 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data04 != 1 then + return -1 +endi +if $data05 != 1 then + return -1 +endi +if $data06 != 1 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 2 then + return -1 +endi +if $data12 != 6 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data14 != 3 then + return -1 +endi +if $data15 != 3 then + return -1 +endi +if $data16 != 3 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 2 then + return -1 +endi +if $data22 != 8 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data24 != 4 then + return -1 +endi +if $data25 != 4 then + return -1 +endi +if $data26 != 4 then + return -1 +endi + + + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having top(f1,1); + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having top(f1,1) > 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having bottom(f1,1) > 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),top(f1,1),bottom(f1,1) from tb1 group by f1 having bottom(f1,1) > 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),top(f1,1),bottom(f1,1) from tb1 group by f1 having sum(f1) > 1; + +sql_error select PERCENTILE(f1) from tb1 group by f1 having sum(f1) > 1; + +sql select PERCENTILE(f1,20) from tb1 group by f1 having sum(f1) = 4; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from tb1 group by f1 having sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from tb1 group by f1 having apercentile(f1,1) > 1; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from tb1 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,1) < 50; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from tb1 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,1) < 3; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + +sql select aPERCENTILE(f1,20) from tb1 group by f1 having apercentile(f1,1) > 1 and apercentile(f1,3) < 3; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + +sql_error select aPERCENTILE(f1,20) from tb1 group by f1 having apercentile(1) > 1; + +sql_error select aPERCENTILE(f1,20),LAST_ROW(f1) from tb1 group by f1 having apercentile(1) > 1; + +sql_error select aPERCENTILE(f1,20),LAST_ROW(f1) from tb1 group by f1 having apercentile(f1,1) > 1; + +sql_error select sum(f1) from tb1 group by f1 having last_row(f1) > 1; + +sql_error select avg(f1) from tb1 group by f1 having diff(f1) > 0; + +sql_error select avg(f1),diff(f1) from tb1 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),diff(f1) from tb1 group by f1 having spread(f2) > 0; + +sql select avg(f1) from tb1 group by f1 having spread(f2) > 0; +if $rows != 0 then + return -1 +endi + +sql select avg(f1) from tb1 group by f1 having spread(f2) = 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi + +sql select avg(f1),spread(f2) from tb1 group by f1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) = 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) != 0; +if $rows != 0 then + return -1 +endi + + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) + 1 > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) + 1; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) + sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) + sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) - sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) * sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) / sum(f1) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) > sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) 0 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) + 0 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) - f1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) - id1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) > id1 and sum(f1); + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) > id1 and sum(f1) > 1; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) > 2 and sum(f1) > 1; +if $rows != 0 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) = 0 and sum(f1) > 1; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having spread(f1) = 0 and avg(f1) > 1; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by c1 having spread(f1) = 0 and avg(f1) > 1; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by id1 having avg(id1) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by id1 having avg(f1) > id1; + +sql_error select avg(f1),spread(f1,f2,tb1.f1),avg(id1) from tb1 group by id1 having avg(f1) > id1; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by id1 having avg(f1) > 0; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having avg(f1) > 0 and avg(f1) = 3; +if $rows != 1 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by f1 having avg(f1) < 0 and avg(f1) = 3; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 group by id1 having avg(f1) < 2; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f1 > 0 group by f1 having avg(f1) > 0; +if $rows != 4 then + return -1 +endi +if $data00 != 1.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 2.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 3.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi +if $data30 != 4.000000000 then + return -1 +endi +if $data31 != 0.000000000 then + return -1 +endi +if $data32 != 0.000000000 then + return -1 +endi +if $data33 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f1 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f3 > 2 group by f1 having avg(f1) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 3.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 4.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having avg(f1) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having avg(ts) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having avg(f7) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having avg(f8) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having avg(f9) > 0; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having count(f9) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql_error select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having last(f9) > 0; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having last(f2) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 3 group by f1 having last(f3) > 0; +if $rows != 1 then + return -1 +endi +if $data00 != 4.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 1 group by f1 having last(f3) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 1 group by f1 having last(f4) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 1 group by f1 having last(f5) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 1 group by f1 having last(f6) > 0; +if $rows != 3 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi +if $data20 != 4.000000000 then + return -1 +endi +if $data21 != 0.000000000 then + return -1 +endi +if $data22 != 0.000000000 then + return -1 +endi +if $data23 != 0.000000000 then + return -1 +endi + + +sql_error select avg(f1),spread(f1,f2,tb1.f1),f1,f2 from tb1 where f2 > 1 group by f1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1),f1,f6 from tb1 where f2 > 1 group by f1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1),f1,f6 from tb1 where f2 > 1 group by f1,f2 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1),f1,f6 from tb1 where f2 > 1 group by f1,id1 having last(f6) > 0; + +sql_error select avg(f1),spread(f1,f2,tb1.f1),f1,f6 from tb1 where f2 > 1 group by id1 having last(f6) > 0; + +sql select avg(f1),spread(f1,f2,tb1.f1) from tb1 where f2 > 1 and f2 < 4 group by f1 having last(f6) > 0; +if $rows != 2 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data01 != 0.000000000 then + return -1 +endi +if $data02 != 0.000000000 then + return -1 +endi +if $data03 != 0.000000000 then + return -1 +endi +if $data10 != 3.000000000 then + return -1 +endi +if $data11 != 0.000000000 then + return -1 +endi +if $data12 != 0.000000000 then + return -1 +endi +if $data13 != 0.000000000 then + return -1 +endi + +sql_error select top(f1,2) from tb1 group by f1 having count(f1) > 0; + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/test-all.sh b/tests/test-all.sh index 883c1495e9..47e5de6aa0 100755 --- a/tests/test-all.sh +++ b/tests/test-all.sh @@ -25,29 +25,24 @@ function stopTaosd { function dohavecore(){ corefile=`find $corepath -mmin 1` core_file=`echo $corefile|cut -d " " -f2` - echo "corefile:$core_file" - echo "corepath:$corepath" - ls -l $corepath proc=`echo $corefile|cut -d "_" -f3` if [ -n "$corefile" ];then echo 'taosd or taos has generated core' + rm case.log if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]] && [[ $1 == 1 ]]; then cd ../../../ tar -zcPf $corepath'taos_'`date "+%Y_%m_%d_%H_%M_%S"`.tar.gz debug/build/bin/taosd debug/build/bin/tsim debug/build/lib/libtaos*so* if [[ $2 == 1 ]];then cp -r sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S"` - rm -rf sim/case.log else cd community cp -r sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" ` - rm -rf sim/case.log fi else cd ../../ if [[ $1 == 1 ]];then tar -zcPf $corepath'taos_'`date "+%Y_%m_%d_%H_%M_%S"`.tar.gz debug/build/bin/taosd debug/build/bin/tsim debug/build/lib/libtaos*so* cp -r sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" ` - rm -rf sim/case.log fi fi if [[ $1 == 1 ]];then @@ -82,10 +77,10 @@ function runSimCaseOneByOne { # fi end_time=`date +%s` echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log - dohavecore 0 fi done < $1 } + function runSimCaseOneByOnefq { start=`sed -n "/$1-start/=" jenkins/basic.txt` @@ -99,26 +94,25 @@ function runSimCaseOneByOnefq { date +%F\ %T | tee -a out.log if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then echo -n $case - ./test.sh -f $case > ../../../sim/case.log 2>&1 && \ + ./test.sh -f $case > case.log 2>&1 && \ ( grep -q 'script.*'$case'.*failed.*, err.*lineNum' ../../../sim/tsim/log/taoslog0.0 && echo -e "${RED} failed${NC}" | tee -a out.log || echo -e "${GREEN} success${NC}" | tee -a out.log )|| \ ( grep -q 'script.*success.*m$' ../../../sim/tsim/log/taoslog0.0 && echo -e "${GREEN} success${NC}" | tee -a out.log ) || \ - ( echo -e "${RED} failed${NC}" | tee -a out.log && echo '=====================log=====================' && cat ../../../sim/case.log ) + ( echo -e "${RED} failed${NC}" | tee -a out.log && echo '=====================log=====================' && cat case.log ) else echo -n $case ./test.sh -f $case > ../../sim/case.log 2>&1 && \ ( grep -q 'script.*'$case'.*failed.*, err.*lineNum' ../../sim/tsim/log/taoslog0.0 && echo -e "${RED} failed${NC}" | tee -a out.log || echo -e "${GREEN} success${NC}" | tee -a out.log )|| \ ( grep -q 'script.*success.*m$' ../../sim/tsim/log/taoslog0.0 && echo -e "${GREEN} success${NC}" | tee -a out.log ) || \ - ( echo -e "${RED} failed${NC}" | tee -a out.log && echo '=====================log=====================' && cat ../../sim/case.log ) + ( echo -e "${RED} failed${NC}" | tee -a out.log && echo '=====================log=====================' && cat case.log ) fi out_log=`tail -1 out.log ` if [[ $out_log =~ 'failed' ]];then + rm case.log if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then cp -r ../../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S"` - rm -rf ../../../sim/case.log else cp -r ../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" ` - rm -rf ../../sim/case.log fi dohavecore $2 1 if [[ $2 == 1 ]];then @@ -159,10 +153,10 @@ function runPyCaseOneByOne { else $line > /dev/null 2>&1 fi - dohavecore 0 fi done < $1 } + function runPyCaseOneByOnefq() { cd $tests_dir/pytest if [[ $1 =~ full ]] ; then @@ -185,7 +179,7 @@ function runPyCaseOneByOnefq() { start_time=`date +%s` date +%F\ %T | tee -a pytest-out.log echo -n $case - $line > ../../sim/case.log 2>&1 && \ + $line > case.log 2>&1 && \ echo -e "${GREEN} success${NC}" | tee -a pytest-out.log || \ echo -e "${RED} failed${NC}" | tee -a pytest-out.log end_time=`date +%s` @@ -193,8 +187,8 @@ function runPyCaseOneByOnefq() { if [[ $out_log =~ 'failed' ]];then cp -r ../../sim ~/sim_`date "+%Y_%m_%d_%H:%M:%S" ` echo '=====================log===================== ' - cat ../../sim/case.log - rm -rf ../../sim/case.log + cat case.log + rm -rf case.log dohavecore $2 2 if [[ $2 == 1 ]];then exit 8 @@ -210,13 +204,37 @@ function runPyCaseOneByOnefq() { rm -rf ../../sim/case.log } +###################### +# main entry +###################### + +unameOut="$(uname -s)" +case "${unameOut}" in + Linux*) OS=Linux;; + Darwin*) OS=Darwin;; + CYGWIN*) OS=Windows;; + *) OS=Unknown;; +esac + +case "${OS}" in + Linux*) TAOSLIB=libtaos.so;; + Darwin*) TAOSLIB=libtaos.dylib;; + Windows*) TAOSLIB=taos.dll;; + Unknown) TAOSLIB="UNKNOWN:${unameOut}";; +esac + +echo TAOSLIB is ${TAOSLIB} + totalFailed=0 totalPyFailed=0 totalJDBCFailed=0 totalUnitFailed=0 totalExampleFailed=0 -corepath=`grep -oP '.*(?=core_)' /proc/sys/kernel/core_pattern||grep -oP '.*(?=core-)' /proc/sys/kernel/core_pattern` +if [ "${OS}" == "Linux" ]; then + corepath=`grep -oP '.*(?=core_)' /proc/sys/kernel/core_pattern||grep -oP '.*(?=core-)' /proc/sys/kernel/core_pattern` +fi + if [ "$2" != "jdbc" ] && [ "$2" != "python" ] && [ "$2" != "unit" ] && [ "$2" != "example" ]; then echo "### run TSIM test case ###" cd $tests_dir/script @@ -298,11 +316,11 @@ if [ "$2" != "sim" ] && [ "$2" != "jdbc" ] && [ "$2" != "unit" ] && [ "$2" != " fi TOP_DIR=`pwd` - TAOSLIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1` + TAOSLIB_DIR=`find . -name "${TAOSLIB}"|grep -w lib|head -n1` if [[ "$TAOSLIB_DIR" == *"$IN_TDINTERNAL"* ]]; then - LIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1|cut -d '/' --fields=2,3,4,5` + LIB_DIR=`find . -name "${TAOSLIB}"|grep -w lib|head -n1|cut -d '/' -f 2,3,4,5` else - LIB_DIR=`find . -name "libtaos.so"|grep -w lib|head -n1|cut -d '/' --fields=2,3,4` + LIB_DIR=`find . -name "${TAOSLIB}"|grep -w lib|head -n1|cut -d '/' -f 2,3,4` fi export LD_LIBRARY_PATH=$TOP_DIR/$LIB_DIR:$LD_LIBRARY_PATH @@ -498,6 +516,15 @@ if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$2" != "jdbc" ] && [ "$2" != echo "asyncdemo pass" totalExamplePass=`expr $totalExamplePass + 1` fi + + ./demo 127.0.0.1 > /dev/null 2>&1 + if [ $? != "0" ]; then + echo "demo failed" + totalExampleFailed=`expr $totalExampleFailed + 1` + else + echo "demo pass" + totalExamplePass=`expr $totalExamplePass + 1` + fi if [ "$totalExamplePass" -gt "0" ]; then echo -e "\n${GREEN} ### Total $totalExamplePass examples succeed! ### ${NC}" @@ -507,7 +534,9 @@ if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$2" != "jdbc" ] && [ "$2" != echo -e "\n${RED} ### Total $totalExampleFailed examples failed! ### ${NC}" fi - dohavecore 1 + if [ "${OS}" == "Linux" ]; then + dohavecore 1 + fi fi